예제 #1
0
def makeartificial(sw, sf, fmax, res, dw, pad=10, nkern=200, wrange=None):
    """For a given line list with fluxes, create an artifical spectrum"""
    if wrange is None:
        wrange = [sw.min() - pad, sw.max() + pad]
    spec = Spectrum.Spectrum(
        sw, sf, wrange=wrange, dw=dw, stype='line', sigma=res)
    spec.flux = spec.flux * fmax / spec.flux.max()

    return spec.wavelength, spec.flux
예제 #2
0
def getfitsspec(dw=0.1, res=0.1):
    wrange = None #[y.min(), y.max()]
    shdu = fits.open('thar.fits')
    ctype1=shdu[0].header['CTYPE1']
    crval1=shdu[0].header['CRVAL1']
    cdelt1=shdu[0].header['CDELT1']
    sf=shdu[0].data
    sw=crval1+cdelt1*np.arange(len(shdu[0].data))
    spec=Spectrum.Spectrum(sw, sf, wrange=wrange, dw=dw, stype='continuum', sigma=res)
    return spec
예제 #3
0
def readspectrum(specfile, stype='continuum', error=True, cols=None,
                 ftype=None):
    """Given a specfile, read in the spectra and return a spectrum object

       specfile--file containing the input spectra
       error--include an error column in the creation of the spectrum object
       cols--columns or column names for the wavelength, flux, and/or flux
             error
       ftype--type of file (ascii or fits)

    """

    # set the ftype for a fits file
    if ftype is None:
        if specfile[-5] == '.fits':
            ftype = 'fits'
        else:
            ftype = 'ascii'

    if ftype == 'ascii':
        if error:
            if cols is None:
                cols = (0, 1, 2)
            warr, farr, farr_err = np.loadtxt(
                specfile, usecols=cols, unpack=True)
            spectra = Spectrum.Spectrum(warr, farr, farr_err, stype=stype)
        else:
            if cols is None:
                cols = (0, 1)
            warr, farr = np.loadtxt(specfile, usecols=cols, unpack=True)
            spectra = Spectrum.Spectrum(warr, farr, stype=stype)
    elif ftype == 'fits':
        message = 'Support for FITS files not provided yet'
        raise SaltError(message)
    else:
        message = 'Support for %s files is not provided'
        raise SaltError(message)

    return spectra
예제 #4
0
def calfunc(obs_spectra, std_spectra, ext_spectra,
            airmass, exptime, error=False):
    """Given an observe spectra, calculate the calibration curve for the
       spectra.  All data is interpolated to the
       binning of the obs_spectra.  The calibrated spectra is then calculated
       from:
       C =  F_obs/ F_std / 10**(-0.4*A*E)/T/dW
       where F_obs is the observed flux from the source,  F_std  is the
       standard spectra, A is the airmass, E is the
       extinction in mags, T is the exposure time and dW is the bandpass

    Parameters
    -----------
    obs_spectra--spectrum of the observed star (counts/A)
    std_spectra--know spectrum of the standard star (ergs/s/cm2/A)
    ext_spectra--spectrum of the extinction curve (in mags)
    airmass--airmass of the observations
    exptime--exposure time of the observations
    function
    """

    # re-interpt the std_spectra over the same wavelength
    std_spectra.interp(obs_spectra.wavelength)

    # re-interp the ext_spetra over the sam ewavelength
    ext_spectra.interp(obs_spectra.wavelength)

    # create the calibration spectra
    cal_spectra = Spectrum.Spectrum(
        obs_spectra.wavelength,
        obs_spectra.flux.copy(),
        stype='continuum')

    # set up the bandpass
    bandpass = np.diff(obs_spectra.wavelength).mean()

    # correct for extinction
    cal_spectra.flux = obs_spectra.flux / \
        10 ** (-0.4 * airmass * ext_spectra.flux)

    # correct for the exposure time and calculation the calitivity curve
    cal_spectra.flux = cal_spectra.flux / exptime / bandpass / std_spectra.flux

    # correct the error calc
    if error:
        cal_spectra.var = obs_spectra.var * cal_spectra.flux / obs_spectra.flux

    return cal_spectra
