Пример #1
0
def fillgaps(profile):
   """Fill in the gaps"""
   hdu = pyfits.open(profile)

   #get the binning
   xbin, ybin = saltkey.ccdbin( hdu[0], '')

   #fill in the second gap
   x1 = 2044/xbin
   x2 = 2152/xbin
   d1=np.min(hdu[1].data[:,x1-10:x1], axis=1)
   d2=np.min(hdu[1].data[:,x2:x2+10], axis=1)
   d1 = 0.5 * (d1+d2)
   hdu[1].data[:,x1:x2] = d1.reshape(len(d1),1)


   #fill in the second gap
   x1 = 4096/xbin
   x2 = 4308/xbin
   d1=np.min(hdu[1].data[:,x1-10:x1], axis=1)
   d2=np.min(hdu[1].data[:,x2:x2+10], axis=1)
   d1 = 0.5 * (d1+d2)
   hdu[1].data[:,x1:x2] = d1.reshape(len(d1),1)
   
   if os.path.isfile(profile): os.remove(profile)
   hdu.writeto(profile)
Пример #2
0
def fillgaps(profile):
   """Fill in the gaps"""
   hdu = pyfits.open(profile)

   #get the binning
   xbin, ybin = saltkey.ccdbin( hdu[0], '')

   #fill in the second gap
   x1 = 2044/xbin
   x2 = 2152/xbin
   d1=np.min(hdu[1].data[:,x1-10:x1], axis=1)
   d2=np.min(hdu[1].data[:,x2:x2+10], axis=1)
   d1 = 0.5 * (d1+d2)
   hdu[1].data[:,x1:x2] = d1.reshape(len(d1),1)


   #fill in the second gap
   x1 = 4096/xbin
   x2 = 4308/xbin
   d1=np.min(hdu[1].data[:,x1-10:x1], axis=1)
   d2=np.min(hdu[1].data[:,x2:x2+10], axis=1)
   d1 = 0.5 * (d1+d2)
   hdu[1].data[:,x1:x2] = d1.reshape(len(d1),1)
   
   if os.path.isfile(profile): os.remove(profile)
   hdu.writeto(profile)
Пример #3
0
def calc_resolution(hdu):
    """Calculate the resolution for a setup"""
    instrume=saltkey.get('INSTRUME', hdu[0]).strip()
    grating=saltkey.get('GRATING', hdu[0]).strip()
    grang=saltkey.get('GR-ANGLE', hdu[0])
    grasteps=saltkey.get('GRTILT', hdu[0])
    arang=saltkey.get('AR-ANGLE', hdu[0])
    arsteps=saltkey.get('CAMANG', hdu[0])
    rssfilter=saltkey.get('FILTER', hdu[0])
    specmode=saltkey.get('OBSMODE', hdu[0])
    masktype=saltkey.get('MASKTYP', hdu[0]).strip().upper()
    slitname=saltkey.get('MASKID', hdu[0])
    xbin, ybin = saltkey.ccdbin( hdu[0], '')
    slit=st.getslitsize(slitname)
    
    #create RSS Model
    rss=RSSModel.RSSModel(grating_name=grating.strip(), gratang=grang, \
                          camang=arang,slit=slit, xbin=xbin, ybin=ybin, \
                          )
    res=1e7*rss.calc_resolelement(rss.alpha(), -rss.beta())
    return res 
Пример #4
0
def calc_resolution(hdu):
    """Calculate the resolution for a setup"""
    instrume=saltkey.get('INSTRUME', hdu[0]).strip()
    grating=saltkey.get('GRATING', hdu[0]).strip()
    grang=saltkey.get('GR-ANGLE', hdu[0])
    grasteps=saltkey.get('GRTILT', hdu[0])
    arang=saltkey.get('AR-ANGLE', hdu[0])
    arsteps=saltkey.get('CAMANG', hdu[0])
    rssfilter=saltkey.get('FILTER', hdu[0])
    specmode=saltkey.get('OBSMODE', hdu[0])
    masktype=saltkey.get('MASKTYP', hdu[0]).strip().upper()
    slitname=saltkey.get('MASKID', hdu[0])
    xbin, ybin = saltkey.ccdbin( hdu[0], '')
    slit=st.getslitsize(slitname)
    
    #create RSS Model
    rss=RSSModel.RSSModel(grating_name=grating.strip(), gratang=grang, \
                          camang=arang,slit=slit, xbin=xbin, ybin=ybin, \
                          )
    res=1e7*rss.calc_resolelement(rss.alpha(), -rss.beta())
    return res 
Пример #5
0
def specidentify(images, linelist, outfile, guesstype='rss', guessfile='',
                 automethod='Matchlines', function='poly', order=3, rstep=100,
                 rstart='middlerow', mdiff=5, thresh=3, niter=5, smooth=0,
                 subback=0, inter=True, startext=0,  clobber=False, 
                 textcolor='black', logfile='salt.log', verbose=True):

    with logging(logfile, debug) as log:

        # set up the variables
        infiles = []
        outfiles = []

        # Check the input images
        infiles = saltio.argunpack('Input', images)

        # create list of output files
        outfiles = saltio.argunpack('Output', outfile)

        # open the line lists
        slines, sfluxes = st.readlinelist(linelist)

        # Identify the lines in each file
        for img, ofile in zip(infiles, outfiles):

            # open the image
            hdu = saltio.openfits(img)

            # get the basic information about the spectrograph
            dateobs = saltkey.get('DATE-OBS', hdu[0])
            try:
                utctime = saltkey.get('UTC-OBS', hdu[0])
            except SaltError:
                utctime = saltkey.get('TIME-OBS', hdu[0])

            instrume = saltkey.get('INSTRUME', hdu[0]).strip()
            grating = saltkey.get('GRATING', hdu[0]).strip()
            grang = saltkey.get('GR-ANGLE', hdu[0])
            grasteps = saltkey.get('GRTILT', hdu[0])
            arang = saltkey.get('AR-ANGLE', hdu[0])
            arsteps = saltkey.get('CAMANG', hdu[0])
            rssfilter = saltkey.get('FILTER', hdu[0])
            specmode = saltkey.get('OBSMODE', hdu[0])
            masktype = saltkey.get('MASKTYP', hdu[0]).strip().upper()
            slitname = saltkey.get('MASKID', hdu[0])
            xbin, ybin = saltkey.ccdbin(hdu[0], img)

            for i in range(startext, len(hdu)):
                if hdu[i].name == 'SCI':
                    log.message('Proccessing extension %i in  %s' % (i, img))
                    # things that will change for each slit

                    if masktype == 'LONGSLIT':
                        slit = st.getslitsize(slitname)
                        xpos = -0.2666
                        ypos = 0.0117
                        objid = None
                    elif masktype == 'MOS':
                        slit = 1.5
                        #slit=saltkey.get('SLIT', hdu[i])

                        # set up the x and y positions
                        miny = hdu[i].header['MINY']
                        maxy = hdu[i].header['MAXY']
                        ras = hdu[i].header['SLIT_RA']
                        des = hdu[i].header['SLIT_DEC']
                        objid = hdu[i].header['SLITNAME']

                        # TODO: Check the perfomance of masks at different PA
                        rac = hdu[0].header['MASK_RA']
                        dec = hdu[0].header['MASK_DEC']
                        pac = hdu[0].header['PA']

                        # these are hard wired at the moment
                        xpixscale = 0.1267 * xbin
                        ypixscale = 0.1267 * ybin
                        cx = int(3162 / xbin)
                        cy = int(2050 / ybin)

                        x, y = mt.convert_fromsky(ras, des, rac, dec, xpixscale=xpixscale, ypixscale=ypixscale,
                                                  position_angle=-pac, ccd_cx=cx, ccd_cy=cy)
                        xpos = 0.015 * 2 * (cx - x[0])
                        ypos = 0.0117
                    else:
                        msg = '%s is not a currently supported masktype' % masktype
                        raise SALTSpecError(msg)

                    if instrume not in ['PFIS', 'RSS']:
                        msg = '%s is not a currently supported instrument' % instrume
                        raise SALTSpecError(msg)

                    # create RSS Model
                    rss = RSSModel.RSSModel(grating_name=grating.strip(), gratang=grang,
                                            camang=arang, slit=slit, xbin=xbin, ybin=ybin,
                                            xpos=xpos, ypos=ypos)
                    res = 1e7 * rss.calc_resolelement(rss.alpha(), -rss.beta())
                    dres = res / 10.0
                    wcen = 1e7 * rss.calc_centralwavelength()
                    R = rss.calc_resolution(
                        wcen / 1e7, rss.alpha(), -rss.beta())
                    logmsg = '\nGrating\tGR-ANGLE\tAR-ANGLE\tSlit\tWCEN\tR\n'
                    logmsg += '%s\t%8.3f\t%8.3f\t%4.2f\t%6.2f\t%4f\n' % (
                        grating, grang, arang, slit, wcen, R)
                    if log:
                        log.message(logmsg, with_header=False)

                    # set up the data for the source
                    try:
                        data = hdu[i].data
                    except Exception as e:
                        message = 'Unable to read in data array in %s because %s' % (
                            img, e)
                        raise SALTSpecError(message)

                    # set up the center row
                    if rstart == 'middlerow':
                        ystart = int(0.5 * len(data))
                    else:
                        ystart = int(rstart)

                    rss.gamma = 0.0
                    if masktype == 'MOS':
                        rss.gamma = 180.0 / math.pi * math.atan((y * rss.detector.pix_size * rss.detector.ybin
                                                                 - 0.5 * rss.detector.find_height()) / rss.camera.focallength)

                    # set up the xarr array based on the image
                    xarr = np.arange(len(data[ystart]), dtype='int64')

                    # get the guess for the wavelength solution
                    if guesstype == 'rss':
                        # set up the rss model
                        ws = st.useRSSModel(
                            xarr, rss, function=function, order=order, gamma=rss.gamma)
                    elif guesstype == 'file':
                        soldict = {}
                        soldict = readsolascii(guessfile, soldict)
                        timeobs = enterdatetime('%s %s' % (dateobs, utctime))
                        exptime = saltkey.get('EXPTIME', hdu[0])
                        filtername = saltkey.get('FILTER', hdu[0]).strip()
                        try:
                            slitid = saltkey.get('SLITNAME', hdu[i])
                        except:
                            slitid = None

                        function, order, coef = findlinesol(
                            soldict, ystart, True, timeobs, exptime, instrume, grating, grang, arang, filtername, slitid, xarr=xarr)
                        ws = WavelengthSolution.WavelengthSolution(
                            xarr, xarr, function=function, order=order)
                        ws.set_coef(coef)
                    else:
                        raise SALTSpecError(
                            'This guesstype is not currently supported')

                    # identify the spectral lines
                    ImageSolution = identify(data, slines, sfluxes, xarr, ystart, ws=ws, function=function,
                                             order=order, rstep=rstep,  mdiff=mdiff, thresh=thresh, niter=niter,
                                             method=automethod, res=res, dres=dres, smooth=smooth, inter=inter, filename=img,
                                             subback=0, textcolor=textcolor, log=log, verbose=verbose)

                    if outfile and len(ImageSolution):
                        writeIS(ImageSolution, outfile, dateobs=dateobs, utctime=utctime, instrume=instrume,
                                grating=grating, grang=grang, grasteps=grasteps, arsteps=arsteps,
                                arang=arang, rfilter=rssfilter, slit=slit, xbin=xbin,
                                ybin=ybin, objid=objid,
                                filename=img, log=log, verbose=verbose)
Пример #6
0
def wavemap(
    hdu,
    soldict,
    caltype="line",
    function="poly",
    order=3,
    blank=0,
    nearest=False,
    array_only=False,
    clobber=True,
    log=None,
    verbose=True,
):
    """Read in an image and a set of wavlength solutions.  Calculate the best
       wavelength solution for a given dataset and then apply that data set to the
       image

     return
    """

    # set up the time of the observation
    dateobs = saltkey.get("DATE-OBS", hdu[0])
    utctime = saltkey.get("TIME-OBS", hdu[0])
    exptime = saltkey.get("EXPTIME", hdu[0])
    instrume = saltkey.get("INSTRUME", hdu[0]).strip()
    grating = saltkey.get("GRATING", hdu[0]).strip()
    if caltype == "line":
        grang = saltkey.get("GRTILT", hdu[0])
        arang = saltkey.get("CAMANG", hdu[0])
    else:
        grang = saltkey.get("GR-ANGLE", hdu[0])
        arang = saltkey.get("AR-ANGLE", hdu[0])
    filtername = saltkey.get("FILTER", hdu[0]).strip()
    slitname = saltkey.get("MASKID", hdu[0])
    slit = st.getslitsize(slitname)
    xbin, ybin = saltkey.ccdbin(hdu[0])

    timeobs = sr.enterdatetime("%s %s" % (dateobs, utctime))

    # check to see if there is more than one solution
    if caltype == "line":
        if len(soldict) == 1:
            sol = soldict.keys()[0]
            slitid = None
            if not sr.matchobservations(soldict[sol], instrume, grating, grang, arang, filtername, slitid):
                msg = "Observations do not match setup for transformation but using the solution anyway"
                if log:
                    log.warning(msg)

    for i in range(1, len(hdu)):
        if hdu[i].name == "SCI":
            if log:
                log.message("Correcting extension %i" % i)
            istart = int(0.5 * len(hdu[i].data))

            # open up the data
            # set up the xarr and initial wavlength solution
            xarr = np.arange(len(hdu[i].data[istart]), dtype="int64")

            # get the slitid
            try:
                slitid = saltkey.get("SLITNAME", hdu[i])
            except:
                slitid = None

            # check to see if wavext is already there and if so, then check update
            # that for the transformation from xshift to wavelength
            if saltkey.found("WAVEXT", hdu[i]):
                w_ext = saltkey.get("WAVEXT", hdu[i]) - 1
                wavemap = hdu[w_ext].data
                function, order, coef = sr.findlinesol(
                    soldict,
                    istart,
                    nearest,
                    timeobs,
                    exptime,
                    instrume,
                    grating,
                    grang,
                    arang,
                    filtername,
                    slitid,
                    xarr,
                )
                ws = WavelengthSolution.WavelengthSolution(xarr, xarr, function=function, order=order)
                ws.set_coef(coef)
                for j in range(len(hdu[i].data)):
                    wavemap[j, :] = ws.value(wavemap[j, :])
                if array_only:
                    return wavemap
                hdu[w_ext].data = wavemap
                continue

            # set up a wavelength solution -- still in here for testing MOS data
            try:
                w_arr = sr.findsol(
                    xarr,
                    soldict,
                    istart,
                    caltype,
                    nearest,
                    timeobs,
                    exptime,
                    instrume,
                    grating,
                    grang,
                    arang,
                    filtername,
                    slit,
                    xbin,
                    ybin,
                    slitid,
                    function,
                    order,
                )
            except SALTSpecError as e:
                if slitid:
                    msg = "SLITID %s: %s" % (slitid, e)
                    if log:
                        log.warning(msg)
                    continue
                else:
                    raise SALTSpecError(e)

            if w_arr is None:
                w_arr = sr.findsol(
                    xarr,
                    soldict,
                    istart,
                    "rss",
                    nearest,
                    timeobs,
                    exptime,
                    instrume,
                    grating,
                    grang,
                    arang,
                    filtername,
                    slit,
                    xbin,
                    ybin,
                    slitid,
                    function,
                    order,
                )

            # for each line in the data, determine the wavelength solution
            # for a given line in the image
            wavemap = np.zeros_like(hdu[i].data)
            for j in range(len(hdu[i].data)):
                # find the wavelength solution for the data
                w_arr = sr.findsol(
                    xarr,
                    soldict,
                    j,
                    caltype,
                    nearest,
                    timeobs,
                    exptime,
                    instrume,
                    grating,
                    grang,
                    arang,
                    filtername,
                    slit,
                    xbin,
                    ybin,
                    slitid,
                    function,
                    order,
                )
                if w_arr is not None:
                    wavemap[j, :] = w_arr
            if array_only:
                return wavemap

            # write out the oimg
            hduwav = fits.ImageHDU(data=wavemap, header=hdu[i].header, name="WAV")
            hdu.append(hduwav)
            saltkey.new("WAVEXT", len(hdu) - 1, "Extension for Wavelength Map", hdu[i])

    return hdu
Пример #7
0
def specarcstraighten(images, outfile, function='poly', order=3, rstep=1,
                      rstart='middlerow', nrows=1, 
                      y1=None, y2=None, sigma=5, sections=3, niter=5,
                      startext=0, clobber=False, logfile='salt.log', verbose=True):

    with logging(logfile, debug) as log:

        # Check the input images
        infiles = saltio.argunpack('Input', images)

        # create list of output files
        outfiles = saltio.argunpack('Output', outfile)

        # Identify the lines in each file
        for img, ofile in zip(infiles, outfiles):

            # open the image
            hdu = saltio.openfits(img)

            # get the basic information about the spectrograph
            dateobs = saltkey.get('DATE-OBS', hdu[0])
            try:
                utctime = saltkey.get('UTC-OBS', hdu[0])
            except SaltError:
                utctime = saltkey.get('TIME-OBS', hdu[0])

            instrume = saltkey.get('INSTRUME', hdu[0]).strip()
            grating = saltkey.get('GRATING', hdu[0]).strip()
            grang = saltkey.get('GR-ANGLE', hdu[0])
            grasteps = saltkey.get('GRTILT', hdu[0])
            arang = saltkey.get('AR-ANGLE', hdu[0])
            arsteps = saltkey.get('CAMANG', hdu[0])
            rssfilter = saltkey.get('FILTER', hdu[0])
            specmode = saltkey.get('OBSMODE', hdu[0])
            masktype = saltkey.get('MASKTYP', hdu[0]).strip().upper()
            slitname = saltkey.get('MASKID', hdu[0])
            xbin, ybin = saltkey.ccdbin(hdu[0], img)

            for i in range(startext, len(hdu)):
                if hdu[i].name == 'SCI':
                    log.message('Proccessing extension %i in  %s' % (i, img))
                    # things that will change for each slit

                    if masktype == 'LONGSLIT':
                        slit = st.getslitsize(slitname)
                        objid = None
                    #elif masktype == 'MOS':
                        #slit = 1.5
                        # slit=saltkey.get('SLIT', hdu[i])

                        # set up the x and y positions
                        #miny = hdu[i].header['MINY']
                        #maxy = hdu[i].header['MAXY']
                        #ras = hdu[i].header['SLIT_RA']
                        #des = hdu[i].header['SLIT_DEC']
                        #objid = hdu[i].header['SLITNAME']

                        # Check the perfomance of masks at different PA
                        #rac = hdu[0].header['MASK_RA']
                        #dec = hdu[0].header['MASK_DEC']
                        #pac = hdu[0].header['PA']

                    else:
                        msg = '%s is not a currently supported masktype' % masktype
                        raise SALTSpecError(msg)

                    if instrume not in ['PFIS', 'RSS']:
                        msg = '%s is not a currently supported instrument' % instrume
                        raise SALTSpecError(msg)

                    # set up the data for the source
                    try:
                        data = hdu[i].data
                    except Exception as e:
                        message = 'Unable to read in data array in %s because %s' % (
                            img, e)
                        raise SALTSpecError(message)

                    # set up the center row
                    if rstart == 'middlerow':
                        ystart = int(0.5 * len(data))
                    else:
                        ystart = rstart


                    # set up the xarr array based on the image
                    xarr = np.arange(len(data[ystart]), dtype='int64')

                    # calculate the transformation
                    ImageSolution = arcstraight(data, xarr, ystart, function=function, order=order, 
                                                rstep=rstep, y1=y1, y2=y2, sigma=sigma, sections=sections,
                                                niter=niter, log=log, verbose=verbose)

                    if outfile and len(ImageSolution):
                        writeIS(ImageSolution, outfile, dateobs=dateobs, utctime=utctime, instrume=instrume,
                                grating=grating, grang=grang, grasteps=grasteps, arsteps=arsteps,
                                arang=arang, rfilter=rssfilter, slit=slit, xbin=xbin,
                                ybin=ybin, objid=objid,
                                filename=img, log=log, verbose=verbose)
