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
示例#2
0
def deredden_df(tb, ebv):
    """
    perform extinction correction
    """
    if 'mag' in tb.columns:
        tb['mag0'] = tb['mag'] - extinction.ccm89(
            tb['wave'].values, 3.1 * ebv, 3.1)  # extinction in magnitude
    if "limmag" in tb.columns:
        tb['limmag0'] = tb["limmag"] - extinction.ccm89(
            tb['wave'].values, 3.1 * ebv, 3.1)  # extinction in magnitude
    return tb
示例#3
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
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
示例#5
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])
示例#6
0
def get_keck(z=0.0213, date = "20190412_Keck1_v2", 
             vkernel = 200, t0jd = 58583.2,
             ebv = 0.022):# Keck spectrum
    myfile = "../data/spectra/ZTF18abfcmjw_"+date+".ascii"
    f = open(myfile)
    lines = f.readlines()
    f.close()
    lines = np.array(lines)
    #lines = lines[100:200]
    ind = np.array([x[:11]=="# MJD     =" for x in lines])
    myline = lines[ind] [0]  
    mjd= float(myline[15:-30])
    phase = mjd - t0jd

    tb= asci.read(myfile)
    tb = tb[tb["col1"]>3190]
    dt = {}
    dt["phase"] = np.round(phase, 2)
    xx = tb['col1'].data/(1+z)
    yy = tb['col2'].data
    ind = ~np.isnan(yy)
    dt["wave"] = xx[ind]*(1+z)
    dt['wave_rest'] = xx[ind]
    dt['spec_obs'] = yy[ind]
    dt['spec_obs_sky'] = tb['col3'].data[ind]
    Aextmag =  extinction.ccm89(dt['wave_rest'], 3.1*ebv, 3.1) # extinction in magnitudes
    tau =  Aextmag / 1.086
    dt['spec_obs0'] = dt['spec_obs'] * np.exp(tau)
    dt["ln_spec_obs"] = np.log(dt['spec_obs0'])
    
    ww, ff = convolve_with_constant_velocity_kernel(dt['wave_rest'], dt['spec_obs0'], vkernel)
    dt['wave_con'] = ww
    dt['spec_con'] = ff
    dt["ln_spec_con"] = np.log(ff)
    return dt
示例#7
0
def deredden_spectrum(wave, flux, ebv, r_v=3.1, unit='aa', model='fm07'):
    """Deredden a spectrum based on a Galactic extinction model."""

    model = model.lower().strip()

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

    return remove(mw_extinction, flux)
示例#8
0
def get_ltspec(z=0.0213, date = '0409', vkernel = 800, t0jd = 58583.2, ebv = 0.022):
    myfile = "../data/spectra/ZTF18abfcmjw_2019"+date+"_LT_v1.ascii"
    f = open(myfile)
    lines = f.readlines()
    f.close()
    lines = np.array(lines)
    
    ind = np.array([x[:11]=="# MJD     =" for x in lines])
    myline = lines[ind] [0]  
    mjd= float(myline[15:-30])
    phase = mjd - t0jd
    
    tb = asci.read(myfile)
    dt = {}
    dt["phase"] = np.round(phase, 2)
    dt['wave_rest'] = tb['col1'].data/(1+z)
    dt['spec_obs'] = tb['col2'].data*8e-17
    Aextmag =  extinction.ccm89(dt['wave_rest'], 3.1*ebv, 3.1) # extinction in magnitudes
    tau =  Aextmag / 1.086
    dt['spec_obs0'] = dt['spec_obs'] * np.exp(tau)
    dt["ln_spec_obs"] = np.log(dt['spec_obs0'])

    ww, ff = convolve_with_constant_velocity_kernel(dt['wave_rest'], dt['spec_obs0'], vkernel)
    dt['wave_con'] = ww
    dt['spec_con'] = ff
    dt["ln_spec_con"] = np.log(ff)
    return dt
