Exemple #1
0
def vel_moment(spec, restlam, zabs, vellim=[-50, 50]):
    wave = spec.wavelength.value
    flux = spec.flux.value
    sig = spec.sig.value
    cont = spec.co
    conterr = np.zeros_like(sig)  # Continuum errors will be garbage
    EWpix, sigEWf, sigEWc, Npix, sigNf, sigNc = EW_ACD_array(wave,
                                                             flux,
                                                             sig,
                                                             cont,
                                                             conterr,
                                                             restlam,
                                                             zabs,
                                                             vellim=vellim)
    ### Transform to velocity space
    vel = joebgoodies.veltrans(zabs, wave, restlam)
    velidx = np.where((vel >= vellim[0]) & (vel <= vellim[1]))[0]

    ### Calculate moments
    moment0 = np.sum(Npix)
    moment1 = np.sum(vel[velidx] * Npix)

    ### Mean velocity
    meanv = moment1 / moment0
    return meanv
Exemple #2
0
def vel_moment_fitcont(wave,
                       flux,
                       sig,
                       restlam,
                       zabs,
                       continuumregions,
                       vellim=[-50, 50],
                       **kwargs):
    ### Fit the continuum in the line-free regions
    wave, cont, conterr = contFitLegendreAboutLine(wave, flux, sig, restlam,
                                                   zabs, continuumregions,
                                                   **kwargs)
    EWpix, sigEWf, sigEWc, Npix, sigNf, sigNc = EW_ACD_array(wave,
                                                             flux,
                                                             sig,
                                                             cont,
                                                             conterr,
                                                             restlam,
                                                             zabs,
                                                             vellim=vellim)
    ### Transform to velocity space
    vel = joebgoodies.veltrans(zabs, wave, restlam)
    velidx = np.where((vel >= vellim[0]) & (vel <= vellim[1]))[0]
    velup = vel[velidx + 1]
    veldown = vel[velidx]

    ### Calculate moments
    moment0 = np.sum(Npix)
    moment1 = np.sum(vel[velidx] * Npix)

    ### Mean velocity
    meanv = moment1 / moment0
    return meanv
Exemple #3
0
def fitpix(wave,pararr):
	# define bad pixels
	cfg.bad_pixels = update_bad_pixels() # this variable stores the indices of bad pixels

	ll=pararr[0]
	lz=pararr[3]
	lv1=pararr[5]
	lv2=pararr[6]
	relpix=[]
	for i in range(len(ll)):
		vels=jbg.veltrans(lz[i],wave,ll[i])
		#w1=ll[i]*(1.+lz[i]+lv1[i]/c)
		#w2=ll[i]*(1.+lz[i]+lv2[i]/c)
		#p1=jbg.closest(wave,w1)
		#p2=jbg.closest(wave,w2)
		p1=jbg.closest(vels,lv1[i])
		p2=jbg.closest(vels,lv2[i])

		if ((p1>=10) & (p2<=(len(wave)-1-10))):
			relpix.extend(range(p1-10,p2+10))
		elif (p1<10):
			relpix.extend(range(0, p2 + 10))
		else:
			relpix.extend(range(p1 - 10, len(wave)-1))
	rp = np.unique(np.array(relpix))
	clean_rp = np.array([i for i in rp if i not in cfg.bad_pixels])
	return clean_rp
Exemple #4
0
def fitpix(wave,pararr,find_bad_pixels=True):
	if find_bad_pixels:
		# define bad pixels
		cfg.bad_pixels = update_bad_pixels() # this variable stores the indices of bad pixels
	else:
		cfg.bad_pixels = []
		
	ll=pararr[0]
	lz=pararr[3]
	lv1=pararr[5]
	lv2=pararr[6]
	relpix=[]
	for i in range(len(ll)):
		vels=jbg.veltrans(lz[i],wave,ll[i])
		p1=jbg.closest(vels,lv1[i])
		p2=jbg.closest(vels,lv2[i])

		if ((p1>=10) & (p2<=(len(wave)-1-10))):
			relpix.extend(range(p1-10,p2+10))
		elif (p1<10):
			relpix.extend(range(0, p2 + 10))
		else:
			relpix.extend(range(p1 - 10, len(wave)-1))
	rp = np.unique(np.array(relpix))
	clean_rp = np.array([i for i in rp if i not in cfg.bad_pixels])
	return clean_rp
Exemple #5
0
def fitpix(wave, pararr, find_bad_pixels=True):

    if find_bad_pixels:
        # define bad pixels
        cfg.bad_pixels = update_bad_pixels(
        )  # this variable stores the indices of bad pixels
    else:
        cfg.bad_pixels = []

    ll = pararr[0]
    lz = pararr[3]
    lv1 = pararr[5]
    lv2 = pararr[6]
    relpix = []
    for i in range(len(ll)):
        vels = jbg.veltrans(lz[i], wave, ll[i])
        p1 = jbg.closest(vels, lv1[i])
        p2 = jbg.closest(vels, lv2[i])

        if ((p1 >= 10) & (p2 <= (len(wave) - 1 - 10))):
            relpix.extend(range(p1 - 10, p2 + 10))
        elif (p1 < 10):
            relpix.extend(range(0, p2 + 10))
        else:
            relpix.extend(range(p1 - 10, len(wave) - 1))
    rp = np.unique(np.array(relpix))
    clean_rp = np.array([i for i in rp if i not in cfg.bad_pixels])

    if len(clean_rp) > 1:
        # Matt and Kirill trimming off tiny pixel patches
        max_index_jump = 4  # this is called buf in makevoigt
        min_group_size = 5

        last_idx = clean_rp[0]
        group_idxs = [last_idx]
        really_clean_rp = []
        for idx in clean_rp[1:]:
            jump = idx - last_idx
            if jump <= max_index_jump:
                group_idxs.append(idx)
            else:
                if len(group_idxs) >= min_group_size:
                    really_clean_rp.extend(group_idxs)
                group_idxs = [idx]  # start a new group

            last_idx = idx

        if len(group_idxs) >= min_group_size:
            really_clean_rp.extend(group_idxs)

        return np.array(really_clean_rp, dtype=int)
    else:
        return clean_rp