Пример #8
0
def make_mosaic(struct,
                gap,
                xshift,
                yshift,
                rotation,
                interp_type='linear',
                boundary='constant',
                constant=0,
                geotran=True,
                fill=False,
                cleanup=True,
                log=None,
                verbose=False):
    """Given a SALT image struct, combine each of the individual amplifiers and
        apply the geometric CCD transformations to the image
    """

    # get the name of the file
    infile = saltkey.getimagename(struct[0], base=True)
    outpath = './'

    # identify instrument
    instrume, keyprep, keygain, keybias, keyxtalk, keyslot = \
        saltkey.instrumid(struct)

    # how many amplifiers?
    nsciext = saltkey.get('NSCIEXT', struct[0])
    nextend = saltkey.get('NEXTEND', struct[0])
    nccds = saltkey.get('NCCDS', struct[0])
    amplifiers = nccds * 2

    if nextend > nsciext:
        varframe = True
    else:
        varframe = False

    # CCD geometry coefficients
    if (instrume == 'RSS' or instrume == 'PFIS'):
        xsh = [0., xshift[0], 0., xshift[1]]
        ysh = [0., yshift[0], 0., yshift[1]]
        rot = [0., rotation[0], 0., rotation[1]]
    elif instrume == 'SALTICAM':
        xsh = [0., xshift[0], 0.]
        ysh = [0., yshift[0], 0.]
        rot = [0., rotation[0], 0]

    # how many extensions?
    nextend = saltkey.get('NEXTEND', struct[0])

    # CCD on-chip binning
    xbin, ybin = saltkey.ccdbin(struct[0])

    # create temporary primary extension
    outstruct = []
    outstruct.append(struct[0])
    # define temporary FITS file store tiled CCDs

    tilefile = saltio.tmpfile(outpath)
    tilefile += 'tile.fits'
    if varframe:
        tilehdu = [None] * (3 * int(nsciext / 2) + 1)
    else:
        tilehdu = [None] * int(nsciext / 2 + 1)
    tilehdu[0] = fits.PrimaryHDU()
    #tilehdu[0].header = struct[0].header

    if log:
        log.message('', with_stdout=verbose)

    # iterate over amplifiers, stich them to produce file of CCD images
    for i in range(int(nsciext / 2)):
        hdu = i * 2 + 1
        # amplifier = hdu%amplifiers
        # if (amplifier == 0): amplifier = amplifiers

        # read DATASEC keywords
        datasec1 = saltkey.get('DATASEC', struct[hdu])
        datasec2 = saltkey.get('DATASEC', struct[hdu + 1])
        xdsec1, ydsec1 = saltstring.secsplit(datasec1)
        xdsec2, ydsec2 = saltstring.secsplit(datasec2)

        # read images
        imdata1 = saltio.readimage(struct, hdu)
        imdata2 = saltio.readimage(struct, hdu + 1)

        # tile 2n amplifiers to yield n CCD images
        outdata = numpy.zeros(
            (int(ydsec1[1] + abs(ysh[i + 1] / ybin)),
             int(xdsec1[1] + xdsec2[1] + abs(xsh[i + 1] / xbin))),
            numpy.float32)

        # set up the variance frame
        if varframe:
            vardata = outdata.copy()
            vdata1 = saltio.readimage(struct, struct[hdu].header['VAREXT'])
            vdata2 = saltio.readimage(struct, struct[hdu + 1].header['VAREXT'])

            bpmdata = outdata.copy()
            bdata1 = saltio.readimage(struct, struct[hdu].header['BPMEXT'])
            bdata2 = saltio.readimage(struct, struct[hdu + 1].header['BPMEXT'])

        x1 = xdsec1[0] - 1
        if x1 != 0:
            msg = 'The data in %s have not been trimmed prior to mosaicking.' \
                  % infile
            log.error(msg)
        if xsh[i + 1] < 0:
            x1 += int(abs(xsh[i + 1] / xbin))
        x2 = x1 + xdsec1[1]
        y1 = ydsec1[0] - 1
        if ysh[i + 1] < 0:
            y1 += int(abs(ysh[i + 1] / ybin))
        y2 = y1 + ydsec1[1]
        outdata[y1:y2, x1:x2] =\
            imdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        if varframe:
            vardata[y1:y2, x1:x2] =\
                vdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]
            bpmdata[y1:y2, x1:x2] =\
                bdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        x1 = x2
        x2 = x1 + xdsec2[1]
        y1 = ydsec2[0] - 1
        if ysh[i + 1] < 0:
            y1 += abs(ysh[i + 1] / ybin)
        y2 = y1 + ydsec2[1]
        outdata[y1:y2, x1:x2] =\
            imdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        if varframe:
            vardata[y1:y2, x1:x2] =\
                vdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]
            bpmdata[y1:y2, x1:x2] =\
                bdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        # size of new image
        naxis1 = str(xdsec1[1] + xdsec2[1])
        naxis2 = str(ydsec1[1])

        # add image and keywords to HDU list
        tilehdu[i + 1] = fits.ImageHDU(outdata)
        tilehdu[i + 1].header = struct[hdu].header
        #tilehdu[
        #    i + 1].header['DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

        if varframe:
            vext = i + 1 + int(nsciext / 2.)
            tilehdu[vext] = fits.ImageHDU(vardata)
            #tilehdu[vext].header = struct[struct[hdu].header['VAREXT']].header
            #tilehdu[vext].header[
            #    'DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

            bext = i + 1 + 2 * int(nsciext / 2.)
            tilehdu[bext] = fits.ImageHDU(bpmdata)
            #tilehdu[bext].header = struct[struct[hdu].header['BPMEXT']].header
            #tilehdu[bext].header[
            #    'DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

        # image tile log message #1
        if log:
            message = os.path.basename(infile) + '[' + str(hdu) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + '] --> '
            message += os.path.basename(tilefile) + '[' + str(i + 1) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + ']'
            log.message(message, with_stdout=verbose, with_header=False)
            message = os.path.basename(infile) + '[' + str(hdu + 1) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + '] --> '
            message += os.path.basename(tilefile) + '[' + str(i + 1) + ']['
            message += str(xdsec1[1] + 1) + ':' + \
                str(xdsec1[1] + xdsec2[1]) + ','
            message += str(ydsec2[0]) + ':' + str(ydsec2[1]) + ']'
            log.message(message, with_stdout=verbose, with_header=False)

    # write temporary file of tiled CCDs
    hdulist = fits.HDUList(tilehdu)
    hdulist.writeto(tilefile)

    # iterate over CCDs, transform and rotate images
    yrot = [None] * 4
    xrot = [None] * 4

    tranfile = [' ']
    tranhdu = [0]
    if varframe:
        tranfile = [''] * (3 * int(nsciext / 2) + 1)
        tranhdu = [0] * (3 * int(nsciext / 2) + 1)
    else:
        tranfile = [''] * int(nsciext / 2 + 1)
        tranhdu = [0] * int(nsciext / 2 + 1)

    # this is hardwired for SALT where the second CCD is considered the
    # fiducial
    for hdu in range(1, int(nsciext / 2 + 1)):
        tranfile[hdu] = saltio.tmpfile(outpath)
        tranfile[hdu] += 'tran.fits'
        if varframe:
            tranfile[hdu + nccds] = saltio.tmpfile(outpath) + 'tran.fits'
            tranfile[hdu + 2 * nccds] = saltio.tmpfile(outpath) + 'tran.fits'

        ccd = hdu % nccds
        if (ccd == 0):
            ccd = nccds

        # correct rotation for CCD binning
        yrot[ccd] = rot[ccd] * ybin / xbin
        xrot[ccd] = rot[ccd] * xbin / ybin
        dxshift = xbin * int(float(int(gap) / xbin) + 0.5) - gap

        # transformation using geotran IRAF task
        # if (ccd == 1):
        if (ccd != 2):

            if geotran:
                message = '\nSALTMOSAIC -- geotran ' + tilefile + \
                    '[' + str(ccd) + '] ' + tranfile[hdu]
                message += ' \"\" \"\" xshift=' + \
                    str((xsh[ccd] + (2 - ccd) * dxshift) / xbin) + ' '
                message += 'yshift=' + \
                    str(ysh[ccd] / ybin) + ' xrotation=' + str(xrot[ccd]) + ' '
                message += 'yrotation=' + \
                    str(yrot[ccd]) + ' xmag=1 ymag=1 xmin=\'INDEF\''
                message += 'xmax=\'INDEF\' ymin=\'INDEF\' ymax=\'INDEF\' '
                message += 'ncols=\'INDEF\' '
                message += 'nlines=\'INDEF\' verbose=\'no\' '
                message += 'fluxconserve=\'yes\' nxblock=2048 '
                message += 'nyblock=2048 interpolant=\'' + \
                    interp_type + '\' boundary=\'constant\' constant=0'
                log.message(message, with_stdout=verbose)

                yd, xd = tilehdu[ccd].data.shape
                ncols = 'INDEF'  # ncols=xd+abs(xsh[ccd]/xbin)
                nlines = 'INDEF'  # nlines=yd+abs(ysh[ccd]/ybin)
                geo_xshift = xsh[ccd] + (2 - ccd) * dxshift / xbin
                geo_yshift = ysh[ccd] / ybin
                iraf.images.immatch.geotran(tilefile + "[" + str(ccd) + "]",
                                            tranfile[hdu],
                                            "",
                                            "",
                                            xshift=geo_xshift,
                                            yshift=geo_yshift,
                                            xrotation=xrot[ccd],
                                            yrotation=yrot[ccd],
                                            xmag=1,
                                            ymag=1,
                                            xmin='INDEF',
                                            xmax='INDEF',
                                            ymin='INDEF',
                                            ymax='INDEF',
                                            ncols=ncols,
                                            nlines=nlines,
                                            verbose='no',
                                            fluxconserve='yes',
                                            nxblock=2048,
                                            nyblock=2048,
                                            interpolant="linear",
                                            boundary="constant",
                                            constant=0)
                if varframe:
                    var_infile = tilefile + "[" + str(ccd + nccds) + "]"
                    iraf.images.immatch.geotran(var_infile,
                                                tranfile[hdu + nccds],
                                                "",
                                                "",
                                                xshift=geo_xshift,
                                                yshift=geo_yshift,
                                                xrotation=xrot[ccd],
                                                yrotation=yrot[ccd],
                                                xmag=1,
                                                ymag=1,
                                                xmin='INDEF',
                                                xmax='INDEF',
                                                ymin='INDEF',
                                                ymax='INDEF',
                                                ncols=ncols,
                                                nlines=nlines,
                                                verbose='no',
                                                fluxconserve='yes',
                                                nxblock=2048,
                                                nyblock=2048,
                                                interpolant="linear",
                                                boundary="constant",
                                                constant=0)
                    var2_infile = tilefile + "[" + str(ccd + 2 * nccds) + "]"
                    iraf.images.immatch.geotran(var2_infile,
                                                tranfile[hdu + 2 * nccds],
                                                "",
                                                "",
                                                xshift=geo_xshift,
                                                yshift=geo_yshift,
                                                xrotation=xrot[ccd],
                                                yrotation=yrot[ccd],
                                                xmag=1,
                                                ymag=1,
                                                xmin='INDEF',
                                                xmax='INDEF',
                                                ymin='INDEF',
                                                ymax='INDEF',
                                                ncols=ncols,
                                                nlines=nlines,
                                                verbose='no',
                                                fluxconserve='yes',
                                                nxblock=2048,
                                                nyblock=2048,
                                                interpolant="linear",
                                                boundary="constant",
                                                constant=0)

                # open the file and copy the data to tranhdu
                tstruct = fits.open(tranfile[hdu])
                tranhdu[hdu] = tstruct[0].data
                tstruct.close()
                if varframe:
                    tranhdu[hdu + nccds] = fits.open(tranfile[hdu +
                                                              nccds])[0].data
                    tranhdu[hdu + 2 * nccds] = fits.open(
                        tranfile[hdu + 2 * nccds])[0].data

            else:
                log.message("Transform CCD #%i using dx=%s, dy=%s, rot=%s" %
                            (ccd, xsh[ccd] / 2.0, ysh[ccd] / 2.0, xrot[ccd]),
                            with_stdout=verbose,
                            with_header=False)
                tranhdu[hdu] = geometric_transform(
                    tilehdu[ccd].data,
                    tran_func,
                    prefilter=False,
                    order=1,
                    extra_arguments=(xsh[ccd] / 2, ysh[ccd] / 2, 1, 1,
                                     xrot[ccd], yrot[ccd]))
                tstruct = fits.PrimaryHDU(tranhdu[hdu])
                tstruct.writeto(tranfile[hdu])
                if varframe:
                    tranhdu[hdu + nccds] = geometric_transform(
                        tilehdu[hdu + 3].data,
                        tran_func,
                        prefilter=False,
                        order=1,
                        extra_arguments=(xsh[ccd] / 2, ysh[ccd] / 2, 1, 1,
                                         xrot[ccd], yrot[ccd]))
                    tranhdu[hdu + 2 * nccds] = geometric_transform(
                        tilehdu[hdu + 6].data,
                        tran_func,
                        prefilter=False,
                        order=1,
                        extra_arguments=(xsh[ccd] / 2, ysh[ccd] / 2, 1, 1,
                                         xrot[ccd], yrot[ccd]))

        else:
            log.message("Transform CCD #%i using dx=%s, dy=%s, rot=%s" %
                        (ccd, 0, 0, 0),
                        with_stdout=verbose,
                        with_header=False)
            tranhdu[hdu] = tilehdu[ccd].data
            if varframe:
                tranhdu[hdu + nccds] = tilehdu[ccd + nccds].data
                tranhdu[hdu + 2 * nccds] = tilehdu[ccd + 2 * nccds].data

    # open outfile
    if varframe:
        outlist = 4 * [None]
    else:
        outlist = 2 * [None]

    #outlist[0] = struct[0].copy()
    outlist[0] = fits.PrimaryHDU()
    outlist[0].header = struct[0].header

    naxis1 = int(gap / xbin * (nccds - 1))
    naxis2 = 0
    for i in range(1, nccds + 1):
        yw, xw = tranhdu[i].shape
        naxis1 += xw + int(abs(xsh[ccd] / xbin)) + 1
        naxis2 = max(naxis2, yw)
    outdata = numpy.zeros((naxis2, naxis1), numpy.float32)
    outdata.shape = naxis2, naxis1
    if varframe:
        vardata = outdata * 0
        bpmdata = outdata * 0 + 1

    # iterate over CCDs, stich them to produce a full image
    hdu = 0
    totxshift = 0
    for hdu in range(1, nccds + 1):

        # read DATASEC keywords
        ydsec, xdsec = tranhdu[hdu].shape

        # define size and shape of final image
        # tile CCDs to yield mosaiced image
        x1 = int((hdu - 1) * (xdsec + gap / xbin)) + int(totxshift)
        x2 = xdsec + x1
        y1 = int(0)
        y2 = int(ydsec)
        outdata[y1:y2, x1:x2] = tranhdu[hdu]
        totxshift += int(abs(xsh[hdu] / xbin)) + 1
        if varframe:
            vardata[y1:y2, x1:x2] = tranhdu[hdu + nccds]
            bpmdata[y1:y2, x1:x2] = tranhdu[hdu + 2 * nccds]

    # make sure to cover up all the gaps include bad areas
    if varframe:
        baddata = (outdata == 0)
        baddata = nd.maximum_filter(baddata, size=3)
        bpmdata[baddata] = 1

    # fill in the gaps if requested
    if fill:
        if varframe:
            outdata = fill_gaps(outdata, 0)
        else:
            outdata = fill_gaps(outdata, 0)

    # add to the file
    outlist[1] = fits.ImageHDU(outdata)
    if varframe:
        outlist[2] = fits.ImageHDU(vardata, name='VAR')
        outlist[3] = fits.ImageHDU(bpmdata, name='BPM')

    # create the image structure
    outstruct = fits.HDUList(outlist)

    # update the head informaation
    # housekeeping keywords
    saltkey.put('NEXTEND', 2, outstruct[0])
    saltkey.new('EXTNAME', 'SCI', 'Extension name', outstruct[1])
    saltkey.new('EXTVER', 1, 'Extension number', outstruct[1])
    if varframe:
        saltkey.new('VAREXT', 2, 'Variance frame extension', outstruct[1])
        saltkey.new('BPMEXT', 3, 'BPM Extension', outstruct[1])

    try:
        saltkey.copy(struct[1], outstruct[1], 'CCDSUM')
    except:
        pass

    # Add keywords associated with geometry
    saltkey.new('SGEOMGAP', gap, 'SALT Chip Gap', outstruct[0])
    c1str = '{:3.2f} {:3.2f} {:3.4f}'.format(xshift[0], yshift[0], rotation[0])
    saltkey.new('SGEOM1', c1str, 'SALT Chip 1 Transform', outstruct[0])
    c2str = '{:3.2f} {:3.2f} {:3.4f}'.format(xshift[1], yshift[1], rotation[1])
    saltkey.new('SGEOM2', c2str, 'SALT Chip 2 Transform', outstruct[0])

    # WCS keywords
    saltkey.new('CRPIX1', 0, 'WCS: X reference pixel', outstruct[1])
    saltkey.new('CRPIX2', 0, 'WCS: Y reference pixel', outstruct[1])
    saltkey.new('CRVAL1', float(xbin), 'WCS: X reference coordinate value',
                outstruct[1])
    saltkey.new('CRVAL2', float(ybin), 'WCS: Y reference coordinate value',
                outstruct[1])
    saltkey.new('CDELT1', float(xbin), 'WCS: X pixel size', outstruct[1])
    saltkey.new('CDELT2', float(ybin), 'WCS: Y pixel size', outstruct[1])
    saltkey.new('CTYPE1', 'pixel', 'X type', outstruct[1])
    saltkey.new('CTYPE2', 'pixel', 'Y type', outstruct[1])

    # cleanup temporary files
    if cleanup:
        for tfile in tranfile:
            if os.path.isfile(tfile):
                saltio.delete(tfile)
        if os.path.isfile(tilefile):
            status = saltio.delete(tilefile)

    # return the file
    return outstruct