示例#9
0
def get_P60_eff_wave(myfilter="i'", return_type='R'):
    tb = pd.read_csv('../data/filters/P60/AstrodonSloanGen2Transmission.csv')
    if myfilter == "i'":
        wavecol = "Wavelength (nm).3"
    elif myfilter == "r'":
        wavecol = "Wavelength (nm).2"
    elif myfilter == "g'":
        wavecol = "Wavelength (nm).1"

    wv = tb[wavecol].values * 10
    fg = tb[myfilter].values
    ix = (~np.isnan(wv)) & (~np.isnan(fg))
    wv = wv[ix]
    fg = fg[ix]
    fg /= max(fg)

    wv_diff_ = wv[1:] - wv[:-1]
    wv_diff = 0.5 * (np.hstack([wv_diff_[0], wv_diff_]) +
                     np.hstack([wv_diff_, wv_diff_[-1]]))

    g_eff = np.sum(wv_diff * fg * wv) / np.sum(wv_diff * fg)
    ebv = 1
    Rg = extinction.ccm89(np.array([g_eff]), 3.1 * ebv, 3.1)[0]

    # print ("effective wavelength of %s is %f AA"%(myfilter, g_eff))
    if return_type == 'R':
        return Rg
    elif return_type == 'more':
        return g_eff, wv, fg
示例#10
0
def get_sn2018gep():
    z = 0.03154
    ebv = 0.01
    D = cosmo.luminosity_distance([z])[0].value * 1e+6  # in pc
    dis_mod = 5 * np.log10(D / 10)

    tb = asci.read('../data/otherSN/SN2018gep/table5.txt')
    tb = tb.to_pandas()
    tb = tb.rename(
        columns={
            'col1': 'jd',
            'col2': 'phase',
            'col3': 'instrument',
            'col4': 'filter',
            'col5': 'mag',
            'col6': 'emag'
        })
    tb = tb[tb.instrument == "P48+ZTF"]
    ixg = tb['filter'].values == "g"
    ixr = tb['filter'].values == "r"
    ixi = tb['filter'].values == "i"
    tb['wave'] = np.zeros(len(tb))
    tb['wave'].values[ixg] = 4814
    tb['wave'].values[ixr] = 6422
    tb['wave'].values[ixi] = 7883
    tb['mag0'] = tb['mag'] - extinction.ccm89(tb['wave'].values, 3.1 * ebv,
                                              3.1)
    tb['mag0_abs'] = tb['mag0'] - dis_mod
    tb = tb[tb.wave != 0]
    tb["mjd"] = tb["jd"] - 2400000.5
    t_max = 2458374.6845 - 2400000.5  # from my eye-inspection
    tb['tmax_rf'] = (tb['mjd'] - t_max) / (1 + z)
    return tb
示例#11
0
文件: test.py 项目: hsalas/extinction
def test_ccm89():
    # NOTE: Test is only to precision of 0.016 because there is a discrepancy
    # of 0.014 for the B band wavelength of unknown origin (and up to 0.002 in
    # other bands).
    #
    # Note that a and b can be obtained with:
    # b = ccm89(wave, 0.)
    # a = ccm89(wave, 1.) - b
    #
    # These differ from the values tablulated in the original paper.
    # Could be due to floating point errors in the original paper?
    #
    # U, B, V, R, I, J, H, K band effective wavelengths from CCM '89 table 3

    x_inv_microns = np.array([2.78, 2.27, 1.82, 1.43, 1.11, 0.80, 0.63, 0.46])
    wave = 1.e4 / x_inv_microns

    # A(lambda)/A(V) for R_V = 3.1 from Table 3 of CCM '89
    ref_values = np.array(
        [1.569, 1.337, 1.000, 0.751, 0.479, 0.282, 0.190, 0.114])

    assert_allclose(extinction.ccm89(wave, 1.0, 3.1),
                    ref_values,
                    rtol=0.016,
                    atol=0.)
示例#12
0
def get_ptf09dav():
    tb = asci.read('../data/otherSN/Sullivan2011/ptf09dav')
    tb.rename_column('band', 'filter')
    tb.rename_column('magnitude', 'mag')
    tb.rename_column('e_magnitude', 'emag')
    tb.remove_column("instrument")
    tb = tb[tb['mag'] > 19.7]
    ix = np.any([tb['filter'] == 'r', tb['filter'] == 'R'], axis=0)
    tb = tb[ix]
    tb['filter'] == 'r'
    z = 0.0359
    D = cosmo.luminosity_distance([z])[0].value * 1e+6  # in pc
    ebv = 0.044
    dis_mod = 5 * np.log10(D / 10)
    t_max = 55054  # r band maximum

    tb['wave'] = np.ones(len(tb)) * 6422
    tb['mag0'] = tb['mag'] - extinction.ccm89(tb['wave'], 3.1 * ebv, 3.1)
    tb['mag0_abs'] = tb['mag0'] - dis_mod
    tb['tmax_rf'] = (tb['time'] - t_max) / (1 + z)
    tb['emag'] = np.ones(len(tb)) * 0.1
    tb.remove_row(2)
    tb['mag0_abs'][1] = -15.4
    tb = tb.to_pandas()
    return tb
