Beispiel #1
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])
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
Beispiel #3
0
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) 
Beispiel #4
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
Beispiel #5
0
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)
Beispiel #6
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
Beispiel #8
0
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
Beispiel #9
0
    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)
Beispiel #10
0
    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)
Beispiel #11
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
Beispiel #12
0
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
Beispiel #13
0
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
Beispiel #14
0
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)
Beispiel #15
0
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)
Beispiel #16
0
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
Beispiel #17
0
    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))
Beispiel #18
0
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)
Beispiel #19
0
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
Beispiel #20
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
Beispiel #21
0
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
Beispiel #23
0
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
Beispiel #24
0
 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
Beispiel #25
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
    #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
Beispiel #26
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)
Beispiel #27
0
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
Beispiel #28
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 = [
    t_DR12_DR12_matches['ERR_W{}MAG'.format(i)] for i in range(1, 5)
Beispiel #29
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
Beispiel #30
0
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)
Beispiel #31
0
 def propagate(self, phase, wave, flux):
     """Propagate the flux."""
     ebv = self._parameters[0]
     return extinction.apply(self._f(wave, ebv * self._r_v), flux)
Beispiel #32
0
 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)
Beispiel #33
0
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()
Beispiel #34
0
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')