Пример #9
0
def slotmerge(images, outimages, outpref, geomfile, clobber, logfile, verbose):

    with logging(logfile, debug) as log:
        # are the arguments defined
        saltsafeio.argdefined('images', images)
        saltsafeio.argdefined('geomfile', geomfile)
        saltsafeio.argdefined('logfile', logfile)

        # if the input file is a list, does it exist?
        if images[0] == '@':
            saltsafeio.listexists('Input', images)

        # parse list of input files
        infiles = saltsafeio.listparse('Raw image', images, '', '', '')

        # check input files exist
        saltsafeio.filesexist(infiles, '', 'r')

        # load output name list: @list, * and comma separated
        outimages = outimages.strip()
        outpref = outpref.strip()
        if len(outpref) == 0 and len(outimages) == 0:
            raise SaltIOError('Output file(s) not specified')

        # test output @filelist exists
        if len(outimages) > 0 and outimages[0] == '@':
            saltsafeio.listexists('Output', outimages)

        # parse list of output files
        outfiles = saltsafeio.listparse('Output image', outimages, outpref,
                                        infiles, '')

        # are input and output lists the same length?
        saltsafeio.comparelists(infiles, outfiles, 'Input', 'output')

        # do the output files already exist?
        if not clobber:
            saltsafeio.filesexist(outfiles, '', 'w')

        # does CCD geometry definition file exist
        geomfilefile = geomfile.strip()
        saltsafeio.fileexists(geomfile)

        # read geometry definition file
        gap = 0
        xshift = [0, 0]
        yshift = [0, 0]
        rotation = [0, 0]

        gap, xshift, yshift, rotation = saltsafeio.readccdgeom(geomfile)
        for ro in rotation:
            if ro != 0:
                log.warning('SLOTMERGE currently ignores CCD rotation')

        # Begin processes each file
        for infile, outfile in zip(infiles, outfiles):
            # determine the name for the output file
            outpath = outfile.rstrip(os.path.basename(outfile))
            if (len(outpath) == 0):
                outpath = '.'

            # open each raw image
            struct = saltsafeio.openfits(infile)

            # identify instrument
            instrume, keyprep, keygain, keybias, keyxtalk, keyslot = saltsafekey.instrumid(
                struct, infile)

            # how many amplifiers?
            nccds = saltsafekey.get('NCCDS', struct[0], infile)
            amplifiers = nccds * 2
            #if (nccds != 2):
            #    raise SaltError('Can not currently handle more than two CCDs')

            # CCD geometry coefficients
            if instrume == 'RSS' or instrume == 'PFIS':
                xsh = [xshift[0], 0., xshift[1]]
                ysh = [yshift[0], 0., yshift[1]]
                rot = [rotation[0], 0., rotation[1]]
                refid = 1
            if instrume == 'SALTICAM':
                xsh = [xshift[0], 0.]
                ysh = [yshift[0], 0.]
                rot = [rotation[0], 0]
                refid = 1

            # how many extensions?
            nextend = saltsafekey.get('NEXTEND', struct[0], infile)

            # how many exposures
            exposures = nextend / amplifiers

            # CCD on-chip binning
            xbin, ybin = saltsafekey.ccdbin(struct[0], infile)
            gp = int(gap / xbin)

            # create output hdu structure
            outstruct = [None] * int(exposures + 1)
            outstruct[0] = struct[0]

            # iterate over exposures, stitch them to produce file of CCD images
            for i in range(exposures):
                # Determine the total size of the image
                xsize = 0
                ysize = 0
                for j in range(amplifiers):
                    hdu = i * amplifiers + j + 1
                    try:
                        xsize += len(struct[hdu].data[0])
                        if ysize < len(struct[hdu].data):
                            ysize = len(struct[hdu].data)
                    except:
                        msg = 'Unable to access extension %i ' % hdu
                        raise SaltIOError(msg)
                xsize += gp * (nccds - 1)
                maxxsh, minxsh = determineshifts(xsh)
                maxysh, minysh = determineshifts(ysh)
                xsize += (maxxsh - minxsh)
                ysize += (maxysh - minysh)

                # Determine the x and y origins for each frame
                xdist = 0
                ydist = 0
                shid = 0
                x0 = np.zeros(amplifiers)
                y0 = np.zeros(amplifiers)
                for j in range(amplifiers):
                    x0[j] = xdist + xsh[shid] - minxsh
                    y0[j] = ysh[shid] - minysh
                    hdu = i * amplifiers + j + 1
                    darr = struct[hdu].data
                    xdist += len(darr[0])
                    if j % 2 == 1:
                        xdist += gp
                        shid += 1

                # make the out image
                outarr = np.zeros((ysize, xsize), np.float64)

                # Embed each frame into the output array
                for j in range(amplifiers):
                    hdu = i * amplifiers + j + 1
                    darr = struct[hdu].data
                    outarr = salttran.embed(darr, x0[j], y0[j], outarr)

                # Add the outimage to the output structure
                hdu = i * amplifiers + 1
                outhdu = i + 1
                outstruct[outhdu] = pyfits.ImageHDU(outarr)
                outstruct[outhdu].header = struct[hdu].header

                # Fix the headers in each extension
                datasec = '[1:%4i,1:%4i]' % (xsize, ysize)
                saltsafekey.put('DATASEC', datasec, outstruct[outhdu], outfile)
                saltsafekey.rem('DETSIZE', outstruct[outhdu], outfile)
                saltsafekey.rem('DETSEC', outstruct[outhdu], outfile)
                saltsafekey.rem('CCDSEC', outstruct[outhdu], outfile)
                saltsafekey.rem('AMPSEC', outstruct[outhdu], outfile)

                # add housekeeping key words
                outstruct[outhdu] = addhousekeeping(outstruct[outhdu], outhdu,
                                                    outfile)

            # close input FITS file
            saltsafeio.closefits(struct)

            # housekeeping keywords
            keymosaic = 'SLOTMERG'
            fname, hist = history(level=1, wrap=False)
            saltsafekey.housekeeping(struct[0], keymosaic,
                                     'Amplifiers have been mosaiced', hist)
            #saltsafekey.history(outstruct[0],hist)

            # this is added for later use by
            saltsafekey.put('NCCDS', 0.5, outstruct[0])
            saltsafekey.put('NSCIEXT', exposures, outstruct[0])
            saltsafekey.put('NEXTEND', exposures, outstruct[0])

            # write FITS file of mosaiced image
            outstruct = pyfits.HDUList(outstruct)
            saltsafeio.writefits(outstruct, outfile, clobber=clobber)
Пример #10
0
def specslit(image,
             outimage,
             outpref,
             exttype='auto',
             slitfile='',
             outputslitfile='',
             regprefix='',
             sections=3,
             width=25,
             sigma=2.2,
             thres=6,
             order=3,
             padding=5,
             yoffset=0,
             inter=False,
             clobber=True,
             logfile='salt.log',
             verbose=True):

    with logging(logfile, debug) as log:

        # check all the input and make sure that all the input needed is provided
        # by the user

        # read the image or image list and check if each in the list exist
        infiles = saltio.argunpack('Input', image)

        # unpack the outfiles
        outfiles = saltio.listparse('Outimages', outimage, outpref, infiles,
                                    '')

        # from the extraction type, check whether the input file is specified.
        # if the slitfile parameter is specified then use the slit files for
        # the extraction. if the extraction type is auto then use image for the
        # detection and the slit extraction

        if exttype == 'rsmt' or exttype == 'fits' or exttype == 'ascii' or exttype == 'ds9':
            slitfiles = saltio.argunpack('Slitfile', slitfile)
            if len(slitfiles) == 1:
                slitfiles = slitfiles * len(infiles)
            saltio.comparelists(infiles, slitfiles, 'image', 'slitfile')
        elif exttype == 'auto':
            slitfiles = infiles
            log.message(
                'Extraction type is AUTO. Slit detection will be done from image'
            )

        # read in if an optional ascii file is requested
        if len(outputslitfile) > 0:
            outslitfiles = saltio.argunpack('Outslitfiles', outputslitfile)
            saltio.comparelists(infiles, outslitfiles, 'image',
                                'outputslitfile')
        else:
            outslitfiles = [''] * len(infiles)

        # check if the width and sigma parameters were specified.
        # default is 25 and 2.2
        if width < 10.:
            msg = 'The width parameter needs be a value larger than 10'
            raise SALTSpecError(msg)

        if sigma < 0.0:
            msg = 'Sigma must be greater than zero'
            raise SaltSpecError(msg)

        # check the treshold parameter. this needs to be specified by the user
        if thres <= 0.0:
            msg = 'Threshold must be greater than zero'
            raise SaltSpecError(msg)

        # check to make sure that the sections are greater than the order
        if sections <= order:
            msg = 'Number of sections must be greater than the order for the spline fit'
            raise SaltSpecError(msg)

        # run through each of the images and extract the slits
        for img, oimg, sfile, oslit in zip(infiles, outfiles, slitfiles,
                                           outslitfiles):
            log.message('Proccessing image %s' % img)

            # open the image
            struct = saltio.openfits(img)
            ylen, xlen = struct[1].data.shape
            xbin, ybin = saltkey.ccdbin(struct[0], img)
            # setup the VARIANCE and BPM frames
            if saltkey.found('VAREXT', struct[1]):
                varext = saltkey.get('VAREXT', struct[1])
                varlist = []
            else:
                varext = None

            # setup the BPM frames
            if saltkey.found('BPMEXT', struct[1]):
                bpmext = saltkey.get('BPMEXT', struct[1])
                bpmlist = []
            else:
                bpmext = None

            # open the slit definition file or identify the slits in the image
            slitmask = None
            ycheck = False
            if exttype == 'rsmt':
                log.message('Using slits from %s' % sfile)
                if yoffset is None:
                    yoffset = 0
                    ycheck = True
                slitmask = mt.read_slitmask_from_xml(sfile)
                xpos = -0.3066
                ypos = 0.0117
                cx = int(xlen / 2.0)
                cy = int(ylen / 2.0) + ypos / 0.015 / ybin + yoffset
                order, slit_positions = mt.convert_slits_from_mask(
                    slitmask,
                    order=1,
                    xbin=xbin,
                    ybin=ybin,
                    pix_scale=0.1267,
                    cx=cx,
                    cy=cy)
                sections = 1
            elif exttype == 'fits':
                log.message('Using slits from %s' % sfile)
                order, slit_positions = read_slits_from_fits(sfile)
            elif exttype == 'ascii':
                log.message('Using slits from %s' % sfile)
                order, slit_positions = mt.read_slits_from_ascii(sfile)
            elif exttype == 'ds9':
                log.message('Using slits from %s' % sfile)
                order, slit_positions, slitmask = mt.read_slits_from_ds9(
                    sfile, order=order)
                slitmask = None
                sections = 1
            elif exttype == 'auto':
                log.message('Identifying slits in %s' % img)
                # identify the slits in the image
                order, slit_positions = identify_slits(struct[1].data, order,
                                                       sections, width, sigma,
                                                       thres)

                # write out the slit identifications if ofile has been supplied
                if oslit:
                    log.message('Writing slit positions to %s' % oslit)
                    mt.write_outputslitfile(slit_positions, oslit, order)

            if ycheck:
                slit_positions, dy = check_ypos(slit_positions, struct[1].data)
                log.message('Using an offset of {}'.format(dy))

            # extract the slits
            spline_x = mt.divide_image(struct[1].data, sections)
            spline_x = 0.5 * (np.array(spline_x[:-1]) + np.array(spline_x[1:]))
            extracted_spectra, spline_positions = mt.extract_slits(
                slit_positions,
                spline_x,
                struct[1].data,
                order=order,
                padding=padding)
            if varext:
                extracted_var, var_positions = mt.extract_slits(
                    slit_positions,
                    spline_x,
                    struct[varext].data,
                    order=order,
                    padding=padding)
            if bpmext:
                extracted_bpm, bpm_positions = mt.extract_slits(
                    slit_positions,
                    spline_x,
                    struct[bpmext].data,
                    order=order,
                    padding=padding)

            # write out the data to the new array
            # create the new file
            hdulist = fits.HDUList([struct[0]])

            # log the extracted spectra if needed
            log.message('', with_stdout=verbose)

            # setup output ds9 file
            if regprefix:
                regout = open(
                    regprefix + os.path.basename(img).strip('.fits') + '.reg',
                    'w')
                regout.write('# Region file format: DS9 version 4.1\n')
                regout.write('# Filename: %s\n' % img)
                regout.write(
                    'global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1\nphysical\n'
                )

            # add each
            imglist = []
            nslits = len(spline_positions)
            for i in range(nslits):
                y1 = spline_positions[i][0].min()
                y2 = spline_positions[i][1].max()
                msg = 'Extracted Spectra %i between %i to %i' % (i + 1, y1, y2)
                # log.message(msg, with_header=False, with_stdout=verbose)
                sdu = fits.ImageHDU(extracted_spectra[i],
                                    header=struct[1].header)
                if varext:
                    vdu = fits.ImageHDU(extracted_var[i],
                                        header=struct[varext].header)
                    sdu.header['VAREXT'] = i + nslits + 1
                    varlist.append(vdu)
                if bpmext:
                    bdu = fits.ImageHDU(extracted_bpm[i],
                                        header=struct[bpmext].header)
                    sdu.header['BPMEXT'] = i + 2 * nslits + 1
                    bpmlist.append(bdu)
                imglist.append(sdu)

                # add in some additional keywords
                imglist[i].header['MINY'] = (y1,
                                             'Lower Y value in original image')
                imglist[i].header['MAXY'] = (y2,
                                             'Upper Y value in original image')
                if regprefix:
                    xsize = struct[1].data.shape[1]
                    xsize = int(0.5 * xsize)
                    rtext = ''
                    if slitmask:
                        # rtext='%s, %8.7f, %8.7f, %3.2f' % (slitmask.slitlets.data[i]['name'], slitmask.slitlets.data[i]['targ_ra'], slitmask.slitlets.data[i]['targ_dec'], slitmask.slitlets.data[i]['slit_width'])
                        pass
                    regout.write('box(%i,%i, %i, %i) #text={%s}\n' %
                                 (xsize, 0.5 *
                                  (y1 + y2), 2 * xsize, y2 - y1, rtext))

                # add slit information
                if slitmask:
                    imglist[i].header['SLITNAME'] = (
                        slitmask.slitlets.data[i]['name'], 'Slit Name')
                    imglist[i].header['SLIT_RA'] = (
                        slitmask.slitlets.data[i]['targ_ra'], 'Slit RA')
                    imglist[i].header['SLIT_DEC'] = (
                        slitmask.slitlets.data[i]['targ_dec'], 'Slit DEC')
                    imglist[i].header['SLIT'] = (
                        slitmask.slitlets.data[i]['slit_width'], 'Slit Width')

            # add to the hdulist
            hdulist += imglist
            if varext:
                hdulist += varlist
            if bpmext:
                hdulist += bpmlist

            # write the slit positions to the header
            # create the binary table HDU that contains the split positions
            tbhdu = mt.slits_HDUtable(slit_positions, order)
            bintable_hdr = tbhdu.header

            # add the extname parameter to the extension
            tbhdu.header['EXTNAME'] = 'BINTABLE'

            # add the extname parameter to the extension
            hdulist[0].header['SLITEXT'] = len(hdulist)
            hdulist.append(tbhdu)

            # add addition header information about the mask
            if slitmask:
                hdulist[0].header['MASKNAME'] = (slitmask.mask_name,
                                                 'SlitMask Name')
                hdulist[0].header['MASK_RA'] = (slitmask.center_ra,
                                                'SlitMask RA')
                hdulist[0].header['MASK_DEC'] = (slitmask.center_dec,
                                                 'SlitMask DEC')
                hdulist[0].header['MASK_PA'] = (slitmask.position_angle,
                                                'SlitMask Position Angle')

            # write out the image
            saltio.writefits(hdulist, oimg, clobber)