示例#13
0
def UbandExcess_to_Mdot(Uexcess, dist, mass, radius, Av, Rin=5, unc=False):
    '''
    This function will transform a U band flux value into a mass accretion rate estimate by following 
    the process described in Robinson 2019. 
    
    Inputs:
    Uexcess - U band continuum excess flux [erg/(s*cm^2)]
    dist - distance to object [pc]
    mass - mass of object [Msun]
    radius - radius of object [Rsun]
    
    Optional:
    Rin - magnetospheric radius (default 5 [Rsun])
    
    Outputs:
    Mdot - mass accretion rate [Msun/yr]
    '''
    #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
    deredU = ex.remove(Au, Uexcess)

    #U-band flux to Lu
    Lu = flux_to_luminosity(deredU, dist)

    #convert Lu to solar luminosity
    Lu = Lu / const.L_sun.to('erg/s').value

    #Lu to Lacc using Robinson paper -- natural logarithms
    #uncertainties 0.03 for each constant
    if unc == False:
        logLacc = 0.93 * np.log(Lu) + 0.5
    else:
        logLacc = (0.93 + np.random.normal(0.03)) * np.log(Lu) + (
            0.5 + np.random.normal(0.03))
    Lacc = np.exp(logLacc)

    #accretion luminosity to Mdot
    Mdot = Lacc_to_Mdot(Lacc, mass, radius, Rin)
    return Mdot
示例#14
0
def UVExcess_to_Mdot(UVexcess, bc, dist, mass, radius, Av, Rin=5):
    '''
    This function will transform a UV Excess flux value into a mass accretion rate estimate by following 
    the process described in Herczeg 2008. 
    
    Inputs:
    UVexcess - UV continuum excess flux [erg/(s*cm^2)]
    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:
    Mdot - mass accretion rate [Msun/yr]
    '''
    #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
    deredUV = ex.remove(Au, UVexcess)

    #use the bolometric correction factor to scale the UV excess flux to total accretion flux
    total_excess = deredUV * bc

    #accretion flux to accretion luminosity
    Lacc = flux_to_luminosity(total_excess, dist)

    #convert accretion luminosity to solar luminosity
    Lacc = Lacc / const.L_sun.to('erg/s').value

    #accretion luminosity to Mdot
    Mdot = Lacc_to_Mdot(Lacc, mass, radius, Rin)
    return Mdot
示例#15
0
def get_sn2018kzr(colorplt=False):
    """
    Owen R. Mcbrien 2019
    """
    ebv = 0.113 / 3.1
    z = 0.053
    D = cosmo.luminosity_distance([z])[0].value * 1e+6  # in pc
    dis_mod = 5 * np.log10(D / 10)
    t_max = 58480.422 + 0.1

    f = open('../data/otherSN/Mcbrien2019/table1.tex')
    lines = f.readlines()
    f.close()
    lines = lines[:-4]

    dates = [x.split("&")[0] for x in lines]
    mjds = [float(x.split("&")[1]) for x in lines]
    phases = [
        float(x.split("&")[2].replace('$', '').replace('\t', ''))
        for x in lines
    ]
    gs = [x.split("&")[3].replace('$', '') for x in lines]
    rs = [x.split("&")[4].replace('$', '') for x in lines]
    iis = [x.split("&")[5].replace('$', '') for x in lines]
    zs = [x.split("&")[6].replace('$', '') for x in lines]
    insts = [x.split("&")[7] for x in lines]

    dtg = digital_latex(mjds, phases, gs, insts)
    dtr = digital_latex(mjds, phases, rs, insts)
    dti = digital_latex(mjds, phases, iis, insts)

    filt = np.hstack([
        np.repeat("g", len(dtg[0])),
        np.repeat("r", len(dtr[0])),
        np.repeat("i", len(dti[0]))
    ])
    phase = np.hstack([dtg[1], dtr[1], dti[1]])
    mag = np.hstack([dtg[2], dtr[2], dti[2]])
    emag = np.hstack([dtg[3], dtr[3], dti[3]])
    mjd = np.hstack([dtg[0], dtr[0], dti[0]])

    tb = Table(data=[(mjd - t_max) / (1 + z), mag, emag, filt],
               names=['tmax_rf', 'mag', 'emag', 'filter'])

    ixr = tb['filter'] == "r"
    ixg = tb['filter'] == "g"
    ixi = tb['filter'] == "i"
    tb['wave'] = np.zeros(len(tb))
    tb['wave'][ixg] = 4814
    tb['wave'][ixr] = 6422
    tb['wave'][ixi] = 7883
    tb['mag0'] = tb['mag'] - extinction.ccm89(tb['wave'], 3.1 * ebv, 3.1)
    tb['mag0_abs'] = tb['mag0'] - dis_mod
    tb = tb.to_pandas()
    return tb
