Exemplo n.º 1
0
def get_line_resolution(line, file):
    import pyfits
    from mostools import spectools as st
    spec = pyfits.open(file)[3].data.copy()
    wave = st.wavelength(file, 1)
    data = spec.astype(scipy.float64)
    data[scipy.isnan(data)] = 0.
    size = data.size

    bg = ndimage.percentile_filter(data, 20, 55)
    bg = ndimage.gaussian_filter(bg, 7)
    data -= bg

    pos = abs(wave - line).argmin()
    fitdata = scipy.zeros((15, 2))
    fitdata[:, 0] = wave[pos - 7:pos + 8]
    fitdata[:, 1] = data[pos - 7:pos + 8]

    par = scipy.zeros(4)
    par[1] = data[pos]
    par[2] = line
    par[3] = 1.

    fit, chi2 = special_functions.ngaussfit(fitdata, par)

    pixsize = wave[pos] - wave[pos - 1]
    if fit[3] > 5. * pixsize or fit[3] < 0.8 * pixsize or abs(
            fit[2] - wave[pos]) > 1.5 * fit[3]:
        print 'Could not fit for resolution of spectral line'
        print fit
        return 0

    v = fit[2] / fit[3]
    return 299792. / v
Exemplo n.º 2
0
def extract(outname,root,slit,pos,width=1.):
	"""
	extract(outname,root,slit,pos,width=1.)

	Extracts a spectrum from 2d mask and variance images.

	Inputs:
	  outname - name of output FITS file
	  root    - root name of input data (ie ROOTNAME_bgsub.fits)
	  slit    - number of slit to extract from (1 = bottom slit)
	  pos     - position along slit to extract
	  width   - gaussian-sigma width to extract

	Outputs:
	  FITS file containing extracted spectrum.
	"""
	infile = root+"_bgsub.fits"
	spectools.cutout(infile,outname,slit)
	wave = spectools.wavelength(outname)
	data = pyfits.open(outname)[0].data.astype(scipy.float32)
	os.remove(outname)
	infile = root+"_var.fits"
	spectools.cutout(infile,outname,slit)
	varimg = pyfits.open(outname)[0].data.astype(scipy.float32)
	os.remove(outname)

	yvals = scipy.arange(data.shape[0]).astype(scipy.float32)

	fit = scipy.array([0.,1.,pos,width])
	weight = sf.ngauss(yvals,fit)
	weight[abs(yvals-pos)/width>1.5] = 0.
	weight /= weight.sum()

	spec = weight*data.T
	spec = spec.sum(axis=1)
	varspec = weight*varimg.T
	varspec = varspec.sum(axis=1)
	spec[varspec==0] = 0.
	smooth = signal.wiener(spec,7,varspec)
	smooth[scipy.isnan(smooth)] = 0.

	hdu = pyfits.PrimaryHDU()
	hdu.header.update('CENTER',pos)
	hdu.header.update('WIDTH',width)
	hdulist = pyfits.HDUList([hdu])

	crval = wave[0]
	scale = wave[1]-wave[0]
	for i in [spec,smooth,varspec]:
		thdu = pyfits.ImageHDU(i)
		thdu.header.update('CRVAL1',crval)
		thdu.header.update('CD1_1',scale)
		thdu.header.update('CRPIX1',1)
		thdu.header.update('CRVAL2',1)
		thdu.header.update('CD2_2',1)
		thdu.header.update('CRPIX2',1)
		thdu.header.update('CTYPE1','LINEAR')
		hdulist.append(thdu)

	hdulist.writeto(outname)
Exemplo n.º 3
0
def get_resolution(file):
    import pyfits
    from mostools import spectools as st
    spec = pyfits.open(file)[3].data.copy()
    wave = st.wavelength(file, 1)
    v = measure(spec, wave)
    if v == 1:
        print 'No lines fit!'
        return 0
    return 299792. / v[0]