def test_Linefit():

    hdu = pyfits.open(inimage)

    # create the data arra
    data = hdu[1].data

    # create the header information
    instrume = hdu[1].header['INSTRUME'].strip()
    grating = hdu[1].header['GRATING'].strip()
    grang = hdu[1].header['GR-ANGLE']
    arang = hdu[1].header['AR-ANGLE']
    filter = hdu[1].header['FILTER'].strip()
    slit = float(hdu[1].header['MASKID'])
    xbin, ybin = hdu[1].header['CCDSUM'].strip().split()

    # print instrume, grating, grang, arang, filter
    # print xbin, ybin
    # print len(data), len(data[0])

    # create the RSS Model
    rssmodel = RSSModel.RSSModel(grating_name=grating,
                                 gratang=grang,
                                 camang=arang,
                                 slit=slit,
                                 xbin=int(xbin),
                                 ybin=int(ybin))
    alpha = rssmodel.rss.gratang
    beta = rssmodel.rss.gratang - rssmodel.rss.camang

    sigma = 1e7 * rssmodel.rss.calc_resolelement(alpha, beta)

    # create artificial spectrum
    # create the spectrum
    stype = 'line'
    w, s = np.loadtxt(inspectra, usecols=(0, 1), unpack=True)
    spec = Spectrum(w,
                    s,
                    wrange=[4000, 5000],
                    dw=0.1,
                    stype='line',
                    sigma=sigma)
    spec.flux = spec.set_dispersion(sigma=sigma)

    sw_arr, sf_arr = spec.wavelength, spec.flux
예제 #6
0
def test_CreateImage():

    # read in the data
    hdu = fits.open(inimg)
    im_arr = hdu[1].data
    hdu.close()

    # set up the spectrum
    stype = 'line'
    w, s = np.loadtxt('Xe.dat', usecols=(0, 1), unpack=True)
    spec = Spectrum(w, s, wrange=[4000, 5000], dw=0.1, stype=stype)

    # set up the spectrograph
    dx = 2 * 0.015 * 8.169
    dy = 2 * 0.015 * 0.101
    # set up the spectrograph
    # rssmodel=RSSModel.RSSModel(grating_name='PG0900', gratang=13.625, camang=27.25, slit=1.0, xbin=2, ybin=2, xpos=dx, ypos=dy)
    rssmodel = RSSModel.RSSModel(
        grating_name='PG3000',
        gratang=43.625,
        camang=87.25,
        slit=2.0,
        xbin=2,
        ybin=2,
        xpos=dx,
        ypos=dy)

    rssmodel.set_camera(name='RSS', focallength=330.0)
    rss = rssmodel.rss

    # set up the outfile
    if os.path.isfile(outfile):
        os.remove(outfile)

    arr = im_arr.copy()
    arr = CreateImage(spec, rss)
    arr = arr * im_arr.max() / spec.flux.max()
    writeout(arr, outfile)