示例#16
0
文件: spec.py 项目: janerigby/jrr
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)
示例#17
0
def deredden(spectrum, r_v):
    """
	Removes the extinction from the supernova and repopulates the signal types.
	Note that this function overrides the data stored in the spectrum object
	and creates a new set of data based on the new r_v value.

	:spectrum: (snmc.Spectrum object) the supernova to deredden
	:r_v: (float) the r_v value to use in the dereddening
	"""
    dust = extinction.ccm89(spectrum.wvs, r_v * spectrum.ebv, r_v)
    exp_dust = np.power(10, np.multiply(-0.4, dust))
    spectrum.signal['dust_flux'] = np.divide(spectrum.signal['flux'], exp_dust)
    spectrum.populate_signals()
    spectrum.normalize()
示例#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)
示例#19
0
    def deredden(self, wvs, flux, ebv):
        """
		Removes the extinction from the supernova based on the quoted ebv value

		:wvs: (float array) wavelengths
		:flux: (float array) flux values
		:ebv: (float) the quoted color excess pulled from the scraper

		:returns: (float array) corrected flux values
		"""
        wvs = np.array(wvs)
        dust = extinction.ccm89(wvs, self.pars.r_v * ebv, self.pars.r_v)
        exp_dust = np.power(10, np.multiply(-0.4, dust))
        return np.divide(flux, exp_dust)
示例#20
0
文件: rstar.py 项目: rabrahm/rstar
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
示例#21
0
def get_PS1_eff_wave(myfilter="g", return_type='more'):
    tb = asci.read("../data/filters/PS1/PAN-STARRS_PS1." + myfilter + ".dat")
    wv = tb["col1"].data
    fg = tb["col2"].data
    fg /= max(fg)
    wv_diff_ = wv[1:] - wv[:-1]
    wv_diff = 0.5 * (np.hstack([wv_diff_[0], wv_diff_]) +
                     np.hstack([wv_diff_, wv_diff_[-1]]))

    g_eff = np.sum(wv_diff * fg * wv) / np.sum(wv_diff * fg)
    ebv = 1
    Rg = extinction.ccm89(np.array([float(g_eff)]), 3.1 * ebv, 3.1)[0]

    if return_type == 'R':
        return Rg
    elif return_type == 'more':
        return g_eff, wv, fg
示例#22
0
def deredden_photometry(ext_mag, ext_mag_err, filter_eff_lambda, a_v, r_v=3.1):
    """Use an extinction law to deredden photometry from a given band.
    
    Relies on:
        https://github.com/kbarbary/extinction
    With documentation at:
        https://extinction.readthedocs.io/en/latest/
    
    Parameters
    ----------
    ext_mag: np.array of type float
        The extincted magnitude.
    
    ext_mag_err: np.array of type float
        Error in the extincted magnitude
    
    filter_eff_lamda: np.array of type float
        Effective wavelength of the broad-band photometric filter specific to
        stellar spectral type.
    
    a_v : np.array of type float
        Scaling parameter, A_V: extinction in magnitudes at characteristic
        V band wavelength.
    r_v : np.array of type float
        Ratio of total to selective extinction, A_V / E(B-V).
        
    Returns
    -------
    a_mags: float array
        Array of photometric extinction of form [W, S], where W is the number
        of wavelengths, and S is the number of stars.
    
    de_ext_mag_err: np.array of type float
        Error in the de-extincted magnitude.
    """
    # Create grid of extinction
    a_mags = np.zeros(ext_mag.shape)
    
    # Use the Cardelli, Clayton, & Mathis 1989 extinction model. The extinction
    # module is not vectorised, so we have to work with one star at a time
    for star_i, star in enumerate(ext_mag.itertuples(index=False)):
        a_mags[star_i,:] = extinction.ccm89(filter_eff_lambda, a_v[star_i], 
                                            r_v)
    
    return a_mags