Пример #11
0
def slotmerge(images,outimages,outpref,geomfile,clobber,logfile,verbose):

    with logging(logfile,debug) as log:
        # are the arguments defined
        saltsafeio.argdefined('images',images)
        saltsafeio.argdefined('geomfile',geomfile)
        saltsafeio.argdefined('logfile',logfile)

        # if the input file is a list, does it exist?
        if images[0] == '@':
            saltsafeio.listexists('Input',images)

        # parse list of input files
        infiles=saltsafeio.listparse('Raw image',images,'','','')

        # check input files exist
        saltsafeio.filesexist(infiles,'','r')

        # load output name list: @list, * and comma separated
        outimages = outimages.strip()
        outpref = outpref.strip()
        if len(outpref) == 0 and len(outimages) == 0:
            raise SaltIOError('Output file(s) not specified')

        # test output @filelist exists
        if len(outimages) > 0 and outimages[0] == '@':
            saltsafeio.listexists('Output',outimages)

        # parse list of output files
        outfiles=saltsafeio.listparse('Output image',outimages,outpref,infiles,'')

        # are input and output lists the same length?
        saltsafeio.comparelists(infiles,outfiles,'Input','output')

        # do the output files already exist?
        if not clobber:
            saltsafeio.filesexist(outfiles,'','w')

        # does CCD geometry definition file exist
        geomfilefile = geomfile.strip()
        saltsafeio.fileexists(geomfile)

        # read geometry definition file
        gap = 0
        xshift = [0, 0]
        yshift = [0, 0]
        rotation = [0, 0]

        gap, xshift, yshift, rotation=saltsafeio.readccdgeom(geomfile)
        for ro in rotation:
            if ro!=0:
                log.warning('SLOTMERGE currently ignores CCD rotation')

        # Begin processes each file
        for infile, outfile in zip(infiles, outfiles):
            # determine the name for the output file
            outpath = outfile.rstrip(os.path.basename(outfile))
            if (len(outpath) == 0):
                outpath = '.'

            # open each raw image
            struct=saltsafeio.openfits(infile)

            # identify instrument
            instrume,keyprep,keygain,keybias,keyxtalk,keyslot=saltsafekey.instrumid(struct,infile)

            # how many amplifiers?
            nccds=saltsafekey.get('NCCDS',struct[0],infile)
            amplifiers = nccds * 2
            #if (nccds != 2):
            #    raise SaltError('Can not currently handle more than two CCDs')

            # CCD geometry coefficients
            if instrume == 'RSS' or instrume == 'PFIS':
                xsh = [xshift[0], 0., xshift[1]]
                ysh = [yshift[0], 0., yshift[1]]
                rot = [rotation[0], 0., rotation[1]]
                refid = 1
            if instrume == 'SALTICAM':
                xsh = [xshift[0], 0.]
                ysh = [yshift[0], 0.]
                rot = [rotation[0], 0]
                refid = 1

            # how many extensions?
            nextend=saltsafekey.get('NEXTEND',struct[0],infile)

            # how many exposures
            exposures = nextend/amplifiers

            # CCD on-chip binning
            xbin, ybin=saltsafekey.ccdbin(struct[0],infile)
            gp = int(gap / xbin)

            # create output hdu structure
            outstruct = [None] * int(exposures+1)
            outstruct[0]=struct[0]

            # iterate over exposures, stitch them to produce file of CCD images
            for i in range(exposures):
                # Determine the total size of the image
                xsize=0
                ysize=0
                for j in range(amplifiers):
                    hdu=i*amplifiers+j+1
                    try:
                        xsize += len(struct[hdu].data[0])
                        if ysize < len(struct[hdu].data):
                            ysize=len(struct[hdu].data)
                    except:
                        msg='Unable to access extension %i ' % hdu
                        raise SaltIOError(msg)
                xsize += gp* (nccds-1)
                maxxsh, minxsh = determineshifts(xsh)
                maxysh, minysh = determineshifts(ysh)
                xsize += (maxxsh-minxsh)
                ysize += (maxysh-minysh)

                # Determine the x and y origins for each frame
                xdist=0
                ydist=0
                shid=0
                x0=np.zeros(amplifiers)
                y0=np.zeros(amplifiers)
                for j in range(amplifiers):
                    x0[j]=xdist+xsh[shid]-minxsh
                    y0[j]=ysh[shid]-minysh
                    hdu=i*amplifiers+j+1
                    darr=struct[hdu].data
                    xdist += len(darr[0])
                    if j%2==1:
                        xdist += gp
                        shid += 1

                # make the out image
                outarr=np.zeros((ysize, xsize), np.float64)

                # Embed each frame into the output array
                for j in range(amplifiers):
                    hdu=i*amplifiers+j+1
                    darr=struct[hdu].data
                    outarr=salttran.embed(darr, x0[j], y0[j], outarr)

                # Add the outimage to the output structure
                hdu=i*amplifiers+1
                outhdu=i+1
                outstruct[outhdu] = pyfits.ImageHDU(outarr)
                outstruct[outhdu].header=struct[hdu].header

                # Fix the headers in each extension
                datasec='[1:%4i,1:%4i]' % (xsize, ysize)
                saltsafekey.put('DATASEC',datasec, outstruct[outhdu], outfile)
                saltsafekey.rem('DETSIZE',outstruct[outhdu],outfile)
                saltsafekey.rem('DETSEC',outstruct[outhdu],outfile)
                saltsafekey.rem('CCDSEC',outstruct[outhdu],outfile)
                saltsafekey.rem('AMPSEC',outstruct[outhdu],outfile)

                # add housekeeping key words
                outstruct[outhdu]=addhousekeeping(outstruct[outhdu], outhdu, outfile)

            # close input FITS file
            saltsafeio.closefits(struct)

            # housekeeping keywords
            keymosaic='SLOTMERG'
            fname, hist=history(level=1, wrap=False)
            saltsafekey.housekeeping(struct[0],keymosaic,'Amplifiers have been mosaiced', hist)
            #saltsafekey.history(outstruct[0],hist)

            # this is added for later use by
            saltsafekey.put('NCCDS', 0.5, outstruct[0])
            saltsafekey.put('NSCIEXT', exposures, outstruct[0])
            saltsafekey.put('NEXTEND', exposures, outstruct[0])

            # write FITS file of mosaiced image
            outstruct=pyfits.HDUList(outstruct)
            saltsafeio.writefits(outstruct, outfile, clobber=clobber)
Пример #12
0
def specidentify(images,
                 linelist,
                 outfile,
                 guesstype='rss',
                 guessfile='',
                 automethod='Matchlines',
                 function='poly',
                 order=3,
                 rstep=100,
                 rstart='middlerow',
                 mdiff=5,
                 thresh=3,
                 niter=5,
                 smooth=0,
                 subback=0,
                 inter=True,
                 startext=0,
                 clobber=False,
                 textcolor='black',
                 preprocess=False,
                 logfile='salt.log',
                 verbose=True):

    with logging(logfile, debug) as log:

        # set up the variables
        infiles = []
        outfiles = []

        # Check the input images
        infiles = saltio.argunpack('Input', images)

        # create list of output files
        outfiles = saltio.argunpack('Output', outfile)

        # open the line lists
        slines, sfluxes = st.readlinelist(linelist)

        # Identify the lines in each file
        for img, ofile in zip(infiles, outfiles):

            # open the image
            hdu = saltio.openfits(img)

            # get the basic information about the spectrograph
            dateobs = saltkey.get('DATE-OBS', hdu[0])
            try:
                utctime = saltkey.get('UTC-OBS', hdu[0])
            except SaltError:
                utctime = saltkey.get('TIME-OBS', hdu[0])

            instrume = saltkey.get('INSTRUME', hdu[0]).strip()
            grating = saltkey.get('GRATING', hdu[0]).strip()
            grang = saltkey.get('GR-ANGLE', hdu[0])
            grasteps = saltkey.get('GRTILT', hdu[0])
            arang = saltkey.get('AR-ANGLE', hdu[0])
            arsteps = saltkey.get('CAMANG', hdu[0])
            rssfilter = saltkey.get('FILTER', hdu[0])
            specmode = saltkey.get('OBSMODE', hdu[0])
            masktype = saltkey.get('MASKTYP', hdu[0]).strip().upper()
            slitname = saltkey.get('MASKID', hdu[0])
            xbin, ybin = saltkey.ccdbin(hdu[0], img)

            for i in range(startext, len(hdu)):
                if hdu[i].name == 'SCI':
                    log.message('Proccessing extension %i in  %s' % (i, img))
                    # things that will change for each slit

                    if masktype == 'LONGSLIT':
                        slit = st.getslitsize(slitname)
                        xpos = -0.2666
                        ypos = 0.0117
                        objid = None
                    elif masktype == 'MOS':
                        slit = 1.
                        #slit=saltkey.get('SLIT', hdu[i])

                        # set up the x and y positions
                        miny = hdu[i].header['MINY']
                        maxy = hdu[i].header['MAXY']
                        ras = hdu[i].header['SLIT_RA']
                        des = hdu[i].header['SLIT_DEC']
                        objid = hdu[i].header['SLITNAME']

                        # TODO: Check the perfomance of masks at different PA
                        rac = hdu[0].header['MASK_RA']
                        dec = hdu[0].header['MASK_DEC']
                        pac = hdu[0].header['PA']

                        # these are hard wired at the moment
                        xpixscale = 0.1267 * xbin
                        ypixscale = 0.1267 * ybin
                        cx = int(3162 / xbin)
                        cy = int(2050 / ybin)

                        x, y = mt.convert_fromsky(ras,
                                                  des,
                                                  rac,
                                                  dec,
                                                  xpixscale=xpixscale,
                                                  ypixscale=ypixscale,
                                                  position_angle=-pac,
                                                  ccd_cx=cx,
                                                  ccd_cy=cy)
                        xpos = 0.015 * 2 * (cx - x[0])
                        ypos = 0.0117
                    else:
                        msg = '%s is not a currently supported masktype' % masktype
                        raise SALTSpecError(msg)

                    if instrume not in ['PFIS', 'RSS']:
                        msg = '%s is not a currently supported instrument' % instrume
                        raise SALTSpecError(msg)

                    # create RSS Model
                    rss = RSSModel.RSSModel(grating_name=grating.strip(),
                                            gratang=grang,
                                            camang=arang,
                                            slit=slit,
                                            xbin=xbin,
                                            ybin=ybin,
                                            xpos=xpos,
                                            ypos=ypos)
                    res = 1e7 * rss.calc_resolelement(rss.alpha(), -rss.beta())
                    dres = res / 10.0
                    wcen = 1e7 * rss.calc_centralwavelength()
                    R = rss.calc_resolution(wcen / 1e7, rss.alpha(),
                                            -rss.beta())
                    logmsg = '\nGrating\tGR-ANGLE\tAR-ANGLE\tSlit\tWCEN\tR\n'
                    logmsg += '%s\t%8.3f\t%8.3f\t%4.2f\t%6.2f\t%4f\n' % (
                        grating, grang, arang, slit, wcen, R)
                    if log:
                        log.message(logmsg, with_header=False)

                    # set up the data for the source
                    try:
                        data = hdu[i].data
                    except Exception, e:
                        message = 'Unable to read in data array in %s because %s' % (
                            img, e)
                        raise SALTSpecError(message)

                    # set up the center row
                    if rstart == 'middlerow':
                        ystart = int(0.5 * len(data))
                    else:
                        ystart = int(rstart)

                    rss.gamma = 0.0
                    if masktype == 'MOS':
                        rss.gamma = 180.0 / math.pi * math.atan(
                            (y * rss.detector.pix_size * rss.detector.ybin -
                             0.5 * rss.detector.find_height()) /
                            rss.camera.focallength)

                    # set up the xarr array based on the image
                    xarr = np.arange(len(data[ystart]), dtype='int64')

                    # get the guess for the wavelength solution
                    if guesstype == 'rss':
                        # set up the rss model
                        ws = st.useRSSModel(xarr,
                                            rss,
                                            function=function,
                                            order=order,
                                            gamma=rss.gamma)
                        if function in ['legendre', 'chebyshev']:
                            ws.func.func.domain = [xarr.min(), xarr.max()]
                    elif guesstype == 'file':
                        soldict = {}
                        soldict = readsolascii(guessfile, soldict)
                        timeobs = enterdatetime('%s %s' % (dateobs, utctime))
                        exptime = saltkey.get('EXPTIME', hdu[0])
                        filtername = saltkey.get('FILTER', hdu[0]).strip()
                        try:
                            slitid = saltkey.get('SLITNAME', hdu[i])
                        except:
                            slitid = None

                        function, order, coef, domain = findlinesol(soldict,
                                                                    ystart,
                                                                    True,
                                                                    timeobs,
                                                                    exptime,
                                                                    instrume,
                                                                    grating,
                                                                    grang,
                                                                    arang,
                                                                    filtername,
                                                                    slitid,
                                                                    xarr=xarr)
                        ws = WavelengthSolution.WavelengthSolution(
                            xarr, xarr, function=function, order=order)
                        ws.func.func.domain = domain
                        ws.set_coef(coef)
                    else:
                        raise SALTSpecError(
                            'This guesstype is not currently supported')

                    # identify the spectral lines
                    ImageSolution = identify(data,
                                             slines,
                                             sfluxes,
                                             xarr,
                                             ystart,
                                             ws=ws,
                                             function=function,
                                             order=order,
                                             rstep=rstep,
                                             mdiff=mdiff,
                                             thresh=thresh,
                                             niter=niter,
                                             method=automethod,
                                             res=res,
                                             dres=dres,
                                             smooth=smooth,
                                             inter=inter,
                                             filename=img,
                                             subback=0,
                                             textcolor=textcolor,
                                             preprocess=preprocess,
                                             log=log,
                                             verbose=verbose)

                    if outfile and len(ImageSolution):
                        writeIS(ImageSolution,
                                outfile,
                                dateobs=dateobs,
                                utctime=utctime,
                                instrume=instrume,
                                grating=grating,
                                grang=grang,
                                grasteps=grasteps,
                                arsteps=arsteps,
                                arang=arang,
                                rfilter=rssfilter,
                                slit=slit,
                                xbin=xbin,
                                ybin=ybin,
                                objid=objid,
                                filename=img,
                                log=log,
                                verbose=verbose)
