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 womreddening(hop): """redden or deredden with various reddening laws""" import matplotlib.pyplot as plt import extinction from tmath.wombat.inputter_single import inputter_single from tmath.wombat.inputter import inputter from tmath.wombat.yesno import yesno r_v=3.1 print('Redden or deredden a spectrum') plt.cla() plt.plot(hop[0].wave,hop[0].flux,drawstyle='steps-mid',color='k') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.title(hop[0].obname) flux=hop[0].flux.copy() action=inputter_single('(r)edden or (d)eredden the spectrum? (r/d) ', 'rd') print(' ') type=inputter_single('Do you want to enter the (c)olor excess, or (v)isual extinction? ','cv') print(' ') if (type == 'v'): av=inputter('Enter A_V in magnitudes: ','float',False) else: ebv=inputter('Enter E(B-V) in magnitudes: ','float',False) av=r_v*ebv print(' ') print('Do you want to use: ') print('(c)ardelli, Clayton, Mathis 1989') print("(o)'donnell 1994") print('(f)itzpatrick 1999\n') method=inputter_single('(c/o/f) ','cof') if (action == 'r'): if (method == 'c'): newflux=extinction.apply(extinction.ccm89(hop[0].wave,av,r_v),flux) elif (method == 'o'): newflux=extinction.apply(extinction.odonnell94(hop[0].wave,av,r_v),flux) else: newflux=extinction.apply(extinction.fitzpatrick99(hop[0].wave,av,r_v),flux) else: if (method == 'c'): ext=extinction.ccm89(hop[0].wave,av,r_v) elif (method == 'o'): ext=extinction.odonnell94(hop[0].wave,av,r_v) else: ext=extinction.fitzpatrick99(hop[0].wave,av,r_v) newflux=flux*10**(0.4*ext) plt.plot(hop[0].wave,newflux,drawstyle='steps-mid',color='r') print('\nOriginal spectrum in black, red/dered in red\n') print('Is this OK?\n') answer=yesno('y') if (answer == 'y'): hop[0].flux=newflux.copy() print('\nActive spectrum now changed') else: print('\nSorry to disappoint you, active spectrum unchanged') return hop
def deredden_internal_extinction(sp, this_ebv, colf='rest_fnu', colu="rest_fnu_u", deredden_uncert=True, colwave='rest_wave') : # Remove internal extinction as fit by Chisholm's S99 fits. Assumes Calzetti sp_filt = sp.loc[sp[colwave].between(1200,20000)] Rv = 4.05 # IS THIS RIGHT FOR STELLAR CONTINUUM?***** Av = -1 * Rv * this_ebv # stupidity w .Series and .as_matrix() is bc extinction package barfs on pandas. pandas->np->pandas colfout = colf + "_dered" coluout = colu + "_dered" sp[colfout] = pandas.Series(extinction.apply(extinction.calzetti00(sp[colwave].astype('float64').as_matrix(), Av, Rv, unit='aa'), sp[colf].astype('float64').as_matrix())) if deredden_uncert : sp[coluout] = pandas.Series(extinction.apply(extinction.calzetti00(sp[colwave].astype('float64').as_matrix(), Av, Rv, unit='aa'), sp[colu].astype('float64').as_matrix())) return(0)
def _remove_flux_extinction(self): """ Remove extinction for light curve assuming Fitzpatrick '99 reddening law, given some value of E(B-V) """ self.fluxUnred = self.flux.copy() self.fluxErrUnred = self.fluxErr.copy() self.fluxRenorm = self.flux.copy() self.fluxErrRenorm = self.fluxErr.copy() # Using negative a_v so that extinction.apply works in reverse and removes the extinction if self.mwebv: extinctions = extinction.fitzpatrick99(wave=self._good_filter_wave, \ a_v=-3.1 * self.mwebv, r_v=3.1, unit='aa') for i, pb in enumerate(self._good_filters): mask = (self.passband == pb) flux_pb = self.flux[mask] fluxerr_pb = self.fluxErr[mask] npbobs = len(flux_pb) if npbobs < 1: return if self.mwebv: flux_out = extinction.apply(extinctions[i], flux_pb, inplace=False) fluxerr_out = extinction.apply(extinctions[i], fluxerr_pb, inplace=False) else: flux_out = flux_pb fluxerr_out = fluxerr_pb self.fluxUnred[mask] = flux_out self.fluxErrUnred[mask] = fluxerr_out if npbobs > 1: # there's at least enough observations to find minimum and maximum minfluxpb = flux_out.min() maxfluxpb = flux_out.max() norm = maxfluxpb - minfluxpb self.fluxRenorm[mask] = (flux_out - minfluxpb) / norm self.fluxErrRenorm[mask] = fluxerr_out / norm elif npbobs == 1: # deal with the case with one observation in this passband by setting renorm = 0.5 norm = self.fluxUnred[mask] / 0.5 self.fluxRenorm[mask] /= norm self.fluxErrRenorm[mask] /= norm self._default_cols = ['time', 'flux', 'fluxErr', 'fluxUnred', 'fluxErrUnred', \ 'fluxRenorm', 'fluxErrRenorm', 'photflag', 'zeropoint', 'obsId'] return
def deredden_MW_extinction(sp, EBV_MW, colwave='wave', colf='fnu', colfu='fnu_u', colcont='fnu_cont', colcontu='fnu_cont_u') : #print "Dereddening Milky Way extinction" Rv = 3.1 Av = -1 * Rv * EBV_MW # Want to deredden, so negative sign print("jrr.spec.deredden_MW_extinction, applying Av EBV_MW: ", Av, EBV_MW) #sp['oldfnu'] = sp[colf] # Debugging MW_extinction = extinction.ccm89(sp[colwave].astype('float64').as_matrix(), Av, Rv) sp['MWredcor'] = 10**(-0.4 * MW_extinction) sp[colf] = pandas.Series(extinction.apply(MW_extinction, sp[colf].astype('float64').as_matrix())) sp[colfu] = pandas.Series(extinction.apply(MW_extinction, sp[colfu].astype('float64').as_matrix())) if colcont in list(sp.keys()) : sp[colcont] = pandas.Series(extinction.apply(MW_extinction, sp[colcont].astype('float64').as_matrix())) if colcontu in list(sp.keys()) : sp[colcontu] = pandas.Series(extinction.apply(MW_extinction, sp[colcontu].astype('float64').as_matrix())) return(0)
def Mdot_to_UVExcess(Mdot, bc, dist, mass, radius, Av, Rin=5): ''' This function will transform a mass accretion rate estimate to a UV Excess flux value by following the process described in Herczeg 2008. Inputs: Mdot - mass accretion rate [Msun/yr] bc - bolometric correction dist - distance to object [pc] mass - mass of object [Msun] radius - radius of object [Rsun] Optional: Rin - magnetospheric radius (default 5 [Rsun]) Outputs: UVexcess - UV continuum excess flux [erg/(s*cm^2)] ''' #Mdot to accretion luminosity Lacc = Mdot_to_Lacc(Mdot, mass, radius, Rin) #convert accretion luminosity to erg/s Lacc = Lacc * const.L_sun.to('erg/s').value #accretion luminosity to accretion flux total_excess = luminosity_to_flux(Lacc, dist) #use the bolometric correction factor to scale the total accretion flux to UV excess flux UVexcess = total_excess / bc #Extinction correction of flux redUV = ex.apply(Av, UVexcess) return redUV
def extract_spec(data, ebv=0, RV=3.1): mask = data["AND_MASK"].data > 0 logwave_obs = data["LOGLAM"].astype(float).data spec = data["FLUX"].astype(float).data spec[mask] = np.nan spec_ivar = data["IVAR"].astype(float).data spec_ivar[mask] = np.nan spec_off = data["MODEL"].astype(float).data # spec = np.ma.masked_array(data["FLUX"].astype(float).data, mask=mask) # spec_off = np.ma.masked_array(data["MODEL"].astype(float).data, mask=mask) # spec_ivar = np.ma.masked_array(data["IVAR"].astype(float).data, mask=mask) if ebv > 0: extinction_sed = ebv * extinction.ccm89( 10**logwave_obs, 1.0, RV, unit="aa") spec = extinction.remove(extinction_sed, spec) spec_off = extinction.remove(extinction_sed, spec_off) spec_ivar = extinction.apply(extinction_sed, spec_ivar) # ind = np.isfinite(logwave_obs) # ind &= np.isfinite(spec) # ind &= np.isfinite(spec_ivar) # ind &= np.isfinite(spec_off) return logwave_obs, spec, spec_ivar, spec_off
def extinction_correction(wave, flux, ebv, r_v=3.1): if ebv is None: return flux ext = extinction.odonnell94(wave, r_v * ebv, r_v) return extinction.apply(-1. * ext, flux) # de-redden
def reddening(self, wave, flux, av, rv=3.1): """ Redden a 1-D spectrum with extinction Uses the extinction function corresponding to the ``rvmodel`` parametrization set in :py:func:`WDmodel.WDmodel.WDmodel._WDmodel__init__rvmodel` to calculate the extinction as a function of wavelength (in Angstroms), :math:`A_{\lambda}`. Parameters ---------- wave : array-like Array of wavelengths in Angstrom at which to compute extinction, sorted in ascending order flux : array-like Array of fluxes at ``wave`` at which to apply extinction av : float Extinction in the V band, :math:`A_V` rv : float, optional The reddening law parameter, :math:`R_V`, the ration of the V band extinction :math:`A_V` to the reddening between the B and V bands, :math:`E(B-V)`. Default is ``3.1``, appropriate for stellar SEDs in the Milky Way. Returns ------- out : array-like The reddened spectrum Notes ----- ``av`` and ``flux`` should be >= 0. """ return extinction.apply(self.extinction(wave, av, rv), flux, inplace=True)
def extinction_curve(self, ws, *params): """ return the reddening curve given wavlengths and params. the type of extinction curve is determined by attribute self.extinction_law. For example, for 'calzetti00' the params are a_v, r_v, and scaling. For example, for 'linear' the params are slope and intercept. Params ------ self ws (array) *params """ if self.extinction_law == 'linear': slope, intercept = params return slope * ws + intercept elif self.extinction_law == 'calzetti00': a_v, r_v, scaling = params flux = np.ones(len(ws)) extlaw = extinction.calzetti00(ws.astype('double'), a_v=a_v, r_v=r_v) return scaling * extinction.apply(extlaw, flux)
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 blackbody_spectrum( temperature: float, scale: float, redshift: float = None, extinction_av: float = None, extinction_rv: float = None, get_bolometric_flux: bool = False, ): """ """ wavelengths, frequencies = get_wavelengths_and_frequencies() scale_lambda = 1 * FLAM / u.sr scale_lambda = 1 / scale * FLAM / u.sr scale_nu = 1 / scale * FNU / u.sr bb_nu = BlackBody(temperature=temperature * u.K, scale=scale_nu) flux_nu = bb_nu(wavelengths) * u.sr bolometric_flux = bb_nu.bolometric_flux #.value flux_lambda = flux_nu_to_lambda(flux_nu, wavelengths) if extinction_av is not None: flux_lambda_reddened = apply( calzetti00(np.asarray(wavelengths), extinction_av, extinction_rv), np.asarray(flux_lambda), ) flux_nu_reddened = flux_lambda_to_nu(flux_lambda_reddened, wavelengths) spectrum_reddened = sncosmo_spectral_v13.Spectrum( wave=wavelengths, flux=flux_nu_reddened, unit=FNU) spectrum_unreddened = sncosmo_spectral_v13.Spectrum(wave=wavelengths, flux=flux_nu, unit=FNU) if redshift is not None: if extinction_av is not None: spectrum_reddened.z = 0 spectrum_reddened_redshifted = spectrum_reddened.redshifted_to( redshift, cosmo=cosmo, ) outspectrum = spectrum_reddened_redshifted else: spectrum_unreddened.z = 0 spectrum_unreddened_redshifted = spectrum_unreddened.redshifted_to( redshift, cosmo=cosmo) outspectrum = spectrum_unreddened_redshifted else: if extinction_av is not None: outspectrum = spectrum_reddened else: outspectrum = spectrum_unreddened if get_bolometric_flux: return outspectrum, bolometric_flux else: return outspectrum
def broken_powerlaw_spectrum( alpha1: float, scale1: float, alpha2: float, scale2: float, redshift: float = None, extinction_av: float = None, extinction_rv: float = None, ): """ """ wavelengths, frequencies = get_wavelengths_and_frequencies() if scale1 is None: flux_nu1 = frequencies.value**alpha1 * u.erg / u.cm**2 / u.s / u.Hz else: flux_nu1 = (frequencies.value**alpha1 * scale1 * (u.erg / u.cm**2 / u.s / u.Hz)) if scale2 is None: flux_nu2 = frequencies.value**alpha2 * u.erg / u.cm**2 / u.s / u.Hz else: flux_nu2 = (frequencies.value**alpha2 * scale2 * (u.erg / u.cm**2 / u.s / u.Hz)) flux_lambda1 = flux_nu_to_lambda(flux_nu1, wavelengths) flux_lambda2 = flux_nu_to_lambda(flux_nu2, wavelengths) flux_nu = flux_nu1 + flux_nu2 flux_lambda = flux_lambda1 + flux_lambda2 spectrum_unreddened = sncosmo_spectral_v13.Spectrum(wave=wavelengths, flux=flux_nu, unit=FNU) if extinction_av is not None: flux_lambda_reddened = apply( calzetti00(np.asarray(wavelengths), extinction_av, extinction_rv), np.asarray(flux_lambda), ) flux_nu_reddened = flux_lambda_to_nu(flux_lambda_reddened, wavelengths) spectrum_reddened = sncosmo_spectral_v13.Spectrum( wave=wavelengths, flux=flux_nu_reddened, unit=FNU) if redshift is not None: spectrum_unreddened.z = 0 spectrum_unreddened_redshifted = spectrum_unreddened.redshifted_to( redshift, cosmo=cosmo) outspectrum = spectrum_unreddened_redshifted else: outspectrum = spectrum_unreddened return outspectrum
def test_calzetti00(): """Test calzetti against another translation of the same base code""" wave = np.array([2000., 4000., 8000.]) flux = np.ones(3) new_flux = extinction.apply(extinction.calzetti00(wave, -1., 3.1), flux) # derived using Julia version of IDL calz_unred ref_values = np.array([10.5288, 3.88153, 1.61769]) assert_allclose(new_flux, ref_values, atol=0.0001)
def test_calzetti00(): """Test calzetti against another translation of the same base code""" wave = np.array([2000., 4000., 8000.]) flux = np.ones(3) new_flux = extinction.apply(extinction.calzetti00(wave, -1., 3.1), flux) # derived using Julia version of IDL calz_unred ref_values = np.array([10.5288, 3.88153, 1.61769]) assert_allclose(new_flux, ref_values, atol=0.0001)
def Mdot_to_UbandExcess(Mdot, dist, mass, radius, Av, Rin=5, unc=False): ''' This function will transform a mass accretion rate estimate into a U band flux value by following the process described in Robinson 2019. Inputs: Mdot - mass accretion rate [Msun/yr] dist - distance to object [pc] mass - mass of object [Msun] radius - radius of object [Rsun] Optional: Rin - magnetospheric radius (default 5 [Rsun]) Outputs: Uexcess - U band continuum excess flux [erg/(s*cm^2)] ''' #Mdot to accretion luminosity Lacc = Mdot_to_Lacc(Mdot, mass, radius, Rin) #ln Lacc logLacc = np.log(Lacc) #Lacc to Lu using Robinson paper -- natural logarithms #uncertainties 0.03 for each constant if unc == False: logLu = (logLacc - 0.5) / 0.93 else: logLu = (logLacc - (0.5 + np.random.normal(0.03))) / (0.93 + np.random.normal(0.03)) Lu = np.exp(logLu) #convert Lu to erg/s Lu = Lu * const.L_sun.to('erg/s').value #Lu to U-band flux Uexcess = luminosity_to_flux(Lu, dist) #extinction correction of flux #reddening law to U-band if type(Av) == float: Au = ex.ccm89(np.array([3650.0]), Av, 3.1)[0] elif type(Av) == list or type(Av) == np.ndarray: Au = [] for av in Av: Au.append(ex.ccm89(np.array([3650.0]), av, 3.1)[0]) Au = np.array(Au) #extinction correction redU = ex.apply(Au, Uexcess) return redU
def add_dust(self): for x in self.sed.dtype.names[1:]: if self.dust == 'calzetti': try: self.sed[x] = apply( calzetti00(self.sed['waves'], self.Av, 4.05), self.sed[x]) except NameError: self.sed[x] = self.sed[x] * np.exp( -calzetti(self.sed['waves'], self.Av)) elif self.dust == 'cardelli': self.sed[x] = self.sed[x] * np.exp( -cardelli(self.sed['waves'], self.Av))
def correct_for_galactic_extinction(spec, E_BV, R_V=3.1): ''' Correct flux for galactic (Milky Way) extinction using a Cardelli law Inputs: spec: spectrum1d object to be corrected (has wave and flux attributes) E_BV: E(B-V) for correction R_V: default to 3.1 values Output: spectrum1d object with the dust corrected flux ''' A_V = R_V * E_BV new_flux = extinction.apply(-extinction.ccm89(spec.wave, A_V, R_V), spec.flux) return spectrum1d(spec.wave, new_flux)
def Spec_mags(Models, pbs, ex=0, Conversion=1.029): """ Generate synthetic magnitudes from the models and passbands added. Conversion converts between Ebv and Egr, the Green value is 0.981, but the best fit value was found to be 1.029. """ a_v = 3.1 * (Conversion * ex) # ex = extinction from Bayestar19 = Egr pbg, zpg = pbs['ps1g'] pbr, zpr = pbs['ps1r'] pbi, zpi = pbs['ps1i'] pbz, zpz = pbs['ps1z'] pbk, zpk = pbs['Kep'] mg = [] mr = [] mi = [] mz = [] mk = [] # construct mags ind = [] red = {} for modelname in Models: model = Models[modelname] model = S.ArraySpectrum(model.wave, apply( fitzpatrick99(model.wave.astype('double'), a_v, 3.1), model.flux), name=modelname) mg += [source_synphot.passband.synphot(model, pbg, zpg)] mr += [source_synphot.passband.synphot(model, pbr, zpr)] mi += [source_synphot.passband.synphot(model, pbi, zpi)] mz += [source_synphot.passband.synphot(model, pbz, zpz)] mk += [source_synphot.passband.synphot(model, pbk, zpk)] mg = np.array(mg) mr = np.array(mr) mi = np.array(mi) mz = np.array(mz) mk = np.array(mk) good = np.isfinite(mg) & np.isfinite(mr) & np.isfinite(mi) & np.isfinite( mz) & np.isfinite(mk) d = { 'g': mg[good], 'r': mr[good], 'i': mi[good], 'z': mz[good], 'k': mk[good] } return d
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 get_model(Rs, Av): #print Rs,Av Rscm = Rs * 6.95700e10 flxs = apply(ccm89(nsyn_wavs, Av, 3.1), nsyn_flxs * Rscm * Rscm) #outsw,nsyn_flxs = syn_flux(mod_wav,flxs,band) #loglog(mod_wav,mod_flx*Rscm*Rscm) #loglog(mod_wav,flxs*Rscm*Rscm) #loglog(outsw,nsyn_flxs*Rscm*Rscm,'ro') #loglog(refw,fluxes*distance*distance,'bo') #show() #Al = [] #for bd in band: # Al.append(get_avge_ext(Av,bd)) #Al = np.array(Al) return flxs #*Rscm*Rscm
def Alam(lamin): A_v = 1 R_v = 3.1 ''' Add extinction with R_v = 3.1 and A_v = 1, A_v = 1 in order to find the constant of proportionality for the extinction law. ''' flux = np.ones(len(lamin)) redreturn = apply(ccm89(lamin, A_v, R_v), flux) #redreturn = A_v*extinction.a_lambda_cardelli_fast(lamin*1e-4,R_v) return redreturn
def Spec_mags(Models, pbs, av=0, Rv=3.1, Conversion=1.029): """ Generate synthetic magnitudes from the models and passbands added. Conversion converts between Ebv and Egr, the Green value is 0.981, but the best fit value was found to be 1.029. """ #a_v = 3.1*(Conversion * ex ) # ex = extinction from Bayestar19 = Egr keys = list(pbs.keys()) mags = {} for key in keys: mags[key] = [] pb, zp = pbs[key] # construct mags ind = [] red = {} for model in Models: if av > 0: model = S.ArraySpectrum(model.wave, apply( fitzpatrick99(model.wave, av, Rv), model.flux), waveunits=model.waveunits, fluxunits=model.fluxunits) if av < 0: model = S.ArraySpectrum(model.wave, remove( fitzpatrick99(model.wave, -av, Rv), model.flux), waveunits=model.waveunits, fluxunits=model.fluxunits) mags[key] += [source_synphot.passband.synphot(model, pb, zp)] for key in keys: mags[key] = np.array(mags[key]) #good = np.ones(len(mags[key])) > 0 #for key in keys: # good = good *np.isfinite(mags[key]) #for key in keys: # mags[key] = mags[key][good] return mags
def rf_spec_from_merged(self): """ Returns the rest frame spectrum as calculated by normalizing and dereddening the merged spectrum. """ wave, flux, var = self.merged_spec() zhelio = self.sn_data['host.zhelio'] zcmb = self.sn_data['host.zcmb'] mwebv = self.sn_data['target.mwebv'] # Remove dust extinction from Milky Way in observer frame flux = apply(ccm89(wave, -mwebv * 3.1, 3.1), flux) # Convert observer frame wavelengths to rest frame wave = wave / (1 + zhelio) # Convert flux to luminosity at z=0.05 dl = (1 + zhelio) * COSMO.comoving_transverse_distance(zcmb) cosmo_factor = (1 + zhelio) / 1.05 * (dl / DLREF)**2 flux = flux * cosmo_factor * 1e15 var = flux * (cosmo_factor * 1e15)**2 return wave, flux, var
def Mdot_to_UVExcess(Mdot, bc, dist, mass, radius, Av, Rin=5): ''' This function will transform a mass accretion rate estimate to a UV Excess flux value by following the process described in Herczeg 2008. Inputs: Mdot - mass accretion rate [Msun/yr] bc - bolometric correction dist - distance to object [pc] mass - mass of object [Msun] radius - radius of object [Rsun] Optional: Rin - magnetospheric radius (default 5 [Rsun]) Outputs: UVexcess - UV continuum excess flux [erg/(s*cm^2)] ''' #Mdot to accretion luminosity Lacc = Mdot_to_Lacc(Mdot, mass, radius, Rin) #convert accretion luminosity to erg/s Lacc = Lacc * const.L_sun.to('erg/s').value #accretion luminosity to accretion flux total_excess = luminosity_to_flux(Lacc, dist) #use the bolometric correction factor to scale the total accretion flux to UV excess flux UVexcess = total_excess / bc #Extinction correction of flux #reddening law to U-band Au = Av if type(Av) == float: Au = ex.ccm89(np.array([3650.0]), Av, 3.1)[0] elif type(Av) == list or type(Av) == np.ndarray: Au = [] for av in Av: Au.append(ex.ccm89(np.array([3650.0]), av, 3.1)[0]) Au = np.array(Au) #extinction correction redUV = ex.apply(Au, UVexcess) return redUV
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 powerlaw_spectrum( alpha: float, scale: float, redshift: float = None, extinction_av: float = None, extinction_rv: float = None, ): """ """ wavelengths, frequencies = get_wavelengths_and_frequencies() if scale is None: flux_nu = frequencies**alpha * u.erg / u.cm**2 / u.s else: flux_nu = frequencies**alpha * u.erg / u.cm**2 / u.s * scale flux_lambda = flux_nu_to_lambda(flux_nu, wavelengths) spectrum_unreddened = sncosmo_spectral_v13.Spectrum(wave=wavelengths, flux=flux_nu, unit=FNU) if extinction_av is not None: flux_lambda_reddened = apply( calzetti00(np.asarray(wavelengths), extinction_av, extinction_rv), np.asarray(flux_lambda), ) flux_nu_reddened = flux_lambda_to_nu(flux_lambda_reddened, wavelengths) spectrum_reddened = sncosmo_spectral_v13.Spectrum( wave=wavelengths, flux=flux_nu_reddened, unit=FNU) if redshift is not None: spectrum_unreddened.z = 0 spectrum_unreddened_redshifted = spectrum_unreddened.redshifted_to( redshift, cosmo=cosmo) outspectrum = spectrum_unreddened_redshifted else: outspectrum = spectrum_unreddened return outspectrum
# 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 = [ t_DR12_DR12_matches['ERR_W{}MAG'.format(i)] for i in range(1, 5)
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
def make_a_stack(labels, rootname, norm_region, norm_func, norm_method_text, mage_mode, zchoice, deredden=False, EBV=[], deredden_MW=False, colcont="fnu_cont") : # Note: this is stacking in the rest-frame. plt.close('all') plt.ion() plt.figure(figsize=(20,5)) # specs = jrr.mage.getlist_labels(mage_mode, labels) specs = jrr.mage.wrap_getlist(mage_mode, which_list="labels", labels=labels) Nspectra = len(specs) print("DEBUG, Nspectra is", Nspectra) stacklo = 800. #A # Create a rest-frame wavelength array to stack into stackhi = 3000. #A disp = 0.1 # Angstroms # observed-frame wavelength binning is ~0.3A pper pix for RCS0327. So, want ~0.1A in rest-frame nbins = int((stackhi - stacklo)/disp) wave_stack = np.linspace(stacklo, stackhi, num=nbins) nfnu_stack = np.ma.zeros(shape=(Nspectra, nbins)) # create array that will hold all the spectra nfnu_u_stack = np.ma.zeros(shape=(Nspectra, nbins)) print("Filename label N_pixels rest-frame wavelength range (A)") for ii in range(0, Nspectra) : #nfnu_stack[ii] will be ii spectrum label = specs['short_label'][ii] filename = specs['filename'][ii] if(zchoice == "stars") : # Update 8/2016, enabling either method to to set systemic redshift, selectable as zchoice zz = specs['z_syst'][ii] # using john chisholm's S99 fits to photospheric absorption lines where possible. elif(zchoice == "neb") : zz = specs['z_neb'][ii] # what I used prior to 21 july 2016. else : raise ValueError('Error, I do not recognize input zchoice (choice to set systemic redshift) as stars or neb') # OLD (sp, resoln, dresoln) = jrr.mage.open_spectrum(filename, zz, mage_mode) (sp, resoln, dresoln, LL, zz_syst) = jrr.mage.wrap_open_spectrum(label, mage_mode, addS99=True) # set uncertainties high near skylines [O I] 5577\AA\ and [O I]~6300\AA, skyline = (5577., 6300.) skywidth = 10.0 # flag spectrum +- skywidth of the skyline sp.fnu_u[sp['wave'].between(skyline[0]-skywidth, skyline[0]+skywidth)] = 1.0 # huge uncert near skylines sp.fnu_u[sp['wave'].between(skyline[1]-skywidth, skyline[1]+skywidth)] = 1.0 # huge uncert near skylines sp.fnu_u[sp[colcont].eq(9999)] = 1.0 # Set huge uncertainties where continuum undefined # Mask out known intervening absorbers vmask = 200. # +-200km/s LL['vmask'] = vmask jrr.spec.flag_near_lines(sp, LL, linetype=('INTERVE',)) sp.fnu_u[sp['linemask']] = 1. # Set huge uncertainties at positions of known intervening absorbers if deredden_MW : print("DEBUGGING, dereddening Milky Way extinction") Rv = 3.1 Av = -1 * Rv * specs['EBV_MW'][ii] # Want to deredden, so negative sign sp.fnu = pandas.Series(extinction.apply(extinction.ccm89(sp.wave.as_matrix(), Av, Rv), sp.fnu.as_matrix())) sp.fnu_u = pandas.Series(extinction.apply(extinction.ccm89(sp.wave.as_matrix(), Av, Rv), sp.fnu_u.as_matrix())) sp[colcont] = pandas.Series(extinction.apply(extinction.ccm89(sp.wave.as_matrix(), Av, Rv), sp[colcont].as_matrix())) sp['fnu_cont_u'] = pandas.Series(extinction.apply(extinction.ccm89(sp.wave.as_matrix(), Av, Rv), sp['fnu_cont_u'].as_matrix())) (rest_wave, rest_fnu, rest_fnu_u) = jrr.spec.convert2restframe(sp.wave, sp.fnu, sp.fnu_u, zz, 'fnu') (junk , rest_cont, rest_cont_u) = jrr.spec.convert2restframe(sp.wave, sp[colcont], sp.fnu_cont_u, zz, 'fnu') # should now have arrays of rest wavelength, fnubda, and continuum, as # rest_wave, rest_fnu, rest_fnu_u, rest_cont, rest_cont_u print(filename, label, len(rest_wave), end=' ') print(" %.2f %.2f" % ( rest_wave[0], rest_wave[-1:])) if deredden and len(EBV) : this_ebv = S99.loc[label, 'E(B-V)'] Rv = 4.05 Av = -1 * Rv * this_ebv # stupidity w .Series and .as_matrix() is bc extinction package barfs on pandas. pandas->np->pandas rest_fnu = pandas.Series(extinction.apply(extinction.calzetti00(rest_wave.as_matrix(), Av, Rv), rest_fnu.as_matrix())) rest_fnu_u = pandas.Series(extinction.apply(extinction.calzetti00(rest_wave.as_matrix(), Av, Rv), rest_fnu_u.as_matrix())) rest_cont = pandas.Series(extinction.apply(extinction.calzetti00(rest_wave.as_matrix(), Av, Rv), rest_cont.as_matrix())) rest_cont_u = pandas.Series(extinction.apply(extinction.calzetti00(rest_wave.as_matrix(), Av, Rv), rest_cont_u.as_matrix())) # Normalize the spectrum and error spectrum (temp_norm_fnu, temp_sig) = norm_func(rest_wave, rest_fnu, rest_fnu_u, rest_cont, rest_cont_u, norm_region) nfnu_stack[ii] = np.ma.masked_invalid(jrr.spec.rebin_spec_new(rest_wave, temp_norm_fnu, wave_stack))# normalized fnu, rebinned nfnu_u_stack[ii] = np.ma.masked_invalid(jrr.spec.rebin_spec_new(rest_wave, temp_sig, wave_stack)) # uncertainty on above plt.step(wave_stack, nfnu_stack[ii]) # fnu_u_stack is 1sigma uncertainty spectrum. weight is 1/sigma**2 nfnu_u_stack += 0.00001 # add a very small number to avoid 1/zero errror weight_stack = nfnu_u_stack**-2 sig2clip = 2 # clip at N sigma, in astropy.stats.sigma_clip # Use a masked average to deal with the whole wavelength range. numpy.ma is masking mask1 = np.isnan(nfnu_stack) # interp1d writes NaNs in non-overlap region. Mask these mask2 = np.isnan(nfnu_u_stack) # ditto for uncertainty crazy_high = 1000. mask3 = np.greater(nfnu_stack, crazy_high) + np.less(nfnu_stack, -1*crazy_high) # flag crazy flux values. mask = mask1 + mask2 + mask3 print("DEBUGGING masks", mask1.sum(), mask2.sum(), mask3.sum(), mask.sum(), mask.shape) nfnu_clip = sigma_clip(nfnu_stack, sig=sig2clip, iters=None, axis=0) ## Sigma clipping X_avg, sumweight1 = np.ma.average(nfnu_stack, axis=0, weights=weight_stack, returned=True) # weighted avg of continuum-normalized spectra X_clipavg, sumweight2 = np.ma.average(nfnu_clip, axis=0, weights=weight_stack, returned=True) # weighted avg of cont-normalized spectra, w sig clip X_Ngal = np.sum((1 - mask), axis=0) # Number of galaxies that went into the stack at that wavelength X_sigma = sumweight1**-0.5 X_clipsigma = sumweight2**-0.5 # spiky, dunno why. Presumably legacy of sigma_clip? Don't use it X_median = np.ma.median(nfnu_stack, axis=0) plt.step(wave_stack, X_avg, color="black", linewidth=3) plt.ylim( -1, 3) plt.xlim(1000, 1200) plt.draw() plt.show() #pdb.set_trace() if GOSLOW : plt.pause(4) # Jack-knife: drop one spectrum and make weighted average, repeat. Measure the stdev. jackknife = np.ma.zeros(shape=(Nspectra, nbins)) jack_var = np.ma.zeros(shape=nbins) for ii in range(0, Nspectra) : jnf = nfnu_stack.copy() print("Jackknife, dropping ", specs['short_label'][ii], " from the stack") jnf[ii, :].mask = True # Mask one spectrum jackknife[ii], weight = np.ma.average(jnf, axis=0, weights=weight_stack, returned=True) # all the work is done here. jack_var = jack_var + (jackknife[ii] - X_avg)**2 jack_var *= ((Nspectra -1.0)/float(Nspectra)) X_jack_std = np.sqrt(jack_var) # Jackknife variance estimation, from wikipedia: var = (n-1)/n * sum(i=1 to n) of (xi - x.)**2 #Output the stacked spectrum long_rootname = "magestack_by" + zchoice + "_" + rootname head = '# Stack(s) of the MagE spectral atlas of lensed galaxies, named ' + long_rootname + '\n' head += '# Generated on ' + time.strftime("%d/%m/%Y") + '(dd/mm/yyr)\n' head += '# Generated from ' + str(labels) + "\n" head += '# ' + norm_method_text + "\n" head += '# Columns are: \n' head += '# wave : Rest-frame vacuum wavelength, in Angstroms. Covers ' + str(stacklo) + " to " + str(stackhi) + '\n' head += '# X_avg : Weighted avg of continuum-normalized fnu spectra.\n' head += '# X_clipavg: same as X_avg, but weighted avg done with sigma clipping at sigma=' + str(sig2clip) + '\n' head += '# X_median: median of continuum-normalized fnu spectra. No weighting.\n' head += '# X_sigma : uncertainty on X_avg and X_clipavg, from propagating individual error spectra\n' head += '# X_jack_std : sqrt of variance estimate from jackknife test. \n' head += '# Ngal : Number of galaxies that went into the stack at that wavelength.\n' head += 'restwave X_avg X_clipavg X_median X_sigma X_jack_std Ngal' outfile = long_rootname + "_spectrum.txt" np.savetxt(outfile, np.transpose([wave_stack, X_avg, X_clipavg, X_median, X_sigma, X_jack_std, X_Ngal]), "%.3f %.2E %.2E %.2E %.2E %.2E %d", header=head, comments="") maskout_head = "#This mask shows which galaxies were stacked at each wavelength. 0=gal used. 1=gal masked out.\n" outfile = long_rootname + "_maskused.txt" jack_head = "restwave " + re.sub("\n", "", str(specs.short_label.values)) jack_head = re.sub("'", "", jack_head) jack_head = re.sub("\[", "", jack_head) jack_head = re.sub("\]", "", jack_head) maskout_head += jack_head format_string = "%.3f " + "%.0f " * mask.shape[0] np.savetxt(outfile, np.transpose(np.vstack((wave_stack, mask))), fmt=format_string, header=maskout_head, comments="") # so much pain to figure out this syntax # The above np magic allows us to concatenate wave_stack (which is 1D, and mask, which is 2D, and the 2nd dimension isn't defined. painful" # output the jackknife stacks outfile = long_rootname + "_jackknife.txt" head2 = "# Weighted-averages of MagE spectra, each missing 1 spectrum, for jackknife tests\n#wave(A) weighted_means_w_jackknife\n" head2 += "# Each jackknife is missing the following spectrum:\n" + jack_head np.savetxt(outfile, np.transpose(np.vstack((wave_stack, jackknife))), fmt="%.5E", header=head2, comments="") # plot the stacked spectrum plt.clf() plt.step(wave_stack, X_avg, color="black") plt.step(wave_stack, X_median, color="blue") plt.step(wave_stack, X_sigma, color="orange") plt.step(wave_stack, X_jack_std, color="red") plt.ylabel(r'$f_\nu$') #plt.xlim(stacklo, stackhi) plt.xlim(800,3000) plt.ylim(-1,2) figname = long_rootname + "_quicklook.pdf" plt.savefig(figname) plt.show() if GOSLOW : plt.pause(4) PLOT_NGAL = True if PLOT_NGAL : plt.clf() plt.xlabel(r'wavelength ($\AA$)') plt.ylabel("number of galaxies that went into the stack") plt.plot(wave_stack, X_Ngal, color="red") plt.ylim(0,16) figname = long_rootname + "_Ngals_in_stack.pdf" plt.savefig(figname) plt.show() #raise Exception("I need to see whats happening") return(wave_stack, nfnu_stack, nfnu_u_stack)
def propagate(self, phase, wave, flux): """Propagate the flux.""" ebv = self._parameters[0] return extinction.apply(self._f(wave, ebv * self._r_v), flux)
def propagate(self, phase, wave, flux): """Propagate the flux.""" ebv, r_v = self._parameters return extinction.apply(extinction.odonnell94(wave, ebv * r_v, r_v), flux)
def get_sed_fluxes(teff, logg, feh, models='bt-settl-cifist'): if models == 'bt-settl-cifist': print teff, logg, feh #print 'entering in get sed...' teffs = np.arange(4000, 7050, 100) loggs = np.arange(2.5, 5.6, 0.5) if teff >= 4000 and teff <= 7000: dift = teffs - teff I1 = np.where(dift <= 0)[0][-1] I2 = np.where(dift >= 0)[0][0] elif teff < 4000: I1 = 0 I2 = 0 else: I1 = -1 I2 = -1 difg = loggs - logg J1 = np.where(difg <= 0)[0][-1] J2 = np.where(difg >= 0)[0][0] #print 'calling the interpolation...' #wavs,flxs = bilinear(teff,logg,teffs[I1],teffs[I2],loggs[J1],loggs[J2]) flxs = bilinear_fluxes(teff, logg, teffs[I1], teffs[I2], loggs[J1], loggs[J2]) f = open( 'bt-settl-cifist/lte040.0-4.0-0.0a+0.0.BT-Settl.spec.7.bands.txt', 'r') lines = f.readlines() wavs, bands, widths = [], [], [] for line in lines: cos = line.split() tband = cos[0] bands.append(tband) wavs.append(get_bpass_pos(tband)) widths.append(get_bpass_width(tband)) wavs, bands, widths = np.array(wavs), np.array(bands), np.array(widths) return wavs, flxs, bands, widths #Al = get_Al(0.01,wavs) #print 'ended' flxs = flxs * (0.674 * 6.95700e10)**2 loglog(wavs, flxs) #flxs2 = flxs*np.exp(-Al/2.5) flxs2 = apply(ccm89(wavs, Av, 3.1), flxs) loglog(wavs, flxs2, 'k') #dw = np.array([2274.37,4280.00,4297.17,4640.42,5340.00,5394.29,5857.56,6122.33,7439.49,12350.00,16620.00,21590.00,33526.00,46028.00,115608.00]) #df = np.array([1.778e-14,3.524e-13,4.214e-13,3.884e-13,4.364e-13,4.098e-13,3.365e-13,3.659e-13,2.683e-13,9.996e-14,4.594e-14,1.812e-14,3.637e-15,1.036e-15,2.868e-17]) dw = np.array([ 4297.17, 5394.29, 12350.00, 16620.00, 21590.00, 33526.00, 46028.00, 115608.00 ]) df = np.array([ 4.214e-13, 4.098e-13, 9.996e-14, 4.594e-14, 1.812e-14, 3.637e-15, 1.036e-15, 2.868e-17 ]) db = np.array([ 'Johnson_B', 'Johnson_V', '2mass_J', '2mass_H', '2mass_Ks', 'W1', 'W2', 'W3' ]) dw = np.array([ 4297.17, 5394.29, 12350.00, 16620.00, 21590.00, 33526.00, 46028.00, 115608.00, 220883 ]) db = np.array([ 'Johnson_B', 'Johnson_V', '2mass_J', '2mass_H', '2mass_Ks', 'W1', 'W2', 'W3', 'W4' ]) df = np.array([ 7.977e-14, 9.716e-14, 7.261e-14, 4.412e-14, 1.868e-14, 3.875e-15, 1.063e-15, 3.087e-17, 3.426e-18 ]) #print 'iterating...' exp_fluxes = [] for i in range(len(db)): tband = db[i] rw, rr = get_bpass_response(tband) JJ = np.where(rr > 0.001)[0] rw, rr = rw[JJ], rr[JJ] II = np.where((wavs > rw[0]) & (wavs < rw[-1]))[0] tck = scipy.interpolate.splrep(rw, rr, k=1) rr = scipy.interpolate.splev(wavs[II], tck) wt1 = wavs[II].copy() wt2 = np.hstack((wt1[0], wt1[:-1])) dws = wt1 - wt2 dws[0] = dws[1] #print dws FF = np.sum(rr * flxs2[II] * dws) / get_bpass_width(tband) exp_fluxes.append(FF) #print 'out' #print exp_fluxes exp_fluxes = np.array(exp_fluxes) loglog(dw, exp_fluxes, 'go') D = 7.694021354007038 / 1000. D = 17.014529124468865 / 1000. D = 3.0857e18 * 1. / D df = df * D**2 loglog(dw, df, 'ro') show()
def plot(target, rstar, Av, query=True, correction=True, models='bt-settl-cifist'): # Set seaborn contexts: sns.set_context("talk") sns.set_style("ticks") # Fonts: # Arial font (pretty, not latex-like) #rc('font',**{'family':'sans-serif','sans-serif':['Arial']}) # Latex fonts, quick: #matplotlib.rcParams['mathtext.fontset'] = 'stix' #matplotlib.rcParams['font.family'] = 'STIXGeneral' # Latex fonts, slow (but accurate): rc('font', **{'family': 'Helvetica'}) rc('text', usetex=True) matplotlib.rcParams.update({'font.size': 20}) plt.rc('legend', **{'fontsize': 7}) # Ticks to the outside: rcParams['axes.linewidth'] = 3.0 rcParams['xtick.direction'] = 'out' rcParams['ytick.direction'] = 'out' global nsyn_wavs, nsyn_flxs, nsyn_widths, band global refw, fluxes f = open(target + '_pars.txt', 'r') lines = f.readlines() have_dist = False for line in lines: cos = line.split() if 'parallax' in cos[0]: parallax = float(cos[1]) eparallax = float(cos[2]) elif 'teff' in cos[0]: teff = float(cos[1]) eteff = float(cos[2]) elif 'logg' in cos[0]: logg = float(cos[1]) elogg = float(cos[2]) elif 'feh' in cos[0]: feh = float(cos[1]) efeh = float(cos[2]) elif 'ra' in cos[0]: ra = cos[1] elif 'dec' in cos[0]: dec = cos[1] elif 'dist' in cos[0]: dist = float(cos[1]) edist = float(cos[2]) have_dist = True print parallax, eparallax if correction: parallax += 0.029 eparallax += 0.4 * eparallax print parallax, eparallax global distance #print have_dist if not have_dist: #print parallax, eparallax parallax = parallax / 1000. eparallax = eparallax / 1000. distance = 3.0857e18 / parallax else: distance = 3.0857e16 * dist * 100. if query == False: f = open(target + '_fluxes.txt', 'r') lines = f.readlines() band, fluxes, efluxes, refw = [], [], [], [] for line in lines: cos = line.split() band.append(cos[0]) fluxes.append(float(cos[2])) efluxes.append(float(cos[3])) refw.append(get_bpass_pos(cos[0])) band, fluxes, efluxes, refw = np.array(band), np.array( fluxes), np.array(efluxes), np.array(refw) f.close() else: try: ra, dec = float(ra), float(dec) except: ra, dec = trans_coords(ra, dec) #print 'coords:',ra, dec dct = get_mags_2mass(ra, dec) dct.update(get_mags_APASS(ra, dec)) dct.update(get_mags_WISE(ra, dec, models=models)) print dct band, fluxes, efluxes, refw = [], [], [], [] for key in dct.keys(): if key[0] != 'e': #print dct[key],dct['e'+key],key flux, eflux, refwt = mag_to_flux(dct[key], dct['e' + key], key) if flux != -1 and eflux != -1 and np.isnan( flux) == False and np.isnan(eflux) == False: fluxes.append(flux) efluxes.append(eflux) refw.append(refwt) band.append(key) band, fluxes, efluxes, refw = np.array(band), np.array( fluxes), np.array(efluxes), np.array(refw) """ f = open(target+'_pars.txt','r') lines = f.readlines() for line in lines: cos = line.split() if 'parallax' in cos[0]: parallax = float(cos[1]) eparallax = float(cos[2]) elif 'teff' in cos[0]: teff = float(cos[1]) eteff = float(cos[2]) elif 'logg' in cos[0]: logg = float(cos[1]) elogg = float(cos[2]) elif 'feh' in cos[0]: feh = float(cos[1]) efeh = float(cos[2]) parallax = parallax / 1000. eparallax = eparallax / 1000. distance = 3.0857e18 / parallax """ y = fluxes * distance * distance Rscm = rstar * 6.95700e10 y = y / (Rscm**2) w, f = get_sed(teff, logg, 0.0, models='bt-settl-cifist') #Al = extinction.ccm89(w, Av, 3.1) #f = f*np.exp(-get_Al(Av, w)/2.5) f = apply(ccm89(w, Av, 3.1), f) figure() modsed = f * Rscm * Rscm / (distance * distance) loglog(w, modsed, color='g', alpha=0.4) loglog(refw, fluxes, 'ro') for i in range(len(band)): cos = band[i].split('_') #print band[i] text(refw[i], 3 * fluxes[i], cos[-1], fontsize=18) xlim([1e3, 3e5]) ylim([1e-25, 1e-10]) xlabel(r'Wavelength [$\AA$]') ylabel(r'F [erg cm$^{-2}$ s$^{-1}$ $\AA^{-1}$]') plt.savefig(target + '_sed.pdf', bbox_inches='tight')