Exemplo n.º 4
0
def vegacorr(input, output, size=250):
    d = pyfits.open(input)[1].data.copy()
    wave = st.wavelength(input, 1)
    k = numpy.linspace(wave[0], wave[-1], wave.size / size)

    twave, trans = cPickle.load(open(dir + 'data/trans.dat'))
    kernel = (wave[1] - wave[0]) / (1e4 * (twave[1] - twave[0]))
    trans = ndimage.gaussian_filter(trans, kernel)
    sky = interpolate.splrep(twave * 1e4, trans, k=3, s=0)

    swave, star = cPickle.load(open(dir + 'data/vega.dat'))
    snorm = star.mean()
    starmodel = interpolate.splrep(swave * 10., star / snorm, k=3, s=0)

    def dofit(p, wave, star, vega, sky, trans=False):
        vvel, broad, svel, scale = p
        vwave = 10**(numpy.log10(wave) * vvel)
        v = interpolate.splev(vwave, vega)
        v = ndimage.gaussian_filter(v, broad)
        swave = 10**(numpy.log10(wave) * svel)
        s = interpolate.splev(swave, sky)**scale
        s[swave < 8510.] = 1.
        mod = interpolate.splrep(wave, star / (v * s), t=k[1:-1], k=3, task=-1)
        model = s * v * interpolate.splev(wave, mod)
        if trans:
            return v / model
        return model - star

    pars = [1., 1., 1., 1.]
    coeff, ier = optimize.leastsq(dofit, pars, (wave, d, starmodel, sky))

    model = dofit(coeff, wave, d, starmodel, sky, True) / snorm
    model = interpolate.splrep(wave, model)
    f = open(output, 'wb')
    cPickle.dump(model, f, 2)
    f.close()
    return model
Exemplo n.º 5
0
def extract(image,
            varimage,
            outname,
            width=2.,
            offset=0.,
            pos=None,
            minwave=None,
            maxwave=None,
            response_image=None,
            response_model=None,
            regions=[],
            centroid=None):

    if outname.lower().find('fits') < 1:
        outname = "%s.fits" % outname

    resp = None
    respwave = None
    if response_image is not None:
        if response_model is None:
            #            print "No response model included; not performing response correction."
            import cPickle
            resp = cPickle.load(open(response_image))
        else:
            resp = get_response(response_image, response_model, regions)
    elif response_model is not None:
        print "No response image included; not performing response correction."

    if minwave is None:
        minwave = -10.
    if maxwave is None:
        maxwave = 1e99

    data = pyfits.open(image)[0].data.copy()
    if data.ndim == 3:
        if data.shape[0] > 1:
            print "Only working on first image plane of 3D image."
        data = data[0].copy()
    wave = st.wavelength(image)
    indx = scipy.where((wave > minwave) & (wave < maxwave))[0]
    minx, maxx = indx.min(), indx.max()
    wave = wave[minx:maxx]
    data = data[:, minx:maxx]
    tmp = data.copy()

    tmp[numpy.isnan(data)] = 0.

    ospec = wave * 0.
    ovar = wave * 0.
    x = numpy.arange(data.shape[0])
    if centroid is None:
        n = tmp.shape[1] / 100
        peaks = []
        bounds = numpy.linspace(0, tmp.shape[1], n + 1)
        for i in range(n):
            a, b = bounds[i], bounds[i + 1]
            p = tmp[:, a:b].sum(1).argmax()
            peaks.append([(a + b) / 2., p])
        peak = sf.lsqfit(numpy.asarray(peaks), 'polynomial', 3)

        if pos is not None:
            peak['coeff'][0] = pos

        peaks = sf.genfunc(numpy.arange(tmp.shape[1]), 0., peak)

        center = wave * 0.
        for i in range(center.size):
            d = data[:, i].copy()
            peak = peaks[i]
            if peak < 0:
                peak = 0
            if peak >= d.shape:
                peak = d.shape - 1.
            fit = numpy.array([0., d[peak], peak, 1.])
            cond = ~numpy.isnan(d)
            input = numpy.empty((d[cond].size, 2))
            input[:, 0] = x[cond].copy()
            input[:, 1] = d[cond].copy()
            fit = sf.ngaussfit(input, fit)[0]
            center[i] = fit[2]

        fit = sf.lsqfit(ndimage.median_filter(center, 17), 'polynomial', 5)
        centroid = sf.genfunc(scipy.arange(wave.size), 0., fit)
    #import pylab
    #pylab.plot(center-centroid)
    #pylab.show()

    xvals = scipy.arange(data.shape[0])
    var = pyfits.open(varimage)[0].data.copy()
    if var.ndim == 3:
        var = var[0].copy()
    var = var[:, minx:maxx]
    cond = (numpy.isnan(var)) | (numpy.isnan(data))

    for i in range(ovar.size):
        c = centroid[i] + offset
        wid = width

        mask = xvals * 0.
        mask[(xvals - c < wid) & (xvals - c > 0.)] = wid - (xvals[
            (xvals - c < wid) & (xvals - c > 0.)] - c)
        mask[(xvals - c < wid - 1) & (xvals - c > 0.)] = 1.
        mask[(c - xvals < wid + 1) & (c - xvals > 0.)] = (wid + 1) - (
            c - xvals[(c - xvals < wid + 1) & (c - xvals > 0.)])
        mask[(c - xvals < wid) & (c - xvals > 0.)] = 1.
        mask[cond[:, i]] = 0.
        mask /= mask.sum()

        ospec[i] = (mask[~cond[:, i]] * data[:, i][~cond[:, i]]).sum()
        ovar[i] = ((mask[~cond[:, i]]**2) * var[:, i][~cond[:, i]]).sum()

    badpix = numpy.where(numpy.isnan(ospec))[0]
    ospec[badpix] = 0.
    ovar[badpix] = ovar[~numpy.isnan(ovar)].max() * 1e6

    med = numpy.median(ospec)
    ospec /= med
    ovar /= med**2

    if resp is not None:
        #        if respwave is None:
        #            resp = sf.genfunc(wave,0,resp)
        #        else:
        #        resp = interpolate.splrep(respwave,resp)
        resp = interpolate.splev(wave, resp)
        ospec *= resp
        ovar *= resp**2

    st.make_spec(ospec, ovar, wave, outname, clobber=True)
    return centroid