Пример #13
0
def make_mosaic(struct, gap, xshift, yshift, rotation, interp_type='linear',
                boundary='constant', constant=0, geotran=True, fill=False,
                cleanup=True, log=None, verbose=False):
    """Given a SALT image struct, combine each of the individual amplifiers and
        apply the geometric CCD transformations to the image
    """

    # get the name of the file
    infile = saltkey.getimagename(struct[0], base=True)
    outpath = './'

    # identify instrument
    instrume, keyprep, keygain, keybias, keyxtalk, keyslot = \
        saltkey.instrumid(struct)

    # how many amplifiers?
    nsciext = saltkey.get('NSCIEXT', struct[0])
    nextend = saltkey.get('NEXTEND', struct[0])
    nccds = saltkey.get('NCCDS', struct[0])
    amplifiers = nccds * 2

    if nextend > nsciext:
        varframe = True
    else:
        varframe = False

    # CCD geometry coefficients
    if (instrume == 'RSS' or instrume == 'PFIS'):
        xsh = [0., xshift[0], 0., xshift[1]]
        ysh = [0., yshift[0], 0., yshift[1]]
        rot = [0., rotation[0], 0., rotation[1]]
    elif instrume == 'SALTICAM':
        xsh = [0., xshift[0], 0.]
        ysh = [0., yshift[0], 0.]
        rot = [0., rotation[0], 0]

    # how many extensions?
    nextend = saltkey.get('NEXTEND', struct[0])

    # CCD on-chip binning
    xbin, ybin = saltkey.ccdbin(struct[0])

    # create temporary primary extension
    outstruct = []
    outstruct.append(struct[0])
    # define temporary FITS file store tiled CCDs

    tilefile = saltio.tmpfile(outpath)
    tilefile += 'tile.fits'
    if varframe:
        tilehdu = [None] * (3 * int(nsciext / 2) + 1)
    else:
        tilehdu = [None] * int(nsciext / 2 + 1)
    tilehdu[0] = fits.PrimaryHDU()
    #tilehdu[0].header = struct[0].header

    if log:
        log.message('', with_stdout=verbose)

    # iterate over amplifiers, stich them to produce file of CCD images
    for i in range(int(nsciext / 2)):
        hdu = i * 2 + 1
        # amplifier = hdu%amplifiers
        # if (amplifier == 0): amplifier = amplifiers

        # read DATASEC keywords
        datasec1 = saltkey.get('DATASEC', struct[hdu])
        datasec2 = saltkey.get('DATASEC', struct[hdu + 1])
        xdsec1, ydsec1 = saltstring.secsplit(datasec1)
        xdsec2, ydsec2 = saltstring.secsplit(datasec2)

        # read images
        imdata1 = saltio.readimage(struct, hdu)
        imdata2 = saltio.readimage(struct, hdu + 1)

        # tile 2n amplifiers to yield n CCD images
        outdata = numpy.zeros((ydsec1[1] +
                               abs(ysh[i +
                                       1] /
                                   ybin), xdsec1[1] +
                               xdsec2[1] +
                               abs(xsh[i +
                                       1] /
                                   xbin)), numpy.float32)

        # set up the variance frame
        if varframe:
            vardata = outdata.copy()
            vdata1 = saltio.readimage(struct, struct[hdu].header['VAREXT'])
            vdata2 = saltio.readimage(struct, struct[hdu + 1].header['VAREXT'])

            bpmdata = outdata.copy()
            bdata1 = saltio.readimage(struct, struct[hdu].header['BPMEXT'])
            bdata2 = saltio.readimage(struct, struct[hdu + 1].header['BPMEXT'])

        x1 = xdsec1[0] - 1
        if x1 != 0:
            msg = 'The data in %s have not been trimmed prior to mosaicking.' \
                  % infile
            log.error(msg)
        if xsh[i + 1] < 0:
            x1 += abs(xsh[i + 1] / xbin)
        x2 = x1 + xdsec1[1]
        y1 = ydsec1[0] - 1
        if ysh[i + 1] < 0:
            y1 += abs(ysh[i + 1] / ybin)
        y2 = y1 + ydsec1[1]
        outdata[y1:y2, x1:x2] =\
            imdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        if varframe:
            vardata[y1:y2, x1:x2] =\
                vdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]
            bpmdata[y1:y2, x1:x2] =\
                bdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        x1 = x2
        x2 = x1 + xdsec2[1]
        y1 = ydsec2[0] - 1
        if ysh[i + 1] < 0:
            y1 += abs(ysh[i + 1] / ybin)
        y2 = y1 + ydsec2[1]
        outdata[y1:y2, x1:x2] =\
            imdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        if varframe:
            vardata[y1:y2, x1:x2] =\
                vdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]
            bpmdata[y1:y2, x1:x2] =\
                bdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        # size of new image
        naxis1 = str(xdsec1[1] + xdsec2[1])
        naxis2 = str(ydsec1[1])

        # add image and keywords to HDU list
        tilehdu[i + 1] = fits.ImageHDU(outdata)
        tilehdu[i + 1].header = struct[hdu].header
        #tilehdu[
        #    i + 1].header['DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

        if varframe:
            vext = i + 1 + int(nsciext / 2.)
            tilehdu[vext] = fits.ImageHDU(vardata)
            #tilehdu[vext].header = struct[struct[hdu].header['VAREXT']].header
            #tilehdu[vext].header[
            #    'DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

            bext = i + 1 + 2 * int(nsciext / 2.)
            tilehdu[bext] = fits.ImageHDU(bpmdata)
            #tilehdu[bext].header = struct[struct[hdu].header['BPMEXT']].header
            #tilehdu[bext].header[
            #    'DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

        # image tile log message #1
        if log:
            message = os.path.basename(infile) + '[' + str(hdu) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + '] --> '
            message += os.path.basename(tilefile) + '[' + str(i + 1) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + ']'
            log.message(message, with_stdout=verbose, with_header=False)
            message = os.path.basename(infile) + '[' + str(hdu + 1) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + '] --> '
            message += os.path.basename(tilefile) + '[' + str(i + 1) + ']['
            message += str(xdsec1[1] + 1) + ':' + \
                str(xdsec1[1] + xdsec2[1]) + ','
            message += str(ydsec2[0]) + ':' + str(ydsec2[1]) + ']'
            log.message(message, with_stdout=verbose, with_header=False)

    # write temporary file of tiled CCDs
    hdulist = fits.HDUList(tilehdu)
    hdulist.writeto(tilefile)

    # iterate over CCDs, transform and rotate images
    yrot = [None] * 4
    xrot = [None] * 4

    tranfile = [' ']
    tranhdu = [0]
    if varframe:
        tranfile = [''] * (3 * int(nsciext / 2) + 1)
        tranhdu = [0] * (3 * int(nsciext / 2) + 1)
    else:
        tranfile = [''] * int(nsciext / 2 + 1)
        tranhdu = [0] * int(nsciext / 2 + 1)

    # this is hardwired for SALT where the second CCD is considered the
    # fiducial
    for hdu in range(1, int(nsciext / 2 + 1)):
        tranfile[hdu] = saltio.tmpfile(outpath)
        tranfile[hdu] += 'tran.fits'
        if varframe:
            tranfile[hdu + nccds] = saltio.tmpfile(outpath) + 'tran.fits'
            tranfile[hdu + 2 * nccds] = saltio.tmpfile(outpath) + 'tran.fits'

        ccd = hdu % nccds
        if (ccd == 0):
            ccd = nccds

        # correct rotation for CCD binning
        yrot[ccd] = rot[ccd] * ybin / xbin
        xrot[ccd] = rot[ccd] * xbin / ybin
        dxshift = xbin * int(float(int(gap) / xbin) + 0.5) - gap

        # transformation using geotran IRAF task
        # if (ccd == 1):
        if (ccd != 2):

            if geotran:
                message = '\nSALTMOSAIC -- geotran ' + tilefile + \
                    '[' + str(ccd) + '] ' + tranfile[hdu]
                message += ' \"\" \"\" xshift=' + \
                    str((xsh[ccd] + (2 - ccd) * dxshift) / xbin) + ' '
                message += 'yshift=' + \
                    str(ysh[ccd] / ybin) + ' xrotation=' + str(xrot[ccd]) + ' '
                message += 'yrotation=' + \
                    str(yrot[ccd]) + ' xmag=1 ymag=1 xmin=\'INDEF\''
                message += 'xmax=\'INDEF\' ymin=\'INDEF\' ymax=\'INDEF\' '
                message += 'ncols=\'INDEF\' '
                message += 'nlines=\'INDEF\' verbose=\'no\' '
                message += 'fluxconserve=\'yes\' nxblock=2048 '
                message += 'nyblock=2048 interpolant=\'' + \
                    interp_type + '\' boundary=\'constant\' constant=0'
                log.message(message, with_stdout=verbose)

                yd, xd = tilehdu[ccd].data.shape
                ncols = 'INDEF'  # ncols=xd+abs(xsh[ccd]/xbin)
                nlines = 'INDEF'  # nlines=yd+abs(ysh[ccd]/ybin)
                geo_xshift = xsh[ccd] + (2 - ccd) * dxshift / xbin
                geo_yshift = ysh[ccd] / ybin
                iraf.images.immatch.geotran(tilefile + "[" + str(ccd) + "]",
                                            tranfile[hdu],
                                            "",
                                            "",
                                            xshift=geo_xshift,
                                            yshift=geo_yshift,
                                            xrotation=xrot[ccd],
                                            yrotation=yrot[ccd],
                                            xmag=1, ymag=1, xmin='INDEF',
                                            xmax='INDEF', ymin='INDEF',
                                            ymax='INDEF', ncols=ncols,
                                            nlines=nlines, verbose='no',
                                            fluxconserve='yes', nxblock=2048,
                                            nyblock=2048, interpolant="linear",
                                            boundary="constant", constant=0)
                if varframe:
                    var_infile = tilefile + "[" + str(ccd + nccds) + "]"
                    iraf.images.immatch.geotran(var_infile,
                                                tranfile[hdu + nccds],
                                                "",
                                                "",
                                                xshift=geo_xshift,
                                                yshift=geo_yshift,
                                                xrotation=xrot[ccd],
                                                yrotation=yrot[ccd],
                                                xmag=1, ymag=1, xmin='INDEF',
                                                xmax='INDEF', ymin='INDEF',
                                                ymax='INDEF', ncols=ncols,
                                                nlines=nlines, verbose='no',
                                                fluxconserve='yes',
                                                nxblock=2048, nyblock=2048,
                                                interpolant="linear",
                                                boundary="constant",
                                                constant=0)
                    var2_infile = tilefile + "[" + str(ccd + 2 * nccds) + "]"
                    iraf.images.immatch.geotran(var2_infile,
                                                tranfile[hdu + 2 * nccds],
                                                "",
                                                "",
                                                xshift=geo_xshift,
                                                yshift=geo_yshift,
                                                xrotation=xrot[ccd],
                                                yrotation=yrot[ccd],
                                                xmag=1, ymag=1, xmin='INDEF',
                                                xmax='INDEF', ymin='INDEF',
                                                ymax='INDEF', ncols=ncols,
                                                nlines=nlines, verbose='no',
                                                fluxconserve='yes',
                                                nxblock=2048, nyblock=2048,
                                                interpolant="linear",
                                                boundary="constant",
                                                constant=0)

                # open the file and copy the data to tranhdu
                tstruct = fits.open(tranfile[hdu])
                tranhdu[hdu] = tstruct[0].data
                tstruct.close()
                if varframe:
                    tranhdu[
                        hdu +
                        nccds] = fits.open(
                        tranfile[
                            hdu +
                            nccds])[0].data
                    tranhdu[
                        hdu +
                        2 *
                        nccds] = fits.open(
                        tranfile[
                            hdu +
                            2 *
                            nccds])[0].data

            else:
                log.message(
                    "Transform CCD #%i using dx=%s, dy=%s, rot=%s" %
                    (ccd,
                     xsh[ccd] /
                        2.0,
                        ysh[ccd] /
                        2.0,
                        xrot[ccd]),
                    with_stdout=verbose,
                    with_header=False)
                tranhdu[hdu] = geometric_transform(
                    tilehdu[ccd].data,
                    tran_func,
                    prefilter=False,
                    order=1,
                    extra_arguments=(
                        xsh[ccd] / 2,
                        ysh[ccd] / 2,
                        1,
                        1,
                        xrot[ccd],
                        yrot[ccd]))
                tstruct = fits.PrimaryHDU(tranhdu[hdu])
                tstruct.writeto(tranfile[hdu])
                if varframe:
                    tranhdu[hdu + nccds] = geometric_transform(
                        tilehdu[hdu + 3].data,
                        tran_func,
                        prefilter=False,
                        order=1,
                        extra_arguments=(
                            xsh[ccd] / 2, ysh[ccd] / 2,
                            1, 1,
                            xrot[ccd], yrot[ccd]))
                    tranhdu[hdu + 2 * nccds] = geometric_transform(
                        tilehdu[hdu + 6].data,
                        tran_func,
                        prefilter=False,
                        order=1,
                        extra_arguments=(
                            xsh[ccd] / 2, ysh[ccd] / 2,
                            1, 1,
                            xrot[ccd], yrot[ccd]))

        else:
            log.message(
                "Transform CCD #%i using dx=%s, dy=%s, rot=%s" %
                (ccd, 0, 0, 0), with_stdout=verbose, with_header=False)
            tranhdu[hdu] = tilehdu[ccd].data
            if varframe:
                tranhdu[hdu + nccds] = tilehdu[ccd + nccds].data
                tranhdu[hdu + 2 * nccds] = tilehdu[ccd + 2 * nccds].data

    # open outfile
    if varframe:
        outlist = 4 * [None]
    else:
        outlist = 2 * [None]

    #outlist[0] = struct[0].copy()
    outlist[0] = fits.PrimaryHDU()
    outlist[0].header = struct[0].header

    naxis1 = int(gap / xbin * (nccds - 1))
    naxis2 = 0
    for i in range(1, nccds + 1):
        yw, xw = tranhdu[i].shape
        naxis1 += xw + int(abs(xsh[ccd] / xbin)) + 1
        naxis2 = max(naxis2, yw)
    outdata = numpy.zeros((naxis2, naxis1), numpy.float32)
    outdata.shape = naxis2, naxis1
    if varframe:
        vardata = outdata * 0
        bpmdata = outdata * 0 + 1

    # iterate over CCDs, stich them to produce a full image
    hdu = 0
    totxshift = 0
    for hdu in range(1, nccds + 1):

        # read DATASEC keywords
        ydsec, xdsec = tranhdu[hdu].shape

        # define size and shape of final image
        # tile CCDs to yield mosaiced image
        x1 = int((hdu - 1) * (xdsec + gap / xbin)) + int(totxshift)
        x2 = xdsec + x1
        y1 = int(0)
        y2 = int(ydsec)
        outdata[y1:y2, x1:x2] = tranhdu[hdu]
        totxshift += int(abs(xsh[hdu] / xbin)) + 1
        if varframe:
            vardata[y1:y2, x1:x2] = tranhdu[hdu + nccds]
            bpmdata[y1:y2, x1:x2] = tranhdu[hdu + 2 * nccds]

    # make sure to cover up all the gaps include bad areas
    if varframe:
        baddata = (outdata == 0)
        baddata = nd.maximum_filter(baddata, size=3)
        bpmdata[baddata] = 1
        

    # fill in the gaps if requested
    if fill:
        if varframe:
            outdata = fill_gaps(outdata, 0)
        else:
            outdata = fill_gaps(outdata, 0)

    # add to the file
    outlist[1] = fits.ImageHDU(outdata)
    if varframe:
        outlist[2] = fits.ImageHDU(vardata,name='VAR')
        outlist[3] = fits.ImageHDU(bpmdata,name='BPM')

    # create the image structure
    outstruct = fits.HDUList(outlist)

    # update the head informaation
    # housekeeping keywords
    saltkey.put('NEXTEND', 2, outstruct[0])
    saltkey.new('EXTNAME', 'SCI', 'Extension name', outstruct[1])
    saltkey.new('EXTVER', 1, 'Extension number', outstruct[1])
    if varframe:
        saltkey.new('VAREXT', 2, 'Variance frame extension', outstruct[1])
        saltkey.new('BPMEXT', 3, 'BPM Extension', outstruct[1])

    try:
        saltkey.copy(struct[1], outstruct[1], 'CCDSUM')
    except:
        pass

    # Add keywords associated with geometry
    saltkey.new('SGEOMGAP', gap, 'SALT Chip Gap', outstruct[0])
    c1str = '{:3.2f} {:3.2f} {:3.4f}'.format(xshift[0],
                                     yshift[0],
                                     rotation[0])
    saltkey.new('SGEOM1', c1str, 'SALT Chip 1 Transform', outstruct[0])
    c2str = '{:3.2f} {:3.2f} {:3.4f}'.format(xshift[1],
                                     yshift[1],
                                     rotation[1])
    saltkey.new('SGEOM2', c2str, 'SALT Chip 2 Transform', outstruct[0])

    # WCS keywords
    saltkey.new('CRPIX1', 0, 'WCS: X reference pixel', outstruct[1])
    saltkey.new('CRPIX2', 0, 'WCS: Y reference pixel', outstruct[1])
    saltkey.new(
        'CRVAL1',
        float(xbin),
        'WCS: X reference coordinate value',
        outstruct[1])
    saltkey.new(
        'CRVAL2',
        float(ybin),
        'WCS: Y reference coordinate value',
        outstruct[1])
    saltkey.new('CDELT1', float(xbin), 'WCS: X pixel size', outstruct[1])
    saltkey.new('CDELT2', float(ybin), 'WCS: Y pixel size', outstruct[1])
    saltkey.new('CTYPE1', 'pixel', 'X type', outstruct[1])
    saltkey.new('CTYPE2', 'pixel', 'Y type', outstruct[1])

    # cleanup temporary files
    if cleanup:
        for tfile in tranfile:
            if os.path.isfile(tfile):
                saltio.delete(tfile)
        if os.path.isfile(tilefile):
            status = saltio.delete(tilefile)

    # return the file
    return outstruct
Пример #14
0
def rectify(hdu, soldict, caltype='line', function='poly', order=3, inttype='interp', 
            w1=None, w2=None, dw=None, nw=None,
            blank=0, pixscale=0.0, time_interp=False, clobber=True, log=None, verbose=True):
   """Read in an image and a set of wavlength solutions.  Calculate the best
      wavelength solution for a given dataset and then apply that data set to the 
      image 

    return
   """
 
   #set the 
   set_w1=(w1 is  None)
   set_w2=(w2 is  None)
   set_dw=(dw is  None)
   set_nw=(nw is  None)

   #set up the time of the observation
   dateobs=saltkey.get('DATE-OBS', hdu[0])
   utctime=saltkey.get('TIME-OBS', hdu[0])
   exptime=saltkey.get('EXPTIME', hdu[0])
   instrume=saltkey.get('INSTRUME', hdu[0]).strip()
   grating=saltkey.get('GRATING', hdu[0]).strip()
   if caltype=='line':
      grang=saltkey.get('GRTILT', hdu[0])
      arang=saltkey.get('CAMANG', hdu[0])
   else:
      grang=saltkey.get('GR-ANGLE', hdu[0])
      arang=saltkey.get('AR-ANGLE', hdu[0])
   filtername=saltkey.get('FILTER', hdu[0]).strip()
   slitname=saltkey.get('MASKID', hdu[0])
   slit=st.getslitsize(slitname)
   xbin, ybin = saltkey.ccdbin( hdu[0])

   timeobs=enterdatetime('%s %s' % (dateobs, utctime))

   #check to see if there is more than one solution
   if caltype=='line':
    if len(soldict)==1:
      sol=soldict.keys()[0]
      slitid=None
      if not matchobservations(soldict[sol], instrume, grating, grang, arang, filtername, slitid):
         msg='Observations do not match setup for transformation but using the solution anyway'
         if log: log.warning(msg)

   for i in range(1,len(hdu)):
     if hdu[i].name=='SCI':
       if log: log.message('Correcting extension %i' % i)
       istart=int(0.5*len(hdu[i].data))
       #open up the data
       #set up the xarr and initial wavlength solution
       xarr=np.arange(len(hdu[i].data[istart]), dtype='int64')

       #get the slitid
       try:
          slitid=saltkey.get('SLITNAME', hdu[i])
       except:
          slitid=None
       #set up a wavelength solution
       try:
           w_arr=findsol(xarr, soldict, istart, caltype, timeobs, exptime, instrume, grating, grang, arang, filtername, 
              slit, xbin, ybin, slitid, function, order )
       except SALTSpecError, e:
           if slitid: 
              msg='SLITID %s: %s' % (slitid, e)
              if log: log.warning(msg)
              continue
           else:
              raise SALTSpecError(e)
 
       if w_arr is None: 
          w_arr=findsol(xarr, soldict, istart, 'rss', timeobs, exptime, instrume, grating, grang, arang, filtername, 
              slit, xbin, ybin, slitid, function, order )
  
       #set up the output x-axis

       if set_w1: w1=w_arr.min()
       if set_w2: w2=w_arr.max()
       if set_nw: nw=len(xarr)
       if set_dw: dw=float(w2-w1)/nw
       nw_arr=createoutputxaxis(w1, w2, nw)

       #setup the VARIANCE and BPM frames       
       if saltkey.found('VAREXT', hdu[i]):
           varext=saltkey.get('VAREXT', hdu[i])
       else:
           varext=None

       #setup the BPM frames       
       if saltkey.found('BPMEXT', hdu[i]):
           bpmext=saltkey.get('BPMEXT', hdu[i])
       else:
           bpmext=None

       #for each line in the data, determine the wavelength solution
       #for a given line in the image
       for j in range(len(hdu[i].data)):
           #find the wavelength solution for the data
           w_arr=findsol(xarr, soldict, j, caltype, timeobs, exptime, instrume, grating, grang, arang, filtername, 
              slit, xbin, ybin, slitid, function, order )

           #apply that wavelength solution to the data
           if w_arr is not None:
               try:
                  hdu[i].data[j,:]=st.interpolate(nw_arr, w_arr, hdu[i].data[j,:], inttype, left=blank, right=blank)
               except Exception, e:
                  hdu[i].data[j,:]=hdu[i].data[j,:]*0.0+blank
                  msg='In row %i, solution cannot be found due to %s' % (i, e)  

               #correct the variance frame
               if varext:
                   try:
                       hdu[varext].data[j,:]=st.interpolate(nw_arr, w_arr, hdu[varext].data[j,:], inttype, left=blank, right=blank)
                   except Exception, e:
                       msg='In row %i, solution cannot be found due to %s' % (i, e)  

               #correct the BPM frame
               if bpmext:
                   try:
                       hdu[bpmext].data[j,:]=st.interpolate(nw_arr, w_arr, hdu[bpmext].data[j,:], inttype, left=blank, right=blank)
                   except Exception, e:
                       msg='In row %i, solution cannot be found due to %s' % (i, e)  