예제 #7
0
def plotarcspectra(arclist='Ne.txt',
                   grating='PG0900',
                   gratang=15.0,
                   camang=30.0,
                   slit=1.5,
                   xbin=2,
                   ybin=2):
    """Plot an Arc Line list for a given RSS set up 
      arclist--an arc line list in the format of 'wavelength flux' for arc lines
      grating--name of the grating
      gratang--angle of the grating
      camang--angle of the camera (articulation angle)
      slit--slit width in arcseconds
      xbin--xbinning
      ybin--ybinning

   """
    rss = RSSModel.RSSModel(grating_name=grating,
                            gratang=gratang,
                            camang=camang,
                            slit=slit,
                            xbin=xbin,
                            ybin=ybin)

    #print out some basic statistics
    print 1e7 * rss.calc_bluewavelength(), 1e7 * rss.calc_centralwavelength(
    ), 1e7 * rss.calc_redwavelength()
    R = rss.calc_resolution(rss.calc_centralwavelength(), rss.alpha(),
                            -rss.beta())
    res = 1e7 * rss.calc_resolelement(rss.alpha(), -rss.beta())
    print R, res

    #set up the detector
    ycen = rss.detector.get_ypixcenter()
    d_arr = rss.detector.make_detector()[ycen, :]  #creates 1-D detector map
    xarr = np.arange(len(d_arr))
    w = 1e7 * rss.get_wavelength(xarr)

    #set up the artificial spectrum
    sw, sf = pl.loadtxt(arclist, usecols=(0, 1), unpack=True)
    wrange = [1e7 * rss.calc_bluewavelength(), 1e7 * rss.calc_redwavelength()]
    spec = Spectrum.Spectrum(sw,
                             sf,
                             wrange=wrange,
                             dw=res / 10,
                             stype='line',
                             sigma=res)

    #interpolate it over the same range as the detector
    spec.interp(w)

    #plot it
    pl.figure()
    pl.plot(spec.wavelength, d_arr * ((spec.flux) / spec.flux.max()))

    print pl.gca().get_ylim()
    for i, f in zip(sw, sf):
        if i > spec.wavelength.min() and i < spec.wavelength.max():
            print i, f, sf.max(), spec.flux.max()
            #pl.text(i, f/sf.max(), i, fontsize='large', rotation=90)
            y = max(0.1, f / sf.max())
            pl.text(i, y, i, rotation=90)

    pl.show()
예제 #8
0
def test_Linefit():

    hdu = fits.open(inimage)

    # create the data arra
    data = hdu[1].data

    # create the header information
    grating = hdu[1].header['GRATING'].strip()
    grang = hdu[1].header['GR-ANGLE']
    arang = hdu[1].header['AR-ANGLE']
    slit = float(hdu[1].header['MASKID'])
    xbin, ybin = hdu[1].header['CCDSUM'].strip().split()

    # print instrume, grating, grang, arang, filter
    # print xbin, ybin
    # print len(data), len(data[0])

    # create the RSS Model
    rssmodel = RSSModel.RSSModel(grating_name=grating,
                                 gratang=grang,
                                 camang=arang,
                                 slit=slit,
                                 xbin=int(xbin),
                                 ybin=int(ybin))
    alpha = rssmodel.rss.gratang
    beta = rssmodel.rss.gratang - rssmodel.rss.camang

    sigma = 1e7 * rssmodel.rss.calc_resolelement(alpha, beta)

    # create the observed spectrum
    midpoint = int(0.5 * len(data))
    xarr = np.arange(len(data[0]), dtype='float')
    farr = data[midpoint, :]
    obs_spec = Spectrum(xarr, farr, stype='continuum')

    # create artificial spectrum
    stype = 'line'
    w, s = np.loadtxt(inspectra, usecols=(0, 1), unpack=True)
    cal_spec = Spectrum(w,
                        s,
                        wrange=[4000, 5000],
                        dw=0.1,
                        stype=stype,
                        sigma=sigma)
    cal_spec.flux = cal_spec.set_dispersion(sigma=sigma)
    cal_spec.flux = cal_spec.flux * obs_spec.flux.max() / cal_spec.flux.max(
    ) + 1

    lf = LF.LineFit(obs_spec, cal_spec, function='legendre', order=3)
    lf.set_coef(
        [4.23180070e+03, 2.45517852e-01, -4.46931562e-06, -2.22067766e-10])
    print(lf(2000))
    print(lf.obs_spec.get_flux(2000), lf.flux(2000))
    print('chisq ', (lf.errfit(lf.coef, xarr, farr)**2).sum() / 1e7)
    lf.set_coef(
        [4.23280070e+03, 2.45517852e-01, -4.46931562e-06, -2.22067766e-10])
    print(lf(2000))
    print(lf.obs_spec.get_flux(2000), lf.flux(2000))
    print('chisq ', (lf.errfit(lf.coef, xarr, farr)**2).sum() / 1e7)
    # print lf.lfit(xarr)
    # print lf.coef
    # print lf(2000)
    # print lf.results

    pl.figure()

    pl.plot(lf(lf.obs_spec.wavelength), lf.obs_spec.get_flux(xarr))
    pl.plot(lf.cal_spec.wavelength, lf.cal_spec.flux)
    pl.show()