示例#23
0
def get_ZTF_eff_wave(filename, return_type='R'):
    specg = np.loadtxt('../data/filters/P48/' + filename).T
    wv = specg[0]
    fg = specg[1]
    fg /= max(fg)

    wv_diff_ = wv[1:] - wv[:-1]
    wv_diff = 0.5 * (np.hstack([wv_diff_[0], wv_diff_]) +
                     np.hstack([wv_diff_, wv_diff_[-1]]))

    g_eff = np.sum(wv_diff * fg * wv) / np.sum(wv_diff * fg)
    ebv = 1
    Rg = extinction.ccm89(np.array([g_eff]), 3.1 * ebv, 3.1)[0]
    #print ("effective wavelength of %s is %f AA"%(filename, g_eff))
    if return_type == 'R':
        return Rg
    elif return_type == 'more':
        return g_eff, wv, fg
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
示例#25
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
示例#26
0
def get_LT_eff_wave(filename, return_type='R'):
    specg = asci.read('../data/filters/LT/' + filename)
    wv = specg['Wavelength(nm)'].data * 10
    fg = specg['T%'].data
    fg /= max(fg)

    wv_diff_ = wv[1:] - wv[:-1]
    wv_diff = 0.5 * (np.hstack([wv_diff_[0], wv_diff_]) +
                     np.hstack([wv_diff_, wv_diff_[-1]]))

    g_eff = np.sum(wv_diff * fg * wv) / np.sum(wv_diff * fg)
    ebv = 1
    Rg = extinction.ccm89(np.array([g_eff]), 3.1 * ebv, 3.1)[0]

    #print ("effective wavelength of %s is %f AA"%(filename, g_eff))
    if return_type == 'R':
        return Rg
    elif return_type == 'more':
        return g_eff, wv, fg
示例#27
0
def get_hstspec(z=0.0213, t0jd = 58583.2, ebv = 0.022):
    """
    https://archive.stsci.edu/cgi-bin/mastpreview?mission=hst&dataid=IDYQ7B030
    Apr 22 2019 5:08AM
    """
    mjd = Time('2019-04-22T05:08:00', format='isot', scale = 'utc').mjd
    phase = mjd - t0jd

    tb = asci.read("../data/spectra/spectrum.txt")
    tb = tb[~np.isnan(tb["col2"])]
    dt = {}
    dt['wave_rest'] = tb['col1'].data/(1+z)
    dt['spec_obs'] = tb['col2'].data
    Aextmag =  extinction.ccm89(dt['wave_rest'], 3.1*ebv, 3.1) # extinction in magnitudes
    tau =  Aextmag / 1.086
    dt['spec_obs0'] = dt['spec_obs'] * np.exp(tau)
    dt["ln_spec_obs"] = np.log(dt['spec_obs0'])
    dt["phase"] = np.round(phase, 2)
    return dt
示例#28
0
def get_SDSS_eff_wave(ext=2, return_type='more'):
    """
    extension 2: g band
    """
    tb = Table(fits.open("../data/filters/SDSS/filter_curves.fits")[ext].data)
    wv = tb["wavelength"].data
    fg = tb["respt"].data
    fg /= max(fg)
    wv_diff_ = wv[1:] - wv[:-1]
    wv_diff = 0.5 * (np.hstack([wv_diff_[0], wv_diff_]) +
                     np.hstack([wv_diff_, wv_diff_[-1]]))

    g_eff = np.sum(wv_diff * fg * wv) / np.sum(wv_diff * fg)
    ebv = 1
    Rg = extinction.ccm89(np.array([float(g_eff)]), 3.1 * ebv, 3.1)[0]

    if return_type == 'R':
        return Rg
    elif return_type == 'more':
        return g_eff, wv, fg