Пример #15
0
def auto_arc_lens(arc_image, dbfile='wav.db', ndstep=20, logfile='salt.log'):
    """Automatically process an arc image for the SALT Lens project

    """
    hdu = fits.open(arc_image)
    hdr = hdu[0].header
    if hdr['LAMPID'] == 'Xe' and hdr['GRATING'] == 'PG0900' and hdr['GRTILT'] == 15.875:
        print('Automatically processing arc image')
        data = hdu[1].data
        ystart = int(0.5 * len(data))
        xarr = np.arange(len(data[ystart]), dtype='int64')
        farr = data[ystart]

        lampfile = os.path.dirname(__file__)+'/data/Xe.lens'
        guessfile = os.path.dirname(__file__)+'/data/lens.db'

        slines, sfluxes = st.readlinelist(lampfile)
        spectrum = Spectrum.Spectrum(
            slines, sfluxes, dw=0.1, stype='line', sigma=6)
        swarr = spectrum.wavelength
        sfarr = spectrum.flux * farr.max() / spectrum.flux.max()

        soldict = readsolascii(guessfile, {})
        soldict = (soldict[soldict.keys()[0]])
        ws = WavelengthSolution.WavelengthSolution(
             xarr, xarr, function=soldict[7], order=soldict[8])
        ws.func.func.domain = soldict[11]
        ws.set_coef(soldict[10][2])
 
        # start the pre processing
        dcoef = ws.coef * 0.0
        dcoef[0] = 0.05 * ndstep
        dcoef[1] = 0.01 * ws.coef[1]
        ws = st.findxcor(xarr, farr, swarr, sfarr, ws,
                         dcoef=dcoef, ndstep=ndstep, best=False, inttype='interp')
        xp, wp = st.crosslinematch(xarr, farr, slines, sfluxes, ws,
                                   res=6, mdiff=20, wdiff=10,
                                   sections=3, sigma=5, niter=5)
        ws = st.findfit(np.array(xp), np.array(wp), ws=ws, thresh=ws.thresh)
        print(ws)
        with logging(logfile, True) as log:
            iws = ai.AutoIdentify(xarr, data, slines, sfluxes, ws, farr=farr,
                      method='Matchlines', rstep=100, istart=ystart, nrows=1,
                      res=6, dres=0.25, mdiff=20, sigma=5,
                      smooth=3, niter=5, dc=5, ndstep=ndstep, 
                      oneline=False, log=log, verbose=True)

            # get the basic information about the spectrograph
            dateobs = saltkey.get('DATE-OBS', hdu[0])
            try:
                utctime = saltkey.get('UTC-OBS', hdu[0])
            except SaltError:
                utctime = saltkey.get('TIME-OBS', hdu[0])

            instrume = saltkey.get('INSTRUME', hdu[0]).strip()
            grating = saltkey.get('GRATING', hdu[0]).strip()
            grang = saltkey.get('GR-ANGLE', hdu[0])
            grasteps = saltkey.get('GRTILT', hdu[0])
            arang = saltkey.get('AR-ANGLE', hdu[0])
            arsteps = saltkey.get('CAMANG', hdu[0])
            rssfilter = saltkey.get('FILTER', hdu[0])
            specmode = saltkey.get('OBSMODE', hdu[0])
            masktype = saltkey.get('MASKTYP', hdu[0]).strip().upper()
            slitname = saltkey.get('MASKID', hdu[0])
            slit = st.getslitsize(slitname)
            xbin, ybin = saltkey.ccdbin(hdu[0], arc_image)
            writeIS(iws, dbfile, dateobs=dateobs, utctime=utctime, instrume=instrume,
                    grating=grating, grang=grang, grasteps=grasteps, arsteps=arsteps,
                    arang=arang, rfilter=rssfilter, slit=slit, xbin=xbin,
                    ybin=ybin, objid=None, filename=arc_image, log=log, verbose=True)
        print(iws)

        #self.findfit()

 
    else:
        lamp = hdr['LAMPID']
        lampfile=iraf.osfn("pysalt$data/linelists/%s.salt" % lamp)
        lampfile = 'Xe.lens'
        specidentify(arc_image, lampfile, dbfile, guesstype='rss', 
                  guessfile=None, automethod='Matchlines',  function='legendre',  order=3,
                  rstep=100, rstart='middlerow', mdiff=20, thresh=5, niter=5, smooth=3,
                  inter=True, clobber=True,  preprocess=True, logfile=logfile, verbose=True)
        print("Running specidenity in interactive mode")
Пример #16
0
def wavemap(hdu,
            soldict,
            caltype='line',
            function='poly',
            order=3,
            blank=0,
            nearest=False,
            array_only=False,
            clobber=True,
            log=None,
            verbose=True):
    """Read in an image and a set of wavlength solutions.  Calculate the best
       wavelength solution for a given dataset and then apply that data set to the
       image

     return
    """

    # set up the time of the observation
    dateobs = saltkey.get('DATE-OBS', hdu[0])
    utctime = saltkey.get('TIME-OBS', hdu[0])
    exptime = saltkey.get('EXPTIME', hdu[0])
    instrume = saltkey.get('INSTRUME', hdu[0]).strip()
    grating = saltkey.get('GRATING', hdu[0]).strip()
    if caltype == 'line':
        grang = saltkey.get('GRTILT', hdu[0])
        arang = saltkey.get('CAMANG', hdu[0])
    else:
        grang = saltkey.get('GR-ANGLE', hdu[0])
        arang = saltkey.get('AR-ANGLE', hdu[0])
    filtername = saltkey.get('FILTER', hdu[0]).strip()
    slitname = saltkey.get('MASKID', hdu[0])
    slit = st.getslitsize(slitname)
    xbin, ybin = saltkey.ccdbin(hdu[0])

    timeobs = sr.enterdatetime('%s %s' % (dateobs, utctime))

    # check to see if there is more than one solution
    if caltype == 'line':
        if len(soldict) == 1:
            sol = soldict.keys()[0]
            slitid = None
            if not sr.matchobservations(soldict[sol], instrume, grating, grang,
                                        arang, filtername, slitid):
                msg = 'Observations do not match setup for transformation but using the solution anyway'
                if log:
                    log.warning(msg)

    for i in range(1, len(hdu)):
        if hdu[i].name == 'SCI':
            if log:
                log.message('Correcting extension %i' % i)
            istart = int(0.5 * len(hdu[i].data))

            # open up the data
            # set up the xarr and initial wavlength solution
            xarr = np.arange(len(hdu[i].data[istart]), dtype='int64')

            # get the slitid
            try:
                slitid = saltkey.get('SLITNAME', hdu[i])
            except:
                slitid = None

            #check to see if wavext is already there and if so, then check update
            #that for the transformation from xshift to wavelength
            if saltkey.found('WAVEXT', hdu[i]):
                w_ext = saltkey.get('WAVEXT', hdu[i]) - 1
                wavemap = hdu[w_ext].data
                function, order, coef = sr.findlinesol(
                    soldict, istart, nearest, timeobs, exptime, instrume,
                    grating, grang, arang, filtername, slitid, xarr)
                ws = WavelengthSolution.WavelengthSolution(xarr,
                                                           xarr,
                                                           function=function,
                                                           order=order)
                ws.set_coef(coef)
                for j in range(len(hdu[i].data)):
                    wavemap[j, :] = ws.value(wavemap[j, :])
                if array_only: return wavemap
                hdu[w_ext].data = wavemap
                continue

            # set up a wavelength solution -- still in here for testing MOS data
            try:
                w_arr = sr.findsol(xarr, soldict, istart, caltype, nearest,
                                   timeobs, exptime, instrume, grating, grang,
                                   arang, filtername, slit, xbin, ybin, slitid,
                                   function, order)
            except SALTSpecError as e:
                if slitid:
                    msg = 'SLITID %s: %s' % (slitid, e)
                    if log:
                        log.warning(msg)
                    continue
                else:
                    raise SALTSpecError(e)

            if w_arr is None:
                w_arr = sr.findsol(xarr, soldict, istart, 'rss', nearest,
                                   timeobs, exptime, instrume, grating, grang,
                                   arang, filtername, slit, xbin, ybin, slitid,
                                   function, order)

            # for each line in the data, determine the wavelength solution
            # for a given line in the image
            wavemap = np.zeros_like(hdu[i].data)
            for j in range(len(hdu[i].data)):
                # find the wavelength solution for the data
                w_arr = sr.findsol(xarr, soldict, j, caltype, nearest, timeobs,
                                   exptime, instrume, grating, grang, arang,
                                   filtername, slit, xbin, ybin, slitid,
                                   function, order)
                if w_arr is not None: wavemap[j, :] = w_arr
            if array_only: return wavemap

            # write out the oimg
            hduwav = fits.ImageHDU(data=wavemap,
                                   header=hdu[i].header,
                                   name='WAV')
            hdu.append(hduwav)
            saltkey.new('WAVEXT',
                        len(hdu) - 1, 'Extension for Wavelength Map', hdu[i])

    return hdu
Пример #17
0
def identify(img, oimg, slines, sfluxes, guesstype, guessfile, function, order,
             rstep, interact, clobber, log, verbose):
    """For a given image, find the solution for each row in the file.  Use the appropriate first guess and
       guess type along with the appropriate function and order for the fit.

       Write out the new image with the solution in the headers and/or as a table in the multi-extension
       fits file

        returns the status
    """
    status = 0
    ImageSolution = {}
    dcstep = 3
    nstep = 50
    res = 2.0
    dres = 0.1
    centerrow = None
    nrows = 1
    sigma = 3
    niter = 5
    xdiff = 2 * res
    method = 'MatchZero'

    # Open up the image
    hdu = saltsafeio.openfits(img)

    # Read in important keywords

    # determine the central row and read it in
    try:
        data = hdu[1].data
        midline = int(0.5 * len(data))
        xarr = np.arange(len(data[midline]))
        specarr = data
    except Exception as e:
        message = 'Unable to read in data array in %s because %s' % (img, e)
        raise SALTSpecError(message)

    # determine the type of first guess.  Assumes none
    if guesstype == 'user':
        pass
    elif guesstype == 'rss':
        dateobs = saltsafekey.get('DATE-OBS', hdu[0], img)
        utctime = saltsafekey.get('UTC-OBS', hdu[0], img)
        instrume = saltsafekey.get('INSTRUME', hdu[0], img)
        grating = saltsafekey.get('GRATING', hdu[0], img)
        grang = saltsafekey.get('GR-ANGLE', hdu[0], img)
        arang = saltsafekey.get('AR-ANGLE', hdu[0], img)
        filter = saltsafekey.get('FILTER', hdu[0], img)
        slit = float(saltsafekey.get('MASKID', hdu[0], img))
        xbin, ybin = saltsafekey.ccdbin(hdu[0], img)
        # set up the rss model
        rssmodel = RSSModel.RSSModel(grating_name=grating.strip(),
                                     gratang=grang,
                                     camang=arang,
                                     slit=slit,
                                     xbin=xbin,
                                     ybin=ybin)
        rss = rssmodel.rss
        res = 1e7 * rss.calc_resolelement(rss.gratang,
                                          rss.gratang - rss.camang)

        if not instrume in ['PFIS', 'RSS']:
            msg = '%s is not a currently supported instrument' % instrume
            raise SALTSpecError(msg)
        ws = useRSSModel(xarr, rss, function=function, order=order)
    elif guesstype == 'image':
        pass
    else:
        ws = None

    # run in either interactive or non-interactive mode
    if interact:
        ImageSolution = InterIdentify(xarr,
                                      specarr,
                                      slines,
                                      sfluxes,
                                      ws,
                                      xdiff=xdiff,
                                      function=function,
                                      order=order,
                                      verbose=True)
    else:
        ImageSolution = AutoIdentify(xarr,
                                     specarr,
                                     slines,
                                     sfluxes,
                                     ws,
                                     rstep=rstep,
                                     method=method,
                                     icenter=centerrow,
                                     nrows=nrows,
                                     res=res,
                                     dres=dres,
                                     dc=dcstep,
                                     nstep=nstep,
                                     sigma=sigma,
                                     niter=niter,
                                     verbose=verbose)

    # set up the list of solutions to into an array
    key_arr = np.array(ImageSolution.keys())
    arg_arr = key_arr.argsort()
    ws_arr = np.zeros((len(arg_arr), len(ws.coef) + 1), dtype=float)

    # write the solution to an array
    for j, i in enumerate(arg_arr):
        if isinstance(ImageSolution[key_arr[i]],
                      WavelengthSolution.WavelengthSolution):
            ws_arr[j, 0] = key_arr[i]
            ws_arr[j, 1:] = ImageSolution[key_arr[i]].coef

    # write the solution as an file
    if outfile:
        # write header to the file that should include the order and function
        if os.path.isfile(outfile) and not clobber:
            dout = open(outfile, 'a')
        else:
            dout = open(outfile, 'w')

        msg = '#WS: Wavelength solution for image %s\n' % img
        msg += '#The following parameters were used in determining the solution:\n'
        msg += '#name=%s\n' % img
        msg += '#time-obs=%s %s\n' % (dateobs, utctime)
        msg += '#instrument=%s\n' % instrume
        msg += '#grating=%s\n' % grating.strip()
        msg += '#graang=%s\n' % grang
        msg += '#arang=%s\n' % arang
        msg += '#filter=%s\n' % filter.strip()
        msg += '#Function=%s\n' % function
        msg += '#Order=%s\n' % order
        msg += '#Starting Data\n'
        dout.write(msg)

        for i in range(len(ws_arr)):
            if ws_arr[i, 0]:
                msg = '%5.2f ' % ws_arr[i, 0]
                msg += ' '.join(['%e' % k for k in ws_arr[i, 1:]])
                dout.write(msg + '\n')
        dout.write('\n')
        dout.close()

    # write the solution as an extension
    hdu.close()

    return