예제 #9
0
R = rss.calc_resolution(rss.calc_centralwavelength(), rss.alpha(), -rss.beta())
res = 1e7 * rss.calc_resolelement(rss.alpha(), -rss.beta())
print R, res

#set up the detector
ycen = rss.detector.get_ypixcenter()
d_arr = rss.detector.make_detector()[ycen, :]
xarr = np.arange(len(d_arr))
w = 1e7 * rss.get_wavelength(xarr)

#set up the artificial spectrum
sw, sf = pl.loadtxt('Ar.txt', usecols=(0, 1), unpack=True)
wrange = [1e7 * rss.calc_bluewavelength(), 1e7 * rss.calc_redwavelength()]
spec = Spectrum.Spectrum(sw,
                         sf,
                         wrange=wrange,
                         dw=res / 10,
                         stype='line',
                         sigma=res)

#interpolate it over the same range as the detector
spec.interp(w)

#plot it
pl.figure()
pl.plot(spec.wavelength, d_arr * ((spec.flux) / spec.flux.max()))
pl.plot(spec.wavelength, d_arr * 0.1)
yy = np.median(data[1000:1050, 3:3173], 0)
pl.plot(spec.wavelength, yy / yy.max())

ymod = d_arr * ((spec.flux) / spec.flux.max())
ydata = yy / yy.max()
예제 #10
0
def extract_spectra(hdu, yc, dy, outfile, minsize=5, thresh=3, grow=0, smooth=False, maskzeros=False, 
                    convert=True,  cleanspectra=True, calfile=None, clobber=True, specformat='ascii'):
    """From an image, extract a spectra.   

    """
    data=hdu[1].data

    #replace the zeros with the average from the frame
    if maskzeros:
       mean,std=iterstat(data[data>0])
       #rdata=mean  np.random.normal(mean, std, size=data.shape)
       data[data<=0]=mean #rdata[data<=0]

    y1=yc-dy
    y2=yc+dy

    #sy1=y2-2*dy
    #sy2=y2+2*dy

    #sdata = 1.0 * data 
    #y,x = np.indices(sdata.shape)
    #for i in range(sdata.shape[1]):
    #   mask=(hdu[3].data[:,i]==0)
    #   mask[sy1:sy2] = 0
    #   if mask.sum()>0:
    #     sdata[y1:y2,i] = np.interp(y[y1:y2,i], y[:,i][mask], data[:,i][mask])  
    #hdu[1].data = sdata
    #sk_list=extract(hdu, method='normal', section=[(y1,y2)], minsize=minsize, thresh=thresh, convert=True)
    #ap_list[0].ldata=ap_list[0].ldata-sk_list[0].ldata
    #ap_list[0].ldata=ap_list[0].ldata-float(y2-y1)/(sy2-sy1)*sk_list[0].ldata

    ap_list=extract(hdu, method='normal', section=[(y1,y2)], minsize=minsize, thresh=thresh, convert=convert)
    sy1a=y2
    sy2a=sy1a+2.0*dy
    ska_list=extract(hdu, method='normal', section=[(sy1a,sy2a)], minsize=minsize, thresh=thresh, convert=convert)
    sy2b=y1-dy
    sy1b=sy2b-2.0*dy
    skb_list=extract(hdu, method='normal', section=[(sy1b,sy2b)], minsize=minsize, thresh=thresh, convert=convert)
    print sy1b, sy2b

    sdata = 0.5*(ska_list[0].ldata/(sy2a-sy1a) + skb_list[0].ldata/(sy2b-sy1b))
    #sdata = ska_list[0].ldata/(sy2a-sy1a)
    #sdata = skb_list[0].ldata/(sy2b-sy1b)
    raw = 1.0 * ap_list[0].ldata
    
    ap_list[0].ldata=ap_list[0].ldata-float(y2-y1) * sdata
 
    print ap_list[0].wave[10], ap_list[0].ldata[10], ap_list[0].lvar[10]
    flux_spec=Spectrum.Spectrum(ap_list[0].wave, ap_list[0].ldata, abs(ap_list[0].lvar)**0.5, stype='continuum')
    print flux_spec.wavelength[10], flux_spec.flux[10], flux_spec.var[10]

    if cleanspectra:
       clean_spectra(ap_list[0], grow=grow)

    if calfile:
           cal_spectra=st.readspectrum(calfile, error=False, ftype='ascii')
           airmass=hdu[0].header['AIRMASS']
           exptime=hdu[0].header['EXPTIME']
           extfile=iraf.osfn("pysalt$data/site/suth_extinct.dat")
           ext_spectra=st.readspectrum(extfile, error=False, ftype='ascii')

           flux_spec=Spectrum.Spectrum(ap_list[0].wave, ap_list[0].ldata, abs(ap_list[0].lvar)**0.5, stype='continuum')
           print flux_spec.flux[10], flux_spec.var[10]
           flux_spec=calfunc(flux_spec, cal_spectra, ext_spectra, airmass, exptime, True)
           print flux_spec.flux[10], flux_spec.var[10]
    else:
        flux_spec = Spectrum.Spectrum(ap_list[0].wave, ap_list[0].ldata, abs(ap_list[0].lvar)**0.5, stype='continuum')
    
    if specformat == 'ascii':
        write_ascii(outfile, flux_spec, clobber=clobber)
    elif specformat == 'lcogt':
        write_lcogt(outfile, flux_spec, hdu, sky=float(y2-y1) * sdata, raw = raw, clobber=clobber)