示例#29
0
文件: utils.py 项目: FRBs/FRB
def deredden_spec(spectrum:xspectrum1d.XSpectrum1D, ebv:float):
    """ Deredden the input spectrum using the input EBV value

    Args:
        spectrum (xspectrum1d.XSpectrum1D): Spectrum
        ebv (float): Galactic reddening

    Returns:
        xspectrum1d.XSpectrum1D: De-reddened spectrum
    """

    # Correct for Galactic extinction
    AV = ebv * 3.1  # RV
    Al = extinction.ccm89(spectrum.wavelength.value, AV, 3.1)
    # New spec
    new_flux = spectrum.flux * 10**(Al/2.5)
    new_sig = spectrum.sig * 10**(Al/2.5)
    new_spec = xspectrum1d.XSpectrum1D.from_tuple((spectrum.wavelength, new_flux, new_sig))

    # Return
    return new_spec
示例#30
0
def calc_extinction(E_BV, band, Rv=3.1, E_BV_err=0):
    '''
    Calculate extinction using the Cardelli law
    E_BV: float
        E(B-V) value
    band: str
        filter corresponding to filter in define_filters dictionary
    Rv: float
        R(V) set to 3.1 by default
    E_BV_err: float
        1 sigma error in E(B-V), set to 0 by default
    '''
    Av = Rv * E_BV
    Av_err = Rv**2 * E_BV_err**2
    cenwave = np.array([float(get_cenwave(band))])
    A_band = extinction.ccm89(cenwave, Av, Rv)
    if Av == 0:
        A_band_err = 0.0
    else:
        A_band_err = np.sqrt(Av_err * A_band / Av)
    return A_band, A_band_err
示例#31
0
def MarginalReddening(m_obs, m_true, sg):
    dom = min_extinc_usco, max_extinc_usco
    stp = 100
    #------ grid and deltas
    dtau = (dom[1] - dom[0]) / (stp - 1)
    tau = np.linspace(dom[0], dom[1], stp)

    #-------- extinction integral ------------
    wls = np.array([7630.0, 10310.0, 12500, 16500, 21500
                    ])  # Wavelengths in agstroms (i SDSS, Y UKIDSS, JHK 2MASS)
    pA = p_extinction(tau)
    ext = np.array(map(lambda x: extinction.ccm89(wls, x, 3.1), tau))

    ext[:, 0] = ext[:, 0] - ext[:, 4]
    extincted = m_true + ext
    #------------------------------------------------------
    #x         = m_obs - extincted
    #p_redden = np.exp(-0.5*(np.dot(x.T,isg.dot(x))+lden))
    p_redden = st.multivariate_normal.pdf(extincted, mean=m_obs, cov=sg)
    # returns the integral over reddening
    return np.dot(pA, p_redden) * dtau
示例#32
0
文件: test.py 项目: earnric/modules
def test_ccm89():
    # NOTE: Test is only to precision of 0.016 because there is a discrepancy
    # of 0.014 for the B band wavelength of unknown origin (and up to 0.002 in
    # other bands).
    #
    # Note that a and b can be obtained with:
    # b = ccm89(wave, 0.)
    # a = ccm89(wave, 1.) - b
    # 
    # These differ from the values tablulated in the original paper.
    # Could be due to floating point errors in the original paper?
    #
    # U, B, V, R, I, J, H, K band effective wavelengths from CCM '89 table 3

    x_inv_microns = np.array([2.78, 2.27, 1.82, 1.43, 1.11, 0.80, 0.63, 0.46])
    wave = 1.e4 / x_inv_microns

    # A(lambda)/A(V) for R_V = 3.1 from Table 3 of CCM '89
    ref_values = np.array([1.569, 1.337, 1.000, 0.751, 0.479, 0.282, 0.190,
                           0.114])

    assert_allclose(extinction.ccm89(wave, 1.0, 3.1), ref_values,
                    rtol=0.016, atol=0.)
示例#33
0
文件: plot.py 项目: earnric/modules
#!/usr/bin/env python
"""Plot extinction functions for comparison"""

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
from mpl_toolkits.axes_grid1 import make_axes_locatable

import extinction

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

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

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

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

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

ax = plt.axes()
for name in names:
    plt.plot(wave, a_lambda[name], label=name)
plt.axvline(x=2700., ls=':', c='k')
plt.axvline(x=3030.3030, ls=':', c='k')
plt.axvline(x=9090.9091, ls=':', c='k')
plt.axvspan(wave[0], 1150., fc='0.8', ec='none', zorder=-1000)
plt.axvspan(1150., 1250., fc='0.9', ec='none', zorder=-1000)    
示例#34
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)