Exemple #6
0
def contFitLegendreAboutLine(wave,
                             flux,
                             err,
                             restlam,
                             z,
                             velfitregions,
                             uniform=True,
                             **kwargs):
    '''
    Fits a continuum over a spectral region using the formalism of Sembach
    & Savage 1992, estimating the uncertainty at each point of the continuum.

    Parameters
    ----------
    wave
    flux
    err
    restlam
    z
    velfitregions
    uniform

    Returns
    -------

    '''
    vels = joebgoodies.veltrans(z, wave, restlam)

    ### Find indices corresponding to velocities defined in velfitregions
    fitidxs = []
    for reg in velfitregions:
        thesevels = np.where((vels >= reg[0]) & (vels <= reg[1]))[0]
        fitidxs.extend(thesevels)

    if uniform != True:
        fitsol, err, parsol, errmtx, scalefac = fitLegendre(vels[fitidxs],
                                                            flux[fitidxs],
                                                            sig=err[fitidxs],
                                                            **kwargs)
    else:
        fitsol, err, parsol, errmtx, scalefac = fitLegendre(
            vels[fitidxs], flux[fitidxs], **kwargs)

    ### Normalize x so that domain of fit is -1 to +1
    vscale = vels / scalefac  # must scale to fitted domain

    ### Evaluate continuum using all points, not just those in fit regions
    continuum = L.legval(vels / scalefac, parsol)
    err = errorsLegendre(vscale, errmtx)

    return wave, continuum, err
Exemple #7
0
def EW_ACD_array(wave,
                 flux,
                 ferr,
                 cont,
                 conterr,
                 restlam,
                 zabs,
                 vellim=[-50, 50],
                 **kwargs):
    '''
    Returns arrays of equivalent width and apparent column density per pixel as
    well as their associated uncertainties due to continuum placement and flux errors.

    Parameters
    ----------
    wave: 1D float array
    flux: 1D float array
    ferr: 1D float array
        Error in flux
    cont: 1D float array
        Continuum fitted to data such as that from contFitLegendreAboutLine()
    conterr: 1D float array
        Uncertainty in continuum placement at each pixel
    restlam: float
        Rest-frame wavelength of transition to measure
    zabs: float
        Redshift of the the absorption system
    vellim: 2-element list
        Lower and upper bounds over which to compute arrays

    Returns
    -------
    EWpix: 1D float array
        Equivalent width in each pixel
    sigEWf: 1D float array
        EW uncertainty in each pixel due to flux errors
    sigEWc: 1D float array
        EW uncertainty in each pixel due to continuum placement errors
    Npix: 1D float array
        Apparent column density * dv (N) in each pixel
    sigNf: 1D float array
        Uncertainty in N due to flux errors
    sigNc: 1D float array
        Uncertainty in N due to continuum placement errors
    '''

    ### Set atomic data and constants
    c = 299792.458
    restlam = ad.closestlam([restlam])
    osc = ad.lam2osc([restlam])

    ### Transform to velocity space
    vel = joebgoodies.veltrans(zabs, wave, restlam)
    velidx = np.where((vel >= vellim[0]) & (vel <= vellim[1]))[0]
    velup = vel[velidx + 1]
    veldown = vel[velidx]
    dv = np.abs(velup - veldown)

    ### Identify pixels where flux level is below noise level & replace w/noise
    effflux = flux
    belowerr = np.where(flux < ferr)[0]
    effflux[belowerr] = ferr[belowerr]

    ### Calculate EW and errors due to flux and continuum placement
    print(dv, effflux[velidx], cont[velidx], restlam, c)
    EWpix = dv * (1. - effflux[velidx] / cont[velidx]) * restlam / c
    sigEWf = dv / cont[velidx] * ferr[velidx] * restlam / c
    sigEWc = dv * restlam / c * effflux[velidx] / cont[velidx]**2 * conterr[
        velidx]  # Will not be added in quad.

    ### Calculate optical depth and uncertainty due to flux and continuum
    tauv = np.log(cont[velidx] / (effflux[velidx]))
    tauverr_f = ferr[velidx] / effflux[velidx]
    tauverr_c = conterr[velidx] / cont[velidx]
    Npix = 1. / 2.654e-15 / restlam / osc * dv * tauv
    sigNf = 1. / 2.654e-15 / restlam / osc * dv * tauverr_f
    sigNc = 1. / 2.654e-15 / restlam / osc * dv * tauverr_c

    return EWpix, sigEWf, sigEWc, Npix, sigNf, sigNc