Пример #18
0
def saltadvance(images, outpath, obslogfile=None, gaindb=None,xtalkfile=None, 
	geomfile=None,subover=True,trim=True,masbias=None, 
        subbias=False, median=False, function='polynomial', order=5,rej_lo=3,
        rej_hi=3,niter=5,interp='linear',  sdbhost='',sdbname='',sdbuser='', password='',
        clobber=False, cleanup=True, logfile='salt.log', verbose=True):
   """SALTADVANCE provides advanced data reductions for a set of data.  It will 
      sort the data, and first process the biases, flats, and then the science 
      frames.  It will record basic quality control information about each of 
      the steps.
   """
   plotover=False

   #start logging
   with logging(logfile,debug) as log:

       # Check the input images 
       infiles = saltio.argunpack ('Input',images)
       infiles.sort()

       # create list of output files 
       outpath=saltio.abspath(outpath)

       #log into the database
       sdb=saltmysql.connectdb(sdbhost, sdbname, sdbuser, password)

       #does the gain database file exist
       if gaindb:
           dblist= saltio.readgaindb(gaindb)
       else:
           dblist=[]

       # does crosstalk coefficient data exist
       if xtalkfile:
           xtalkfile = xtalkfile.strip()
           xdict = saltio.readxtalkcoeff(xtalkfile)
       else:
           xdict=None
       #does the mosaic file exist--raise error if no
       saltio.fileexists(geomfile)


       # Delete the obslog file if it already exists
       if os.path.isfile(obslogfile) and clobber: saltio.delete(obslogfile)

       #read in the obsveration log or create it
       if os.path.isfile(obslogfile):
           msg='The observing log already exists.  Please either delete it or run saltclean with clobber=yes'
           raise SaltError(msg)
       else:
           headerDict=obslog(infiles, log)
           obsstruct=createobslogfits(headerDict)
           saltio.writefits(obsstruct, obslogfile)

       #create the list of bias frames and process them
       filename=obsstruct.data.field('FILENAME')
       detmode=obsstruct.data.field('DETMODE')
       obsmode=obsstruct.data.field('OBSMODE')
       ccdtype=obsstruct.data.field('CCDTYPE')
       propcode=obsstruct.data.field('PROPID')
       masktype=obsstruct.data.field('MASKTYP')

       #set the bias list of objects
       biaslist=filename[(ccdtype=='ZERO')*(propcode=='CAL_BIAS')]
       masterbias_dict={}
       for img in infiles:
           if os.path.basename(img) in biaslist:
               #open the image
               struct=fits.open(img)
               bimg=outpath+'bxgp'+os.path.basename(img)

               #print the message
               if log:
                   message='Processing Zero frame %s' % img
                   log.message(message, with_stdout=verbose)

               #process the image
               struct=clean(struct, createvar=True, badpixelstruct=None, mult=True, 
                            dblist=dblist, xdict=xdict, subover=subover, trim=trim, subbias=False,
                            bstruct=None, median=median, function=function, order=order,
                            rej_lo=rej_lo, rej_hi=rej_hi, niter=niter, plotover=plotover, log=log,
                            verbose=verbose)
 
               #update the database
               updatedq(os.path.basename(img), struct, sdb)

               #write the file out
               # housekeeping keywords
               fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref'])
               saltkey.housekeeping(struct[0],'SPREPARE', 'Images have been prepared', hist)
               saltkey.new('SGAIN',time.asctime(time.localtime()),'Images have been gain corrected',struct[0])
               saltkey.new('SXTALK',time.asctime(time.localtime()),'Images have been xtalk corrected',struct[0])
               saltkey.new('SBIAS',time.asctime(time.localtime()),'Images have been de-biased',struct[0])

               # write FITS file
               saltio.writefits(struct,bimg, clobber=clobber)
               saltio.closefits(struct)

               #add files to the master bias list
               masterbias_dict=compareimages(struct, bimg, masterbias_dict, keylist=biasheader_list)

       #create the master bias frame
       for i in masterbias_dict.keys():
           bkeys=masterbias_dict[i][0]
           blist=masterbias_dict[i][1:]
           mbiasname=outpath+createmasterbiasname(blist, bkeys)
           bfiles=','.join(blist)
           saltcombine(bfiles, mbiasname, method='median', reject='sigclip', mask=False, 
                       weight=False, blank=0, scale=None, statsec=None, lthresh=3,    \
                       hthresh=3, clobber=False, logfile=logfile,verbose=verbose)

           

       #create the list of flatfields and process them
       flatlist=filename[ccdtype=='FLAT']
       masterflat_dict={}
       for img in infiles:
           if os.path.basename(img) in flatlist:
               #open the image
               struct=fits.open(img)
               fimg=outpath+'bxgp'+os.path.basename(img)

               #print the message
               if log:
                   message='Processing Flat frame %s' % img
                   log.message(message, with_stdout=verbose)

               #process the image
               struct=clean(struct, createvar=True, badpixelstruct=None, mult=True, 
                            dblist=dblist, xdict=xdict, subover=subover, trim=trim, subbias=False,
                            bstruct=None, median=median, function=function, order=order,
                            rej_lo=rej_lo, rej_hi=rej_hi, niter=niter, plotover=plotover, log=log,
                            verbose=verbose)

               #update the database
               updatedq(os.path.basename(img), struct, sdb)

               #write the file out
               # housekeeping keywords
               fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref'])
               saltkey.housekeeping(struct[0],'SPREPARE', 'Images have been prepared', hist)
               saltkey.new('SGAIN',time.asctime(time.localtime()),'Images have been gain corrected',struct[0])
               saltkey.new('SXTALK',time.asctime(time.localtime()),'Images have been xtalk corrected',struct[0])
               saltkey.new('SBIAS',time.asctime(time.localtime()),'Images have been de-biased',struct[0])

               # write FITS file
               saltio.writefits(struct,fimg, clobber=clobber)
               saltio.closefits(struct)

               #add files to the master bias list
               masterflat_dict=compareimages(struct, fimg, masterflat_dict,  keylist=flatheader_list)

       #create the master flat frame
       for i in masterflat_dict.keys():
           fkeys=masterflat_dict[i][0]
           flist=masterflat_dict[i][1:]
           mflatname=outpath+createmasterflatname(flist, fkeys)
           ffiles=','.join(flist)
           saltcombine(ffiles, mflatname, method='median', reject='sigclip', mask=False, 
                       weight=False, blank=0, scale=None, statsec=None, lthresh=3,    \
                       hthresh=3, clobber=False, logfile=logfile,verbose=verbose)

       #process the arc data
       arclist=filename[(ccdtype=='ARC') * (obsmode=='SPECTROSCOPY') * (masktype=='LONGSLIT')]
       for i, img in enumerate(infiles):
           nimg=os.path.basename(img)
           if nimg in arclist:
               #open the image
               struct=fits.open(img)
               simg=outpath+'bxgp'+os.path.basename(img)
               obsdate=os.path.basename(img)[1:9]

               #print the message
               if log:
                   message='Processing ARC frame %s' % img
                   log.message(message, with_stdout=verbose)


               struct=clean(struct, createvar=False, badpixelstruct=None, mult=True, 
                            dblist=dblist, xdict=xdict, subover=subover, trim=trim, subbias=False,
                            bstruct=None, median=median, function=function, order=order,
                            rej_lo=rej_lo, rej_hi=rej_hi, niter=niter, plotover=plotover, 
                            log=log, verbose=verbose)

               # write FITS file
               saltio.writefits(struct,simg, clobber=clobber)
               saltio.closefits(struct)

               #mosaic the images
               mimg=outpath+'mbxgp'+os.path.basename(img)
               saltmosaic(images=simg, outimages=mimg,outpref='',geomfile=geomfile,
                    interp=interp,cleanup=True,clobber=clobber,logfile=logfile,
                    verbose=verbose)

               #remove the intermediate steps
               saltio.delete(simg)


               #measure the arcdata
               arcimage=outpath+'mbxgp'+nimg
               dbfile=outpath+obsdate+'_specid.db'
               lamp = obsstruct.data.field('LAMPID')[i]
               lamp = lamp.replace(' ', '')
               lampfile = iraf.osfn("pysalt$data/linelists/%s.salt" % lamp)
               print arcimage, lampfile, os.getcwd()
               specidentify(arcimage, lampfile, dbfile, guesstype='rss', 
                                guessfile='', automethod='Matchlines', function='legendre',
                                order=3, rstep=100, rstart='middlerow', mdiff=20, thresh=3,
                                startext=0, niter=5, smooth=3, inter=False, clobber=True, logfile=logfile, 
                                verbose=verbose)
               try:
                   ximg = outpath+'xmbxgp'+os.path.basename(arcimage)
                   specrectify(images=arcimage, outimages=ximg, outpref='', solfile=dbfile, caltype='line',
                              function='legendre', order=3, inttype='interp', w1=None, w2=None, dw=None,
                              nw=None, blank=0.0, conserve=True, nearest=True, clobber=True,
                              logfile=logfile, verbose=verbose)
               except:
                   pass


              
       #process the science data
       for i, img in enumerate(infiles):
           nimg=os.path.basename(img)
           if not (nimg in flatlist or nimg in biaslist or nimg in arclist):
     
               #open the image
               struct=fits.open(img)
               if struct[0].header['PROPID'].count('CAL_GAIN'): continue
               simg=outpath+'bxgp'+os.path.basename(img)
   

               #print the message
               if log:
                   message='Processing science frame %s' % img
                   log.message(message, with_stdout=verbose)


               #Check to see if it is RSS 2x2 and add bias subtraction
               instrume=saltkey.get('INSTRUME', struct[0]).strip()
               gainset = saltkey.get('GAINSET', struct[0])    
               rospeed = saltkey.get('ROSPEED', struct[0])    
               target = saltkey.get('OBJECT', struct[0]).strip()
               exptime = saltkey.get('EXPTIME', struct[0])
               obsmode = saltkey.get('OBSMODE', struct[0]).strip()
               detmode = saltkey.get('DETMODE', struct[0]).strip()
               masktype = saltkey.get('MASKTYP', struct[0]).strip()
  
               
               xbin, ybin = saltkey.ccdbin( struct[0], img)
               obsdate=os.path.basename(img)[1:9]
               bstruct=None
               crtype=None
               thresh=5 
               mbox=11 
               bthresh=5.0,
               flux_ratio=0.2 
               bbox=25 
               gain=1.0 
               rdnoise=5.0 
               fthresh=5.0 
               bfactor=2
               gbox=3 
               maxiter=5
    
               subbias=False
               if instrume=='RSS' and gainset=='FAINT' and rospeed=='SLOW':
                   bfile='P%sBiasNM%ix%iFASL.fits' % (obsdate, xbin, ybin)
                   if os.path.exists(bfile):
                      bstruct=fits.open(bfile)
                      subbias=True
                   if detmode=='Normal' and target!='ARC' and xbin < 5 and ybin < 5:
                       crtype='edge' 
                       thresh=5 
                       mbox=11 
                       bthresh=5.0,
                       flux_ratio=0.2 
                       bbox=25 
                       gain=1.0 
                       rdnoise=5.0 
                       fthresh=5.0 
                       bfactor=2
                       gbox=3 
                       maxiter=3
    
               #process the image
               struct=clean(struct, createvar=True, badpixelstruct=None, mult=True, 
                            dblist=dblist, xdict=xdict, subover=subover, trim=trim, subbias=subbias,
                            bstruct=bstruct, median=median, function=function, order=order,
                            rej_lo=rej_lo, rej_hi=rej_hi, niter=niter, plotover=plotover, 
                            crtype=crtype,thresh=thresh,mbox=mbox, bbox=bbox,      \
                            bthresh=bthresh, flux_ratio=flux_ratio, gain=gain, rdnoise=rdnoise, 
                            bfactor=bfactor, fthresh=fthresh, gbox=gbox, maxiter=maxiter,
                            log=log, verbose=verbose)

               

               #update the database
               updatedq(os.path.basename(img), struct, sdb)

               #write the file out
               # housekeeping keywords
               fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref'])
               saltkey.housekeeping(struct[0],'SPREPARE', 'Images have been prepared', hist)
               saltkey.new('SGAIN',time.asctime(time.localtime()),'Images have been gain corrected',struct[0])
               saltkey.new('SXTALK',time.asctime(time.localtime()),'Images have been xtalk corrected',struct[0])
               saltkey.new('SBIAS',time.asctime(time.localtime()),'Images have been de-biased',struct[0])

               # write FITS file
               saltio.writefits(struct,simg, clobber=clobber)
               saltio.closefits(struct)

               #mosaic the files--currently not in the proper format--will update when it is
               if not saltkey.fastmode(saltkey.get('DETMODE', struct[0])):
                   mimg=outpath+'mbxgp'+os.path.basename(img)
                   saltmosaic(images=simg, outimages=mimg,outpref='',geomfile=geomfile,
                        interp=interp,fill=True, cleanup=True,clobber=clobber,logfile=logfile,
                        verbose=verbose)

                   #remove the intermediate steps
                   saltio.delete(simg)

               #if the file is spectroscopic mode, apply the wavelength correction
               if obsmode == 'SPECTROSCOPY' and masktype.strip()=='LONGSLIT':
                  dbfile=outpath+obsdate+'_specid.db'
                  try:
                     ximg = outpath+'xmbxgp'+os.path.basename(img)
                     specrectify(images=mimg, outimages=ximg, outpref='', solfile=dbfile, caltype='line', 
                              function='legendre', order=3, inttype='interp', w1=None, w2=None, dw=None,
                              nw=None, blank=0.0, conserve=True, nearest=True, clobber=True, 
                              logfile=logfile, verbose=verbose)
                  except Exception, e:
                     log.message('%s' % e)


       #clean up the results
       if cleanup:
          #clean up the bias frames
          for i in masterbias_dict.keys():
               blist=masterbias_dict[i][1:]
               for b in blist: saltio.delete(b)

          #clean up the flat frames
          for i in masterflat_dict.keys():
               flist=masterflat_dict[i][1:]
               for f in flist: saltio.delete(f)
Пример #19
0
def identify(img, oimg, slines, sfluxes, guesstype, guessfile, function, order, rstep, interact, clobber, log, verbose):
    """For a given image, find the solution for each row in the file.  Use the appropriate first guess and
       guess type along with the appropriate function and order for the fit.

       Write out the new image with the solution in the headers and/or as a table in the multi-extension
       fits file

        returns the status
    """
    status = 0
    ImageSolution = {}
    dcstep = 3
    nstep = 50
    res = 2.0
    dres = 0.1
    centerrow = None
    nrows = 1
    sigma = 3
    niter = 5
    xdiff = 2 * res
    method = "MatchZero"

    # Open up the image
    hdu = saltsafeio.openfits(img)

    # Read in important keywords

    # determine the central row and read it in
    try:
        data = hdu[1].data
        midline = int(0.5 * len(data))
        xarr = np.arange(len(data[midline]))
        specarr = data
    except Exception as e:
        message = "Unable to read in data array in %s because %s" % (img, e)
        raise SALTSpecError(message)

    # determine the type of first guess.  Assumes none
    if guesstype == "user":
        pass
    elif guesstype == "rss":
        dateobs = saltsafekey.get("DATE-OBS", hdu[0], img)
        utctime = saltsafekey.get("UTC-OBS", hdu[0], img)
        instrume = saltsafekey.get("INSTRUME", hdu[0], img)
        grating = saltsafekey.get("GRATING", hdu[0], img)
        grang = saltsafekey.get("GR-ANGLE", hdu[0], img)
        arang = saltsafekey.get("AR-ANGLE", hdu[0], img)
        filter = saltsafekey.get("FILTER", hdu[0], img)
        slit = float(saltsafekey.get("MASKID", hdu[0], img))
        xbin, ybin = saltsafekey.ccdbin(hdu[0], img)
        # set up the rss model
        rssmodel = RSSModel.RSSModel(
            grating_name=grating.strip(), gratang=grang, camang=arang, slit=slit, xbin=xbin, ybin=ybin
        )
        rss = rssmodel.rss
        res = 1e7 * rss.calc_resolelement(rss.gratang, rss.gratang - rss.camang)

        if not instrume in ["PFIS", "RSS"]:
            msg = "%s is not a currently supported instrument" % instrume
            raise SALTSpecError(msg)
        ws = useRSSModel(xarr, rss, function=function, order=order)
    elif guesstype == "image":
        pass
    else:
        ws = None

    # run in either interactive or non-interactive mode
    if interact:
        ImageSolution = InterIdentify(
            xarr, specarr, slines, sfluxes, ws, xdiff=xdiff, function=function, order=order, verbose=True
        )
    else:
        ImageSolution = AutoIdentify(
            xarr,
            specarr,
            slines,
            sfluxes,
            ws,
            rstep=rstep,
            method=method,
            icenter=centerrow,
            nrows=nrows,
            res=res,
            dres=dres,
            dc=dcstep,
            nstep=nstep,
            sigma=sigma,
            niter=niter,
            verbose=verbose,
        )

    # set up the list of solutions to into an array
    key_arr = np.array(ImageSolution.keys())
    arg_arr = key_arr.argsort()
    ws_arr = np.zeros((len(arg_arr), len(ws.coef) + 1), dtype=float)

    # write the solution to an array
    for j, i in enumerate(arg_arr):
        if isinstance(ImageSolution[key_arr[i]], WavelengthSolution.WavelengthSolution):
            ws_arr[j, 0] = key_arr[i]
            ws_arr[j, 1:] = ImageSolution[key_arr[i]].coef

    # write the solution as an file
    if outfile:
        # write header to the file that should include the order and function
        if os.path.isfile(outfile) and not clobber:
            dout = open(outfile, "a")
        else:
            dout = open(outfile, "w")

        msg = "#WS: Wavelength solution for image %s\n" % img
        msg += "#The following parameters were used in determining the solution:\n"
        msg += "#name=%s\n" % img
        msg += "#time-obs=%s %s\n" % (dateobs, utctime)
        msg += "#instrument=%s\n" % instrume
        msg += "#grating=%s\n" % grating.strip()
        msg += "#graang=%s\n" % grang
        msg += "#arang=%s\n" % arang
        msg += "#filter=%s\n" % filter.strip()
        msg += "#Function=%s\n" % function
        msg += "#Order=%s\n" % order
        msg += "#Starting Data\n"
        dout.write(msg)

        for i in range(len(ws_arr)):
            if ws_arr[i, 0]:
                msg = "%5.2f " % ws_arr[i, 0]
                msg += " ".join(["%e" % k for k in ws_arr[i, 1:]])
                dout.write(msg + "\n")
        dout.write("\n")
        dout.close()

    # write the solution as an extension
    hdu.close()

    return
Пример #20
0
def rectify(hdu, soldict, caltype='line', function='poly', order=3, inttype='interp',
            w1=None, w2=None, dw=None, nw=None, blank=0, pixscale=0.0, time_interp=False,
            conserve=False, nearest=False, clobber=True, log=None, verbose=True):
    """Read in an image and a set of wavlength solutions.  Calculate the best
       wavelength solution for a given dataset and then apply that data set to the
       image

     return
    """

    # set the basic values
    set_w1 = (w1 is None)
    set_w2 = (w2 is None)
    set_dw = (dw is None)
    set_nw = (nw is None)

    # set up the time of the observation
    dateobs = saltkey.get('DATE-OBS', hdu[0])
    utctime = saltkey.get('TIME-OBS', hdu[0])
    exptime = saltkey.get('EXPTIME', hdu[0])
    instrume = saltkey.get('INSTRUME', hdu[0]).strip()
    grating = saltkey.get('GRATING', hdu[0]).strip()
    if caltype == 'line':
        grang = saltkey.get('GRTILT', hdu[0])
        arang = saltkey.get('CAMANG', hdu[0])
    else:
        grang = saltkey.get('GR-ANGLE', hdu[0])
        arang = saltkey.get('AR-ANGLE', hdu[0])
    filtername = saltkey.get('FILTER', hdu[0]).strip()
    slitname = saltkey.get('MASKID', hdu[0])
    slit = st.getslitsize(slitname)
    xbin, ybin = saltkey.ccdbin(hdu[0])

    timeobs = enterdatetime('%s %s' % (dateobs, utctime))

    # check to see if there is more than one solution
    if caltype == 'line':
        if len(soldict) == 1:
            sol = soldict.keys()[0]
            slitid = None
            if not matchobservations(
                    soldict[sol], instrume, grating, grang, arang, filtername, slitid):
                msg = 'Observations do not match setup for transformation but using the solution anyway'
                if log:
                    log.warning(msg)

    for i in range(1, len(hdu)):
        if hdu[i].name == 'SCI':
            if log:
                log.message('Correcting extension %i' % i)
            istart = int(0.5 * len(hdu[i].data))
            # open up the data
            # set up the xarr and initial wavlength solution
            xarr = np.arange(len(hdu[i].data[istart]), dtype='int64')

            # get the slitid
            try:
                slitid = saltkey.get('SLITNAME', hdu[i])
            except:
                slitid = None
            # set up a wavelength solution
            try:
                w_arr = findsol(xarr, soldict, istart, caltype, nearest, timeobs, exptime, instrume, grating, grang, arang, filtername,
                                slit, xbin, ybin, slitid, function, order)
            except SALTSpecError as e:
                if slitid:
                    msg = 'SLITID %s: %s' % (slitid, e)
                    if log:
                        log.warning(msg)
                    continue
                else:
                    raise SALTSpecError(e)

            if w_arr is None:
                w_arr = findsol(xarr, soldict, istart, 'rss', nearest, timeobs, exptime, instrume, grating, grang, arang, filtername,
                                slit, xbin, ybin, slitid, function, order)

            # set up the output x-axis

            if set_w1:
                w1 = w_arr.min()
            if set_w2:
                w2 = w_arr.max()
            if set_nw:
                nw = len(xarr)
            if set_dw:
                dw = float(w2 - w1) / nw
            nw_arr = createoutputxaxis(w1, w2, nw)

            # setup the VARIANCE and BPM frames
            if saltkey.found('VAREXT', hdu[i]):
                varext = saltkey.get('VAREXT', hdu[i])
            else:
                varext = None

            # setup the BPM frames
            if saltkey.found('BPMEXT', hdu[i]):
                bpmext = saltkey.get('BPMEXT', hdu[i])
            else:
                bpmext = None

            # for each line in the data, determine the wavelength solution
            # for a given line in the image
            for j in range(len(hdu[i].data)):
                # find the wavelength solution for the data
                w_arr = findsol(xarr, soldict, j, caltype, nearest, timeobs, exptime, instrume, grating, grang, arang, filtername,
                                slit, xbin, ybin, slitid, function, order)

                # apply that wavelength solution to the data
                if w_arr is not None:
                    try:
                        hdu[i].data[
                            j,
                            :] = st.interpolate(
                            nw_arr,
                            w_arr,
                            hdu[i].data[
                                j,
                                :],
                            inttype,
                            left=blank,
                            right=blank)
                    except Exception as e:
                        hdu[i].data[j, :] = hdu[i].data[j, :] * 0.0 + blank
                        msg = 'In row %i, solution cannot be found due to %s' % (
                            i, e)

                    # correct the variance frame
                    if varext:
                        try:
                            hdu[varext].data[
                                j,
                                :] = st.interpolate(
                                nw_arr,
                                w_arr,
                                hdu[varext].data[
                                    j,
                                    :],
                                inttype,
                                left=blank,
                                right=blank)
                        except Exception as e:
                            msg = 'In row %i, solution cannot be found due to %s' % (
                                i, e)

                    # correct the BPM frame
                    if bpmext:
                        try:
                            hdu[bpmext].data[
                                j,
                                :] = st.interpolate(
                                nw_arr,
                                w_arr,
                                hdu[bpmext].data[
                                    j,
                                    :],
                                inttype,
                                left=blank,
                                right=blank)
                        except Exception as e:
                            msg = 'In row %i, solution cannot be found due to %s' % (
                                i, e)
                else:
                    hdu[i].data[j, :] = hdu[i].data[j, :] * 0.0 + blank

            if conserve:
                hdu[i].data = hdu[i].data / dw
                if varext:
                    hdu[varext].data = hdu[varext].data / dw

            # Add WCS information
            saltkey.new('CTYPE1', 'LAMBDA', 'Coordinate Type', hdu[i])
            saltkey.new('CTYPE2', 'PIXEL', 'Coordinate Type', hdu[i])
            saltkey.new(
                'CD1_1',
                dw,
                'WCS: Wavelength Dispersion in angstrom/pixel',
                hdu[i])
            saltkey.new('CD2_1', 0.0, 'WCS: ', hdu[i])
            saltkey.new('CD1_2', 0.0, 'WCS: ', hdu[i])
            saltkey.new('CD2_2', ybin * pixscale, 'WCS: ', hdu[i])
            saltkey.new('CRPIX1', 0.0, 'WCS: X Reference pixel', hdu[i])
            saltkey.new('CRPIX2', 0.0, 'WCS: Y Reference pixel', hdu[i])
            saltkey.new('CRVAL1', w1, 'WCS: X Reference pixel', hdu[i])
            saltkey.new('CRVAL2', 0.0, 'WCS: Y Reference pixel', hdu[i])
            saltkey.new('CDELT1', 1.0, 'WCS: X pixel size', hdu[i])
            saltkey.new('CDELT2', 1.0, 'WCS: Y pixel size', hdu[i])
            saltkey.new('DC-FLAG', 0, 'Dispesion Corrected image', hdu[i])

    return hdu