예제 #11
0
def arclisfromhdr(hdr, slitwidth=1.50, xbin=2, ybin=2, lamp='Ar.txt'):

    # ** some numbers below hardwired for 2x2 binning (~3170 pix) **
    grname = hdr['grating']
    camang = hdr['camang']
    gratang = hdr['gr-angle']

    rss = RSSModel.RSSModel(grating_name=grname,
                            gratang=gratang,
                            camang=camang,
                            slit=slitwidth,
                            xbin=xbin,
                            ybin=ybin)

    # set up the detector
    ycen = rss.detector.get_ypixcenter()
    d_arr = rss.detector.make_detector()[ycen, :]
    xarr = np.arange(len(d_arr))
    w = 1e7 * rss.get_wavelength(xarr)

    #set up the artificial spectrum
    res = 1e7 * rss.calc_resolelement(rss.alpha(), -rss.beta())

    sw, sf = pl.loadtxt(lamp, usecols=(0, 1), unpack=True)
    wrange = [1e7 * rss.calc_bluewavelength(), 1e7 * rss.calc_redwavelength()]
    spec = Spectrum.Spectrum(sw,
                             sf,
                             wrange=wrange,
                             dw=res / 10,
                             stype='line',
                             sigma=res)

    #interpolate it over the same range as the detector
    spec.interp(w)

    if (0):
        #plot it
        pl.figure()
        pl.plot(spec.wavelength, d_arr * ((spec.flux) / spec.flux.max()))
        pl.plot(spec.wavelength, d_arr * 0.1)
        #yy=np.median(data[1000:1050,3:3173],0)
        #pl.plot(spec.wavelength,yy/yy.max())

        ymod = d_arr * ((spec.flux) / spec.flux.max())
        ydata = yy / yy.max()

        off, rval = xcor2(ydata, ymod, 100.)

        yyy = np.roll(yy, -int(off)) / yy.max()
        pl.plot(spec.wavelength, yyy)
        pl.show()
        stop()

    # We need to return
    # - a matched list of wavelength(of each pixel),flux for the arc
    # - a list of the arc lines
    modarclam = spec.wavelength
    modarcspec = d_arr * ((spec.flux) / spec.flux.max())

    # extract pixel positions for lines of wavelength sw:
    xpix = np.arange(np.size(modarclam))
    ixp = np.interp(sw, modarclam, xpix, left=0, right=0)

    ok = np.reshape(((ixp > 0.) & (ixp < 3170)).nonzero(), -1)

    np.savetxt('_tmparc.lis', np.transpose((ixp[ok], sw[ok], sw[ok])))

    return modarclam, modarcspec