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
def rssinfo(grating, grang, arang, slitname, xbin, ybin): """RSSINFO--Given informtion about the set up of the spectrograph, return information about the spectrograph grating--name of the grating used gratang--angle of the grating in degrees arang--articulation ange in degrees slitname--name of the slit being used xbin--binning in x-direction ybin--binning in y-direction returns central wavelength, blue wavelength, red wavelenth, resolution resolution element """ #get the slitsize slit=getslitsize(slitname) #set up the rss model rss=RSSModel.RSSModel(grating_name=grating, gratang=grang, \ camang=arang,slit=slit, xbin=xbin, ybin=ybin) #calcuation the resolution element res=1e7*rss.calc_resolelement(rss.alpha(), -rss.beta()) #calculate the central wavelength wcen=1e7*rss.calc_centralwavelength() #calculate the wavelength edges w2=1e7*rss.calc_bluewavelength() w1=1e7*rss.calc_redwavelength() print w1,w2 #calculate the R=rss.calc_resolution(wcen/1e7, rss.alpha(), rss.beta()) return wcen, w1, w2, res, R, slit
def rssinfo(grating, grang, arang, slitname, xbin, ybin): """RSSINFO--Given informtion about the set up of the spectrograph, return information about the spectrograph grating--name of the grating used gratang--angle of the grating in degrees arang--articulation ange in degrees slitname--name of the slit being used xbin--binning in x-direction ybin--binning in y-direction returns central wavelength, blue wavelength, red wavelenth, resolution resolution element """ #get the slitsize slit = getslitsize(slitname) #set up the rss model rss=RSSModel.RSSModel(grating_name=grating, gratang=grang, \ camang=arang,slit=slit, xbin=xbin, ybin=ybin) #calcuation the resolution element res = 1e7 * rss.calc_resolelement(rss.alpha(), -rss.beta()) #calculate the central wavelength wcen = 1e7 * rss.calc_centralwavelength() #calculate the wavelength edges w2 = 1e7 * rss.calc_bluewavelength() w1 = 1e7 * rss.calc_redwavelength() print w1, w2 #calculate the R = rss.calc_resolution(wcen / 1e7, rss.alpha(), rss.beta()) return wcen, w1, w2, res, R, slit
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
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)
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 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)
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")
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)