Пример #21
0
       message = 'Unable to read in data array in %s because %s' % (img, e)
       raise SALTSpecError(message)


   #determine the type of first guess.  Assumes none 
   if guesstype=='user':
       pass
   elif guesstype=='rss':
       dateobs=saltsafekey.get('DATE-OBS', hdu[0], img)
       utctime=saltsafekey.get('UTC-OBS', hdu[0], img)
       instrume=saltsafekey.get('INSTRUME', hdu[0], img)
       grating=saltsafekey.get('GRATING', hdu[0], img)
       grang=saltsafekey.get('GR-ANGLE', hdu[0], img)
       arang=saltsafekey.get('AR-ANGLE', hdu[0], img)
       filter=saltsafekey.get('FILTER', hdu[0], img)
       xbin, ybin = saltsafekey.ccdbin( hdu[0], img)
       if not instrume in ['PFIS', 'RSS']:
           msg='%s is not a currently supported instrument' % instrume
           raise SALTSpecError(msg)
       ws=useRSSModel(xarr, grating, grang, arang, xbin, function=function, order=order)
   elif guesstype=='image':
      pass
   else:
      ws=None

   #if interactive is selected launch the tool in interactive mode
   #if not, produce a wavelength solution from the information already
   #provided.
   xdiff=20
   ws= findwavelengthsolution(xarr, specarr, slines, sfluxes, ws, xdiff, function, 
                              order, zeropoint=False, interact=interact, verbose=verbose)
Пример #22
0
def specslit(image, outimage, outpref, exttype='auto', slitfile='', outputslitfile='',
             regprefix='', sections=3, width=25, sigma=2.2, thres=6, order=3, padding=5, yoffset=0,
             inter=False, clobber=True, logfile='salt.log', verbose=True):

    with logging(logfile, debug) as log:

        # check all the input and make sure that all the input needed is provided
        # by the user

        # read the image or image list and check if each in the list exist
        infiles = saltio.argunpack('Input', image)

        # unpack the outfiles
        outfiles = saltio.listparse(
            'Outimages',
            outimage,
            outpref,
            infiles,
            '')

        # from the extraction type, check whether the input file is specified.
        # if the slitfile parameter is specified then use the slit files for
        # the extraction. if the extraction type is auto then use image for the
        # detection and the slit extraction

        if exttype == 'rsmt' or exttype == 'fits' or exttype == 'ascii' or exttype == 'ds9':
            slitfiles = saltio.argunpack('Slitfile', slitfile)
            if len(slitfiles) == 1:
                slitfiles = slitfiles * len(infiles)
            saltio.comparelists(infiles, slitfiles, 'image', 'slitfile')
        elif exttype == 'auto':
            slitfiles = infiles
            log.message(
                'Extraction type is AUTO. Slit detection will be done from image')

        # read in if an optional ascii file is requested
        if len(outputslitfile) > 0:
            outslitfiles = saltio.argunpack('Outslitfiles', outputslitfile)
            saltio.comparelists(
                infiles,
                outslitfiles,
                'image',
                'outputslitfile')
        else:
            outslitfiles = [''] * len(infiles)

        # check if the width and sigma parameters were specified.
        # default is 25 and 2.2
        if width < 10.:
            msg = 'The width parameter needs be a value larger than 10'
            raise SALTSpecError(msg)

        if sigma < 0.0:
            msg = 'Sigma must be greater than zero'
            raise SaltSpecError(msg)

        # check the treshold parameter. this needs to be specified by the user
        if thres <= 0.0:
            msg = 'Threshold must be greater than zero'
            raise SaltSpecError(msg)

        # check to make sure that the sections are greater than the order
        if sections <= order:
            msg = 'Number of sections must be greater than the order for the spline fit'
            raise SaltSpecError(msg)

        # run through each of the images and extract the slits
        for img, oimg, sfile, oslit in zip(
                infiles, outfiles, slitfiles, outslitfiles):
            log.message('Proccessing image %s' % img)

            # open the image
            struct = saltio.openfits(img)
            ylen, xlen = struct[1].data.shape
            xbin, ybin = saltkey.ccdbin(struct[0], img)
            # setup the VARIANCE and BPM frames
            if saltkey.found('VAREXT', struct[1]):
                varext = saltkey.get('VAREXT', struct[1])
                varlist = []
            else:
                varext = None

            # setup the BPM frames
            if saltkey.found('BPMEXT', struct[1]):
                bpmext = saltkey.get('BPMEXT', struct[1])
                bpmlist = []
            else:
                bpmext = None

            # open the slit definition file or identify the slits in the image
            slitmask = None
            ycheck = False
            if exttype == 'rsmt':
                log.message('Using slits from %s' % sfile)
                if yoffset is None:
                   yoffset = 0 
                   ycheck = True
                slitmask = mt.read_slitmask_from_xml(sfile)
                xpos = -0.3066
                ypos = 0.0117
                cx = int(xlen / 2.0)
                cy = int(ylen / 2.0) + ypos / 0.015 / ybin + yoffset
                order, slit_positions = mt.convert_slits_from_mask(
                    slitmask, order=1, xbin=xbin, ybin=ybin, pix_scale=0.1267, cx=cx, cy=cy)
                sections = 1
            elif exttype == 'fits':
                log.message('Using slits from %s' % sfile)
                order, slit_positions = read_slits_from_fits(sfile)
            elif exttype == 'ascii':
                log.message('Using slits from %s' % sfile)
                order, slit_positions = mt.read_slits_from_ascii(sfile)
            elif exttype == 'ds9':
                log.message('Using slits from %s' % sfile)
                order, slit_positions, slitmask = mt.read_slits_from_ds9(
                    sfile, order=order)
                slitmask = None
                sections = 1
            elif exttype == 'auto':
                log.message('Identifying slits in %s' % img)
                # identify the slits in the image
                order, slit_positions = identify_slits(
                    struct[1].data, order, sections, width, sigma, thres)

                # write out the slit identifications if ofile has been supplied
                if oslit:
                    log.message('Writing slit positions to %s' % oslit)
                    mt.write_outputslitfile(slit_positions, oslit, order)

            if ycheck:
               slit_positions, dy = check_ypos(slit_positions, struct[1].data) 
               log.message('Using an offset of {}'.format(dy))

            # extract the slits
            spline_x = mt.divide_image(struct[1].data, sections)
            spline_x = 0.5 * (np.array(spline_x[:-1]) + np.array(spline_x[1:]))
            extracted_spectra, spline_positions = mt.extract_slits(slit_positions,
                                                                   spline_x, struct[1].data, order=order, padding=padding)
            if varext:
                extracted_var, var_positions = mt.extract_slits(slit_positions,
                                                                spline_x, struct[varext].data, order=order, padding=padding)
            if bpmext:
                extracted_bpm, bpm_positions = mt.extract_slits(slit_positions,
                                                                spline_x, struct[bpmext].data, order=order, padding=padding)

            # write out the data to the new array
            # create the new file
            hdulist = fits.HDUList([struct[0]])

            # log the extracted spectra if needed
            log.message('', with_stdout=verbose)

            # setup output ds9 file
            if regprefix:
                regout = open(
                    regprefix +
                    os.path.basename(img).strip('.fits') +
                    '.reg',
                    'w')
                regout.write('# Region file format: DS9 version 4.1\n')
                regout.write('# Filename: %s\n' % img)
                regout.write(
                    'global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1\nphysical\n')

            # add each
            imglist = []
            nslits = len(spline_positions)
            for i in range(nslits):
                y1 = spline_positions[i][0].min()
                y2 = spline_positions[i][1].max()
                msg = 'Extracted Spectra %i between %i to %i' % (i + 1, y1, y2)
                # log.message(msg, with_header=False, with_stdout=verbose)
                sdu = fits.ImageHDU(
                    extracted_spectra[i],
                    header=struct[1].header)
                if varext:
                    vdu = fits.ImageHDU(
                        extracted_var[i],
                        header=struct[varext].header)
                    sdu.header['VAREXT'] = i + nslits + 1
                    varlist.append(vdu)
                if bpmext:
                    bdu = fits.ImageHDU(
                        extracted_bpm[i],
                        header=struct[bpmext].header)
                    sdu.header['BPMEXT']= i + 2 * nslits + 1
                    bpmlist.append(bdu)
                imglist.append(sdu)

                # add in some additional keywords
                imglist[i].header['MINY'] = (y1,
                    'Lower Y value in original image')
                imglist[i].header['MAXY'] = (y2,
                    'Upper Y value in original image')
                if regprefix:
                    xsize = struct[1].data.shape[1]
                    xsize = int(0.5 * xsize)
                    rtext = ''
                    if slitmask:
                        # rtext='%s, %8.7f, %8.7f, %3.2f' % (slitmask.slitlets.data[i]['name'], slitmask.slitlets.data[i]['targ_ra'], slitmask.slitlets.data[i]['targ_dec'], slitmask.slitlets.data[i]['slit_width'])
                        pass
                    regout.write('box(%i,%i, %i, %i) #text={%s}\n' % (
                        xsize, 0.5 * (y1 + y2), 2 * xsize, y2 - y1, rtext))

                # add slit information
                if slitmask:
                    imglist[i].header['SLITNAME'] = (slitmask.slitlets.data[i]['name'],
                        'Slit Name')
                    imglist[i].header['SLIT_RA'] = (slitmask.slitlets.data[i]['targ_ra'],
                        'Slit RA')
                    imglist[i].header['SLIT_DEC'] = (slitmask.slitlets.data[i]['targ_dec'],
                        'Slit DEC')
                    imglist[i].header['SLIT'] = (slitmask.slitlets.data[i]['slit_width'],
                        'Slit Width')

            # add to the hdulist
            hdulist += imglist
            if varext:
                hdulist += varlist
            if bpmext:
                hdulist += bpmlist

            # write the slit positions to the header
            # create the binary table HDU that contains the split positions
            tbhdu = mt.slits_HDUtable(slit_positions, order)
            bintable_hdr = tbhdu.header

            # add the extname parameter to the extension
            tbhdu.header['EXTNAME'] = 'BINTABLE'

            # add the extname parameter to the extension
            hdulist[0].header['SLITEXT'] = len(hdulist)
            hdulist.append(tbhdu)

            # add addition header information about the mask
            if slitmask:
                hdulist[0].header['MASKNAME'] = (slitmask.mask_name, 'SlitMask Name')
                hdulist[0].header['MASK_RA'] = (slitmask.center_ra,
                    'SlitMask RA')
                hdulist[0].header['MASK_DEC'] = ( slitmask.center_dec,
                    'SlitMask DEC')
                hdulist[0].header['MASK_PA'] = ( slitmask.position_angle,
                    'SlitMask Position Angle')

            # write out the image
            saltio.writefits(hdulist, oimg, clobber)
Пример #23
0
def prepare(hdu):
    """Prepare HRS data to be similar to other SALT file formats
       This includes splitting each amplifier into multi-extension
       formats 
    """

    #set the detector
    detname=saltkey.get('DETNAM', hdu[0])

    if detname=='08443-03-01' or detname=='HRDET':
       detector='hrdet'
    elif detname=='04434-23-02' or detname=='HBDET':
       detector='hbdet'
    else:
       raise SaltError('%s is not an HRS detector' % detnam)

    #get key parameters
    try:
        nccd=saltkey.get('CCDNAMPS', hdu[0])
    except:
        nccd=saltkey.get('CCDAMPS', hdu[0])
    xbin, ybin=saltkey.ccdbin(hdu[0])
    gain=saltkey.get('GAIN', hdu[0])
    gain=gain.split()
    rospeed=saltkey.get('ROSPEED', hdu[0])
    ccdshape=hdu[0].data.shape

    #create a multiexention fits file
    phdu=pyfits.PrimaryHDU()
    phdu.header=hdu[0].header
 
    nhdu = pyfits.HDUList(phdu)

    #these keywords need to be added
    saltkey.new('DETMODE', value='Normal', comment='Detector mode', hdu=nhdu[0])
    saltkey.new('NCCDS', value=1, comment='Detector mode', hdu=nhdu[0])
    saltkey.new('GAINSET', value='SLOW', comment='Detector mode', hdu=nhdu[0])
    value='OBJECT'
    if hdu[0].header['OBJECT']=='Bias': value='ZERO'
    if hdu[0].header['OBJECT']=='Arc': value='ARC'
    if hdu[0].header['OBJECT']=='Flat': value='FLAT'
    saltkey.new('CCDTYPE', value=value, comment='CCD Type', hdu=nhdu[0])
 
    if nccd==1:
        nhdu.append(pyfits.ImageHDU(hdu[0].data))
        j=1
        saltkey.new('GAIN', value=float(gain[0]), comment='Nominal CCD gain (e/ADU)', hdu=nhdu[j])
        saltkey.new('RDNOISE', value=0, comment='Nominal readout noise in e', hdu=nhdu[j])
        saltkey.new('SATURATE', value=1, comment='Pixel saturation level in ADU', hdu=nhdu[j])
        saltkey.new('XTALK',  value=0.0,  comment='Cross talk coefficient', hdu=nhdu[j])

        detsize=getdetsize(ccdshape, xbin, ybin) 
        ampshape=nhdu[j].data.shape
        ampsec=getdetsize(ccdshape, 1, 1)
        saltkey.new('DETSIZE',  value=detsize,  comment='Detector size', hdu=nhdu[j])
        saltkey.new('BIASSEC',  value=getbiassec(j, ampshape, xbin, ybin),  comment='Bias section', hdu=nhdu[j])
        saltkey.new('DATASEC',  value=getdatasec(j, ampshape, xbin, ybin),  comment='Data section', hdu=nhdu[j])
        saltkey.new('AMPSEC',  value=ampsec,  comment='Amplifier section', hdu=nhdu[j])
        saltkey.new('CCDSEC',  value=detsize,  comment='CCD section', hdu=nhdu[j])
        saltkey.new('DETSEC',  value=detsize,  comment='Detector section', hdu=nhdu[j])
      
        return nhdu


    for i in range(nccd):
        j=i+1
        x1,x2,y1,y2=definesection(j, detector, ccdshape)
        nhdu.append(pyfits.ImageHDU(hdu[0].data[y1:y2,x1:x2]))
        #keywords that need to be added include
        #gain, rdnoise, xtalk, saturate, 

        saltkey.new('GAIN', value=float(gain[i]), comment='Nominal CCD gain (e/ADU)', hdu=nhdu[j])
        saltkey.new('RDNOISE', value=0, comment='Nominal readout noise in e', hdu=nhdu[j])
        saltkey.new('SATURATE', value=1, comment='Pixel saturation level in ADU', hdu=nhdu[j])
        saltkey.new('XTALK',  value=0.0,  comment='Cross talk coefficient', hdu=nhdu[j])

        #DETSIZE, BIASSEC, DATASEC, 
        #AMPSEC, CCDSEC, DETSEC
        ampsec='[%i:%i,%i:%i]' % (x1+1,x2,y1+1,y2)
        ampshape=nhdu[j].data.shape
        saltkey.new('DETSIZE',  value=getdetsize(ccdshape, xbin, ybin),  comment='Detector size', hdu=nhdu[j])
        saltkey.new('BIASSEC',  value=getbiassec(j, ampshape, xbin, ybin),  comment='Bias section', hdu=nhdu[j])
        saltkey.new('DATASEC',  value=getdatasec(j, ampshape, xbin, ybin),  comment='Data section', hdu=nhdu[j])
        saltkey.new('AMPSEC',  value=ampsec,  comment='Amplifier section', hdu=nhdu[j])
        saltkey.new('CCDSEC',  value=getdetsize(ccdshape, xbin, ybin),  comment='CCD section', hdu=nhdu[j])
        saltkey.new('DETSEC',  value=getdetsize(ccdshape, xbin, ybin),  comment='Detector section', hdu=nhdu[j])

        #BSCALE, BZERO
        #nhdu[j].header.set('BSCALE', value=1.0, comment='Val=BSCALE*pix+BZERO')
        #nhdu[j].header.set('BZERO',  value=32768.,  comment='Val=BSCALE*pix+BZERO')
     
        #ATM1_1, ATM2_2, 
        #not implimented

    return nhdu