Exemplo n.º 6
0
def get_response(image, model, regions):
    model = numpy.loadtxt(model)
    mwave = model[:, 0]
    mspec = model[:, 1]

    model = interpolate.splrep(mwave, mspec, k=3, s=0)

    hdu = pyfits.open(image)
    if len(hdu) == 4:
        spec = hdu[1].data.copy()
        wave = st.wavelength(image, 1)
    else:
        spec = hdu[0].data.copy()
        wave = st.wavelength(image)

    outmodel = interpolate.splev(wave, model)

    ratio = outmodel / spec

    badregions = []
    cond = ~numpy.isnan(ratio)
    cond = cond & (~numpy.isinf(ratio))
    for lo, hi in regions:
        badregions.append([lo, hi])
        cond = cond & (~((wave > lo) & (wave < hi)))
    scurrent = 2. * wave[cond].size**0.5
    smod = ratio[cond].mean()**2
    spmodel = interpolate.splrep(wave[cond],
                                 ratio[cond],
                                 k=3,
                                 s=scurrent * smod)
    resp = None
    while resp != 'q' and resp != 'Q':
        import pylab
        current = interpolate.splev(wave, spmodel)
        pylab.plot(wave, current)
        pylab.plot(wave, ratio)
        pylab.gca().fmt_xdata = pylab.FormatStrFormatter('%7.2f')
        pylab.show()
        resp = raw_input("Enter command (q, m, s, w, h): ")
        if resp == 'm':
            region = raw_input("Enter region to mask (eg, 6530,6580): ").split(
                ',')
            while len(region) != 2:
                region = raw_input(
                    "Please input wavelengths joined by a comma: ").split(',')
            lo, hi = float(region[0]), float(region[1])
            badregions.append([lo, hi])
            cond = cond & (~((wave > lo) & (wave < hi)))
            spmodel = interpolate.splrep(wave[cond],
                                         ratio[cond],
                                         k=3,
                                         s=scurrent * smod)
        elif resp == 's':
            scurrent = float(
                raw_input(
                    "Current smoothing factor is %4.2f, enter new smoothing factor: "
                    % scurrent))
            spmodel = interpolate.splrep(wave[cond],
                                         ratio[cond],
                                         k=3,
                                         s=scurrent * smod)
        elif resp == 'h':
            print "Use q to quit, m to mask, s to set smoothing scale, w to write model to disk"
        elif resp == 'w':
            import cPickle
            outname = raw_input("Name of file to write to: ")
            f = open(outname, 'wb')
            cPickle.dump(spmodel, f)
            f.close()

    print "Regions masked:", badregions
    return spmodel