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)
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
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
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)