def telluric(iname, oname, cal, dscale=0.0): """ call iraf command telluric. if output file already exist, this function will delete the old one. iname : input file name type : string oname : output file name type : string cal : calibration file name type : string """ if os.path.isfile(oname): print('remove file ' + oname) os.remove(oname) iraf.telluric(input=iname, output=oname, cal=cal, ignoreaps='Yes', xcorr='Yes', tweakrms='Yes', interactive='Yes', sample='*', threshold=0.0, lag=10, shift=0.0, scale=1.0, dshift=1.0, dscale=dscale, offset=1.0, smooth=1, cursor='', airmass='', answer='yes')
def lris_standard(standards, xcorr=yes): '''Extract standard stars and calculate sensitivity functions.''' for ofile, nstd in standards: shutil.copy(ofile, "%s.fits" % nstd) # Extract standard if get_head("%s.fits" % nstd, "SKYSUB"): iraf.apall(nstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none") else: iraf.apall(nstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit") if xcorr: # Cross correlate to tweak wavelength iraf.xcsao("%s.ms" % nstd, templates=XCTEMPLATE, correlate="wavelength", logfiles="%s.xcsao" % ofile) # If a solution was found, apply shift try: xcsaof = open("%s.xcsao" % ofile) shift = float(xcsaof.readlines()[6].split()[14]) except: shift = 0.0 iraf.specshift("%s.ms" % nstd, -shift) # Create telluric iraf.splot("%s.ms" % nstd) # Remove telluric and absorption, save as a%s.ms iraf.sarith("%s.ms" % nstd, "/", "a%s.ms" % nstd, "telluric.%s.fits" % nstd) iraf.imreplace("telluric.%s.fits" % nstd, 1.0, lower=0.0, upper=0.0) iraf.splot("telluric.%s.fits" % nstd) # Remove stellar features and resave # Create smoothed standard iraf.gauss("a%s.ms[*,1,1]" % nstd, "s%s.ms" % nstd, 5.0) iraf.sarith("%s.ms" % nstd, "/", "s%s.ms" % nstd, "ds%s.ms" % nstd) # Apply telluric correction iraf.telluric("ds%s.ms" % nstd, "tds%s.ms" % nstd, "telluric.%s.fits" % nstd, xcorr=no, tweakrms=no, interactive=no, sample='4000:4010,6850:6975,7150:7350,7575:7725,8050:8400,8900:9725') # Define bandpasses for standard star calculation obj=get_head("%s.fits" % nstd, "OBJECT") iraf.standard("tds%s.ms" % nstd, "%s.std" % nstd, extinction='home$extinct/maunakeaextinct.dat', caldir='home$standards/', observatory='Keck', interac=yes, star_name=obj, airmass='', exptime='') # Determine sensitivity function iraf.sensfunc('%s.std' % nstd, '%s.sens' % nstd, extinction='home$extinct/maunakeaextinct.dat', newextinction='extinct.dat', observatory='Keck', function='legendre', order=4, interactive=yes) return
def vega(spectrum, band, path, hlineinter, telluric_shift_scale_record, log, over, airmass=1.0): """ Use iraf.telluric to remove H lines from standard star, then remove normalization added by telluric with iraf.imarith. The extension for vega_ext.fits is specified from band (from header of telluricfile.fits). Args: spectrum (string): filename from 'telluricfile'. band: from telluricfile .fits header. Eg 'K', 'H', 'J'. path: usually top directory with Nifty scripts. hlineinter (boolean): Interactive H line fitting. Specified with -i at command line. Default False. airmass: from telluricfile .fits header. telluric_shift_scale_record: "pointer" to telluric_hlines.txt. log: path to logfile. over (boolean): overwrite old files. Specified at command line. """ if band=='K': ext = '1' sample = "21537:21778" scale = 0.8 if band=='H': ext = '2' sample = "16537:17259" scale = 0.7 if band=='J': ext = '3' sample = "11508:13492" scale = 0.885 if band=='Z': ext = '4' sample = "*" scale = 0.8 if os.path.exists("tell_nolines.fits"): if over: os.remove("tell_nolines.fits") tell_info = iraf.telluric(input=spectrum+"[1]", output='tell_nolines', cal= RUNTIME_DATA_PATH+'vega_ext.fits['+ext+']', xcorr='yes', tweakrms='yes', airmass=airmass, inter=hlineinter, sample=sample, threshold=0.1, lag=3, shift=0., dshift=0.05, scale=scale, dscale=0.05, offset=0., smooth=1, cursor='', mode='al', Stdout=1) else: logging.info("Output file exists and -over not set - skipping H line correction") else: tell_info = iraf.telluric(input=spectrum+"[1]", output='tell_nolines', cal= RUNTIME_DATA_PATH+'vega_ext.fits['+ext+']', xcorr='yes', tweakrms='yes', inter=hlineinter, airmass=airmass, sample=sample, threshold=0.1, lag=3, shift=0., dshift=0.05, scale=scale, dscale=0.05, offset=0., smooth=1, cursor='', mode='al', Stdout=1) # need this loop to identify telluric output containing warning about pix outside calibration limits (different formatting) if "limits" in tell_info[-1].split()[-1]: norm=tell_info[-2].split()[-1] else: norm=tell_info[-1].split()[-1] if os.path.exists("final_tel_no_hlines_no_norm.fits"): if over: os.remove("final_tel_no_hlines_no_norm.fits") iraf.imarith(operand1='tell_nolines', op='/', operand2=norm, result='final_tel_no_hlines_no_norm', title='', divzero=0.0, hparams='', pixtype='', calctype='', verbose='yes', noact='no', mode='al') else: logging.info("Output file exists and -over not set - skipping H line normalization") else: iraf.imarith(operand1='tell_nolines', op='/', operand2=norm, result='final_tel_no_hlines_no_norm', title='', divzero=0.0, hparams='', pixtype='', calctype='', verbose='yes', noact='no', mode='al')
def red_science(image, flats, spath, object=None, arc='Arc-Red.fits', smooth='BD284211.smooth.fits', telluric='telluric.fits', sens='BD284211.sens', biassec=REDBIAS, trimsec=REDTRIM, outflat='Flat-Red.fits', gain=REDGAIN, rdnoise=REDRDNOISE): '''Full reduction of KAST science spectra on red CCD''' # Bias subtract everything first redbias(image, biassec=biassec, trimsec=trimsec) redbias(flats, biassec=biassec, trimsec=trimsec) # Create and apply flat-field make_flat(flats, outflat, gain=gain, rdnoise=rdnoise) iraf.ccdproc(image[0], ccdtype='', noproc=no, fixpix=no, overscan=no, trim=no, zerocor=no, darkcor=no, flatcor=yes, illumcor=no, fringecor=no, readcor=no, scancor=no, flat=outflat) # Cosmic ray rejection #iraf.lacos_spec(image[0], 'c%s' % image[0], 'cm%s' % image[0], # gain=gain, readn=rdnoise, xorder=9, yorder=3, # sigclip=4.5, sigfrac=0.5, objlim=1.0, niter=3) # Extract spectrum if object==None: object=get_head(image, 'OBJECT') iraf.apall('%s' % image[0], output=object, references='', interactive=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background='fit', weights='variance', pfit='fit1d', readnoise=rdnoise, gain=gain) # Apply wavelength solution to standard shutil.copy('%s/%s' % (spath, arc), '.') shutil.copy('%s/database/id%s' % (spath, arc.rstrip('.fits')), 'database') iraf.refspec(object, references=arc, sort="", group="", override=yes, confirm=no, assign=yes) iraf.dispcor(object, '%s.w' % object, confirm=no, listonly=no) # Smooth shutil.copy('%s/%s' % (spath, smooth), '.') iraf.sarith('%s.w' % object, '/', smooth, '%s.s' % object) # Create and apply telluric correction shutil.copy('%s/%s' % (spath, telluric), '.') iraf.telluric('%s.s' % object, '%s.t' % object, telluric, xcorr=yes, tweakrms=yes, interactive=yes, sample='6850:6950,7575:7700') # Flux calibration shutil.copy('%s/%s.0001.fits' % (spath, sens), '.') iraf.calibrate('%s.t' % object, '%s.f' % object, extinct=yes, flux=yes, extinction='onedstds$kpnoextinct.dat', observatory='Lick', sensitivity=sens, airmass='', exptime='') return
def tell_corr(imgID): #tell_rootname = '%s%04d' % (side, telluric_cal_id) #tell_rootname = 'norm_red.std.fits' #if not os.path.exists('norm_red.std.fits'): #iraf.splot('red') iraf.unlearn('telluric') rootname = 'red%04d' % (imgID) iraf.telluric.input = rootname + '_flux.spec.fits' iraf.telluric.output = rootname + '_flux_cor.spec.fits' iraf.telluric.sample = "6277:6288,6860:7000,7584:7678,9252:9842" iraf.telluric.interactive = "yes" iraf.telluric.cal = 'norm_red.std.fits' iraf.telluric.ignoreaps = 'yes' iraf.telluric.xcorr = 'yes' iraf.telluric.tweakrms = 'yes' iraf.telluric.threshold = 0.01 iraf.telluric()
def vega(rawFrame, grating, hLineInter, log, over): """ Use iraf.telluric to remove H lines from standard star, then remove normalization added by telluric with iraf.imarith. The extension for vega_ext.fits is specified from grating (from header of telluricfile.fits). Args: """ if grating == 'K': ext = '1' sample = "21537:21778" scale = 0.8 elif grating == 'H': ext = '2' sample = "16537:17259" scale = 0.7 elif grating == 'J': ext = '3' sample = "11508:13492" scale = 0.885 elif grating == 'Z': ext = '4' sample = "*" scale = 0.8 else: logging.info( "\nWARNING: invalid standard star band. Exiting this correction.") return if os.path.exists("1_htel" + rawFrame + ".fits"): if over: os.remove("1_htel" + rawFrame + ".fits") iraf.chdir(os.getcwd()) tell_info = iraf.telluric(input="0_tel" + rawFrame + ".fits[1]", output="1_htel" + rawFrame, cal=RUNTIME_DATA_PATH + 'vega_ext.fits[' + ext + ']', xcorr='yes', tweakrms='yes', airmass=1.0, inter=hLineInter, sample=sample, threshold=0.1, lag=3, shift=0., dshift=0.05, scale=scale, dscale=0.05, offset=0., smooth=1, cursor='', mode='al', Stdout=1) else: logging.info( "Output file exists and -over not set - skipping H line correction" ) return else: iraf.chdir(os.getcwd()) tell_info = iraf.telluric(input="0_tel" + rawFrame + ".fits[1]", output="1_htel" + rawFrame, cal=RUNTIME_DATA_PATH + 'vega_ext.fits[' + ext + ']', xcorr='yes', tweakrms='yes', airmass=1.0, inter=hLineInter, sample=sample, threshold=0.1, lag=3, shift=0., dshift=0.05, scale=scale, dscale=0.05, offset=0., smooth=1, cursor='', mode='al', Stdout=1) # need this loop to identify telluric output containing warning about pix outside calibration limits (different formatting) if "limits" in tell_info[-1].split()[-1]: norm = tell_info[-2].split()[-1] else: norm = tell_info[-1].split()[-1] if os.path.exists("final_tel_no_hLines_no_norm.fits"): if over: # Subtle bugs in iraf mean imarith doesn't work. So we use an astropy/numpy solution. # Open the image and the scalar we will be dividing it by. operand1 = astropy.io.fits.open("1_htel" + rawFrame + '.fits')[0].data operand2 = float(norm) # Create a new data array multiplied = np.array(operand1, copy=True) # Don't forget to include the original header! If you don't later IRAF tasks get confused. header = astropy.io.fits.open("1_htel" + rawFrame + '.fits')[0].header for i in range(len(multiplied)): if operand2 != 0: multiplied[i] = operand1[i] / operand2 else: multiplied[i] = 1 # Set the data and header of the in-memory image hdu = astropy.io.fits.PrimaryHDU(multiplied) hdu.header = header # Finally, write the new image to a new .fits file. It only has one extension; zero, with a header and data. hdu.writeto('final_tel_no_hLines_no_norm.fits') #iraf.imarith(operand1="1_htel" + rawFrame, op='/', operand2=norm, result='final_tel_no_hLines_no_norm', title='', divzero=0.0, hparams='', pixtype='', calctype='', verbose='yes', noact='no', mode='al') else: logging.info( "Output file exists and -over not set - skipping H line normalization correction" ) else: #iraf.imarith(operand1="1_htel" + rawFrame, op='/', operand2=norm, result='final_tel_no_hLines_no_norm', title='', divzero=0.0, hparams='', pixtype='', calctype='', verbose='yes', noact='no', mode='al') operand1 = astropy.io.fits.open("1_htel" + rawFrame + '.fits')[0].data operand2 = float(norm) multiplied = np.array(operand1, copy=True) header = astropy.io.fits.open("1_htel" + rawFrame + '.fits')[0].header for i in range(len(multiplied)): if operand2 != 0: multiplied[i] = operand1[i] / operand2 else: multiplied[i] = 1 hdu = astropy.io.fits.PrimaryHDU(multiplied) hdu.header = header hdu.writeto('final_tel_no_hLines_no_norm.fits') if os.path.exists('final_tel_no_hLines_no_norm.fits'): os.remove("1_htel" + rawFrame + ".fits") shutil.move('final_tel_no_hLines_no_norm.fits', "1_htel" + rawFrame + ".fits")
def getShiftScale(rawFrame, telluricInter, log, over): """ Use iraf.telluric() to get the best shift and scale of a telluric correction spectrum. Writes: "6_shiftScale"+rawFrame+".txt" : """ if os.path.exists('5_oneDCorrected' + rawFrame + '.fits') and os.path.exists("6_shiftScale" + rawFrame + ".txt"): if over: os.remove('5_oneDCorrected' + rawFrame + '.fits') # TODO(nat): implement logging for this iraf.chdir(os.getcwd()) tell_info = iraf.telluric( input='4_cubeslice' + rawFrame + '.fits[0]', output='5_oneDCorrected' + rawFrame + '.fits', cal="3_chtel" + rawFrame + '.fits[0]', airmass=1.0, answer='yes', ignoreaps='yes', xcorr='yes', tweakrms='yes', inter=telluricInter, sample="*", threshold=0.1, lag=3, shift=0., dshift=0.1, scale=1.0, dscale=0.1, offset=1, smooth=1, cursor='', mode='al', Stdout=1) else: logging.info( "\nOutput exists and -over not set - skipping get shift scale of telluric correction and fit" ) return else: iraf.chdir(os.getcwd()) tell_info = iraf.telluric(input='4_cubeslice' + rawFrame + '.fits[0]', output='5_oneDCorrected' + rawFrame + '.fits', cal="3_chtel" + rawFrame + '.fits[0]', airmass=1.0, answer='yes', ignoreaps='yes', xcorr='yes', tweakrms='yes', inter=telluricInter, sample="*", threshold=0.1, lag=3, shift=0., dshift=0.1, scale=1.0, dscale=0.1, offset=1, smooth=1, cursor='', mode='al', Stdout=1) # Get shift and scale from the list of values iraf.telluric() returns. # Sample tell_info: # ['cubeslice.fits[0]: norm.fits[1]: cubeslice.fits[0]: dshift 5.', 'window:again:window:window:again:window:window:again:window:TELLURIC:', # ' Output: vtella - HE1353-1917', ' Input: cubeslice.fits[0] - HE1353-1917', ' # Calibration: norm.fits[1] - Hip70765', ' Tweak: shift = 59.12, scale = 1.323, # normalization = 0.9041', ' WARNING: 3 pixels outside of calibration limits'] tellshift = 0. scale = 1.0 for i in range(len(tell_info)): # Now string looks like ' Tweak: shift = 59.12, scale = 1.323, normalization = 0.9041' if "Tweak" in tell_info[i]: # Remove the first 9 characters, temp = tell_info[i][9:] # Split into a list; now it looks like '['shift', '=', '59.12,', 'scale', '=', '1.323,', 'normalization', '=', '0.9041']' temp = temp.split() # Index two is the shift value with a trailing comma, index 5 is the scale value with a trailing comma. # Remove trailing comma. tellshift = temp[2].replace(',', '') # Turn it into a float. tellshift = float(tellshift) # Convert to a clean float # Do the same for the scale. scale = temp[5].replace(',', '') scale = float(scale) with open("6_shiftScale" + rawFrame + ".txt", "w") as text_file: text_file.write("Shift: {} Scale: {} \n".format(tellshift, scale))
def deimos_standard(standard): '''Extract standard star and calculate sensitivit function.''' bstd = "%s_01_B" % standard; rstd = "%s_01_R" % standard # Extract standard if get_head("%s.fits" % bstd, "SKYSUB"): iraf.apall(bstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none") iraf.apall(rstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none") else: iraf.apall(bstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit") iraf.apall(rstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit") # Fit the continuum #iraf.continuum("%s.ms" % bstd, output="s%s.ms" % bstd, lines=1, bands=1, # type="fit", sample="*", naverage=1, function="chebyshev", # order=15, low_reject=3.0, high_reject=5.0, niterate=10, grow=1.0, # interac=yes) #iraf.continuum("%s.ms" % rstd, output="s%s.ms" % rstd, lines=1, bands=1, # type="fit", sample="*", naverage=1, function="chebyshev", # order=15, low_reject=3.0, high_reject=5.0, niterate=10, grow=1.0, # interac=yes) # Create telluric iraf.splot("%s.ms" % bstd) # Remove telluric and absorption, save as a%s.ms iraf.sarith("%s.ms" % bstd, "/", "a%s.ms" % bstd, "telluric.B.%s.fits" % bstd) iraf.imreplace("telluric.B.%s.fits" % bstd, 1.0, lower=0.0, upper=0.0) iraf.splot("telluric.B.%s.fits" % bstd) # Remove stellar features and resave iraf.splot("%s.ms" % rstd) # Remove telluric and absorption, save as a%s.ms iraf.sarith("%s.ms" % rstd, "/", "a%s.ms" % rstd, "telluric.R.%s.fits" % rstd) iraf.imreplace("telluric.R.%s.fits" % rstd, 1.0, lower=0.0, upper=0.0) iraf.splot("telluric.R.%s.fits" % rstd) # Remove stellar features and resave # Create smoothed standard iraf.gauss("a%s.ms[*,1,1]" % bstd, "s%s.ms" % bstd, 5.0) iraf.sarith("%s.ms" % bstd, "/", "s%s.ms" % bstd, "ds%s.ms" % bstd) iraf.gauss("a%s.ms[*,1,1]" % rstd, "s%s.ms" % rstd, 5.0) iraf.sarith("%s.ms" % rstd, "/", "s%s.ms" % rstd, "ds%s.ms" % rstd) # Divide through by smoothed standard #iraf.sarith("%s.ms" % bstd, "/", "s%s.ms" % bstd, "ds%s.ms" % bstd) #iraf.sarith("%s.ms" % rstd, "/", "s%s.ms" % rstd, "ds%s.ms" % rstd) # Create and apply telluric correction #iraf.splot("%s.ms" % bstd) # Remove telluric, save as a%s.ms #iraf.splot("%s.ms" % rstd) # Remove telluric, save as a%s.ms #iraf.sarith("%s.ms" % bstd, "/", "a%s.ms" % bstd, "telluric.B.fits") #iraf.sarith("%s.ms" % rstd, "/", "a%s.ms" % rstd, "telluric.R.fits") #iraf.imreplace("telluric.B.fits", 1.0, lower=0.0, upper=0.0) #iraf.imreplace("telluric.R.fits", 1.0, lower=0.0, upper=0.0) iraf.telluric("ds%s.ms" % bstd, "tds%s.ms" % bstd, "telluric.B.%s.fits" % bstd, xcorr=no, tweakrms=no, interactive=no, sample='6850:6950,7575:7700') iraf.telluric("ds%s.ms" % rstd, "tds%s.ms" % rstd, "telluric.R.%s.fits" % rstd, xcorr=no, tweakrms=no, interactive=no, sample='6850:6950,7575:7700') # Define bandpasses for standard star calculation iraf.standard("tds%s.ms" % bstd, "%s.B.std" % standard, extinction='home$extinct/maunakeaextinct.dat', caldir='home$standards/', observatory='Keck', interac=yes, star_name=standard, airmass='', exptime='') iraf.standard("tds%s.ms" % rstd, "%s.R.std" % standard, extinction='home$extinct/maunakeaextinct.dat', caldir='home$standards/', observatory='Keck', interac=yes, star_name=standard, airmass='', exptime='') # Determine sensitivity function iraf.sensfunc('%s.B.std' % standard, '%s.B.sens' % standard, extinction='home$extinct/maunakeaextinct.dat', newextinction='extinct.dat', observatory='Keck', function='legendre', order=4, interactive=yes) iraf.sensfunc('%s.R.std' % standard, '%s.R.sens' % standard, extinction='home$extinct/maunakeaextinct.dat', newextinction='extinct.dat', observatory='Keck', function='legendre', order=4, interactive=yes) return
def deimos_extract(science, standard, dostandard=yes): '''Extract and flux calibrate DEIMOS spectra (assuming they have been processed into 2D images using deimos_pipe above).''' if dostandard: deimos_standard(standard) for source in science: images = iraffiles("%s_??_B.fits" % source) joinstr = "" for image in images: bimage = image.split(".")[0]; rimage = bimage[:-1] + "R" update_head(bimage, "FLUX_OBJ", standard) update_head(rimage, "FLUX_OBJ", standard) # Extract 1D spectra if get_head("%s.fits" % bimage, "SKYSUB"): iraf.apall(bimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none", reference="%s_01_B" % standard) iraf.apall(rimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none", reference="%s_01_R" % standard) else: iraf.apall(bimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit", reference="%s_01_B" % standard) iraf.apall(rimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit", reference="%s_01_R" % standard) # Normalize by the standard continuua iraf.sarith("%s.ms" % bimage, "/", "s%s_01_B.ms.fits" % standard, "s%s.ms" % bimage) iraf.sarith("%s.ms" % rimage, "/", "s%s_01_R.ms.fits" % standard, "s%s.ms" % rimage) # Telluric correct bstd = "%s_01_B" % standard; rstd = "%s_01_R" % standard iraf.telluric("s%s.ms" % bimage, "ts%s.ms" % bimage, "telluric.B.%s.fits" % bstd, tweakrms=yes, interactive=yes, sample='6850:6950,7575:7700') iraf.telluric("s%s.ms" % rimage, "ts%s.ms" % rimage, "telluric.R.%s.fits" % rstd, tweakrms=yes, interactive=yes, sample='6850:6950,7575:7700') # Flux calibration iraf.calibrate("ts%s.ms" % bimage, "fts%s.ms" % bimage, extinct=yes, flux=yes, extinction="home$extinct/maunakeaextinct.dat", observatory="Keck", sensitivity="%s.B.sens" % standard, airmass='', exptime='') iraf.calibrate("ts%s.ms" % rimage, "fts%s.ms" % rimage, extinct=yes, flux=yes, extinction="home$extinct/maunakeaextinct.dat", observatory="Keck", sensitivity="%s.R.sens" % standard, airmass='', exptime='') joinstr += "fts%s.ms,fts%s.ms," % (bimage, rimage) # Combine iraf.scombine(joinstr[:-1], "%s.ms.fits" % source, combine="average", reject="avsigclip", w1=INDEF, w2=INDEF, dw=INDEF, nw=INDEF, scale="none", zero="none", weight="none", lsigma=3.0, hsigma=3.0, gain=CCDGAIN, rdnoise=CCDRNOISE) # Plot to enable final tweaks iraf.splot("%s.ms.fits" % source) return
def red_science(image, flats, spath, object=None, arc='Arc-Red.fits', smooth='BD284211.smooth.fits', telluric='telluric.fits', sens='BD284211.sens', biassec=REDBIAS, trimsec=REDTRIM, outflat='Flat-Red.fits', gain=REDGAIN, rdnoise=REDRDNOISE): '''Full reduction of KAST science spectra on red CCD''' # Bias subtract everything first redbias(image, biassec=biassec, trimsec=trimsec) redbias(flats, biassec=biassec, trimsec=trimsec) # Create and apply flat-field make_flat(flats, outflat, gain=gain, rdnoise=rdnoise) iraf.ccdproc(image[0], ccdtype='', noproc=no, fixpix=no, overscan=no, trim=no, zerocor=no, darkcor=no, flatcor=yes, illumcor=no, fringecor=no, readcor=no, scancor=no, flat=outflat) # Cosmic ray rejection #iraf.lacos_spec(image[0], 'c%s' % image[0], 'cm%s' % image[0], # gain=gain, readn=rdnoise, xorder=9, yorder=3, # sigclip=4.5, sigfrac=0.5, objlim=1.0, niter=3) # Extract spectrum if object == None: object = get_head(image, 'OBJECT') iraf.apall('%s' % image[0], output=object, references='', interactive=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background='fit', weights='variance', pfit='fit1d', readnoise=rdnoise, gain=gain) # Apply wavelength solution to standard shutil.copy('%s/%s' % (spath, arc), '.') shutil.copy('%s/database/id%s' % (spath, arc.rstrip('.fits')), 'database') iraf.refspec(object, references=arc, sort="", group="", override=yes, confirm=no, assign=yes) iraf.dispcor(object, '%s.w' % object, confirm=no, listonly=no) # Smooth shutil.copy('%s/%s' % (spath, smooth), '.') iraf.sarith('%s.w' % object, '/', smooth, '%s.s' % object) # Create and apply telluric correction shutil.copy('%s/%s' % (spath, telluric), '.') iraf.telluric('%s.s' % object, '%s.t' % object, telluric, xcorr=yes, tweakrms=yes, interactive=yes, sample='6850:6950,7575:7700') # Flux calibration shutil.copy('%s/%s.0001.fits' % (spath, sens), '.') iraf.calibrate('%s.t' % object, '%s.f' % object, extinct=yes, flux=yes, extinction='onedstds$kpnoextinct.dat', observatory='Lick', sensitivity=sens, airmass='', exptime='') return
def telluric_correct_standard(): """ Now do telluric correction on sensitivity corrected telluric spectrum, as a check. """ if os.path.exists('tcdimcomb.ms.fits'): os.remove('tcdimcomb.ms.fits') print 'Removing file tcdimcomb.ms.fits' # List of input spectra to correct iraf.telluric.setParam('input', 'cdimcomb.ms.fits') # List of output corrected spectra iraf.telluric.setParam('output', 'tcdimcomb.ms.fits') # List of telluric calibration spectra iraf.telluric.setParam('cal', 'model_tell_spec.fits') # Airmass - of telluric spectrum I think, in this case the same as cdimcomb.ms.fits # should now read from header. # hdulist = fits.open('cdimcomb.ms.fits') # hdr = hdulist[0].header # airmass = hdr['airmass'] # iraf.telluric.setParam('airmass', airmass) # Search interactively? iraf.telluric.setParam('answer', 'yes') # Ignore aperture numbers in calibration spectra? iraf.telluric.setParam('ignoreaps', 'yes') # Cross correlate for shift? iraf.telluric.setParam('xcorr', 'yes') # Tweak to minimize RMS? iraf.telluric.setParam('tweakrms', 'yes') # Interactive tweaking? iraf.telluric.setParam('interactive', 'yes') # Sample ranges # Don't fit bit between H and K iraf.telluric.setParam('sample', '15000:18000,19700:23800') # Threshold for calibration iraf.telluric.setParam('threshold', 0.) # Cross correlation lag (pixels) iraf.telluric.setParam('lag', 10) # Initial shift of calibration spectrum (pixels) iraf.telluric.setParam('shift', 0.) # Initial scale factor multiplying airmass ratio iraf.telluric.setParam('scale', 1.) # Initial shift search step iraf.telluric.setParam('dshift', 5.) # Initial scale factor search step iraf.telluric.setParam('dscale', 0.2) # Initial offset for graphs iraf.telluric.setParam('offset', 1.) # Smoothing box for graphs iraf.telluric.setParam('smooth', 3) iraf.telluric() return None
def deimos_standard(standard): '''Extract standard star and calculate sensitivit function.''' bstd = "%s_01_B" % standard rstd = "%s_01_R" % standard # Extract standard if get_head("%s.fits" % bstd, "SKYSUB"): iraf.apall(bstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none") iraf.apall(rstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none") else: iraf.apall(bstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit") iraf.apall(rstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit") # Fit the continuum #iraf.continuum("%s.ms" % bstd, output="s%s.ms" % bstd, lines=1, bands=1, # type="fit", sample="*", naverage=1, function="chebyshev", # order=15, low_reject=3.0, high_reject=5.0, niterate=10, grow=1.0, # interac=yes) #iraf.continuum("%s.ms" % rstd, output="s%s.ms" % rstd, lines=1, bands=1, # type="fit", sample="*", naverage=1, function="chebyshev", # order=15, low_reject=3.0, high_reject=5.0, niterate=10, grow=1.0, # interac=yes) # Create telluric iraf.splot("%s.ms" % bstd) # Remove telluric and absorption, save as a%s.ms iraf.sarith("%s.ms" % bstd, "/", "a%s.ms" % bstd, "telluric.B.%s.fits" % bstd) iraf.imreplace("telluric.B.%s.fits" % bstd, 1.0, lower=0.0, upper=0.0) iraf.splot("telluric.B.%s.fits" % bstd) # Remove stellar features and resave iraf.splot("%s.ms" % rstd) # Remove telluric and absorption, save as a%s.ms iraf.sarith("%s.ms" % rstd, "/", "a%s.ms" % rstd, "telluric.R.%s.fits" % rstd) iraf.imreplace("telluric.R.%s.fits" % rstd, 1.0, lower=0.0, upper=0.0) iraf.splot("telluric.R.%s.fits" % rstd) # Remove stellar features and resave # Create smoothed standard iraf.gauss("a%s.ms[*,1,1]" % bstd, "s%s.ms" % bstd, 5.0) iraf.sarith("%s.ms" % bstd, "/", "s%s.ms" % bstd, "ds%s.ms" % bstd) iraf.gauss("a%s.ms[*,1,1]" % rstd, "s%s.ms" % rstd, 5.0) iraf.sarith("%s.ms" % rstd, "/", "s%s.ms" % rstd, "ds%s.ms" % rstd) # Divide through by smoothed standard #iraf.sarith("%s.ms" % bstd, "/", "s%s.ms" % bstd, "ds%s.ms" % bstd) #iraf.sarith("%s.ms" % rstd, "/", "s%s.ms" % rstd, "ds%s.ms" % rstd) # Create and apply telluric correction #iraf.splot("%s.ms" % bstd) # Remove telluric, save as a%s.ms #iraf.splot("%s.ms" % rstd) # Remove telluric, save as a%s.ms #iraf.sarith("%s.ms" % bstd, "/", "a%s.ms" % bstd, "telluric.B.fits") #iraf.sarith("%s.ms" % rstd, "/", "a%s.ms" % rstd, "telluric.R.fits") #iraf.imreplace("telluric.B.fits", 1.0, lower=0.0, upper=0.0) #iraf.imreplace("telluric.R.fits", 1.0, lower=0.0, upper=0.0) iraf.telluric("ds%s.ms" % bstd, "tds%s.ms" % bstd, "telluric.B.%s.fits" % bstd, xcorr=no, tweakrms=no, interactive=no, sample='6850:6950,7575:7700') iraf.telluric("ds%s.ms" % rstd, "tds%s.ms" % rstd, "telluric.R.%s.fits" % rstd, xcorr=no, tweakrms=no, interactive=no, sample='6850:6950,7575:7700') # Define bandpasses for standard star calculation iraf.standard("tds%s.ms" % bstd, "%s.B.std" % standard, extinction='home$extinct/maunakeaextinct.dat', caldir='home$standards/', observatory='Keck', interac=yes, star_name=standard, airmass='', exptime='') iraf.standard("tds%s.ms" % rstd, "%s.R.std" % standard, extinction='home$extinct/maunakeaextinct.dat', caldir='home$standards/', observatory='Keck', interac=yes, star_name=standard, airmass='', exptime='') # Determine sensitivity function iraf.sensfunc('%s.B.std' % standard, '%s.B.sens' % standard, extinction='home$extinct/maunakeaextinct.dat', newextinction='extinct.dat', observatory='Keck', function='legendre', order=4, interactive=yes) iraf.sensfunc('%s.R.std' % standard, '%s.R.sens' % standard, extinction='home$extinct/maunakeaextinct.dat', newextinction='extinct.dat', observatory='Keck', function='legendre', order=4, interactive=yes) return
def deimos_extract(science, standard, dostandard=yes): '''Extract and flux calibrate DEIMOS spectra (assuming they have been processed into 2D images using deimos_pipe above).''' if dostandard: deimos_standard(standard) for source in science: images = iraffiles("%s_??_B.fits" % source) joinstr = "" for image in images: bimage = image.split(".")[0] rimage = bimage[:-1] + "R" update_head(bimage, "FLUX_OBJ", standard) update_head(rimage, "FLUX_OBJ", standard) # Extract 1D spectra if get_head("%s.fits" % bimage, "SKYSUB"): iraf.apall(bimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none", reference="%s_01_B" % standard) iraf.apall(rimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none", reference="%s_01_R" % standard) else: iraf.apall(bimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit", reference="%s_01_B" % standard) iraf.apall(rimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit", reference="%s_01_R" % standard) # Normalize by the standard continuua iraf.sarith("%s.ms" % bimage, "/", "s%s_01_B.ms.fits" % standard, "s%s.ms" % bimage) iraf.sarith("%s.ms" % rimage, "/", "s%s_01_R.ms.fits" % standard, "s%s.ms" % rimage) # Telluric correct bstd = "%s_01_B" % standard rstd = "%s_01_R" % standard iraf.telluric("s%s.ms" % bimage, "ts%s.ms" % bimage, "telluric.B.%s.fits" % bstd, tweakrms=yes, interactive=yes, sample='6850:6950,7575:7700') iraf.telluric("s%s.ms" % rimage, "ts%s.ms" % rimage, "telluric.R.%s.fits" % rstd, tweakrms=yes, interactive=yes, sample='6850:6950,7575:7700') # Flux calibration iraf.calibrate("ts%s.ms" % bimage, "fts%s.ms" % bimage, extinct=yes, flux=yes, extinction="home$extinct/maunakeaextinct.dat", observatory="Keck", sensitivity="%s.B.sens" % standard, airmass='', exptime='') iraf.calibrate("ts%s.ms" % rimage, "fts%s.ms" % rimage, extinct=yes, flux=yes, extinction="home$extinct/maunakeaextinct.dat", observatory="Keck", sensitivity="%s.R.sens" % standard, airmass='', exptime='') joinstr += "fts%s.ms,fts%s.ms," % (bimage, rimage) # Combine iraf.scombine(joinstr[:-1], "%s.ms.fits" % source, combine="average", reject="avsigclip", w1=INDEF, w2=INDEF, dw=INDEF, nw=INDEF, scale="none", zero="none", weight="none", lsigma=3.0, hsigma=3.0, gain=CCDGAIN, rdnoise=CCDRNOISE) # Plot to enable final tweaks iraf.splot("%s.ms.fits" % source) return
def red_standard(image, arcs, flats, object=None, biassec=REDBIAS, trimsec=REDTRIM, outflat='Flat-Red.fits', gain=REDGAIN, rdnoise=REDRDNOISE, arc='Arc-Red.fits', caldir='home$standards/'): '''Reduce and calibrate standard star observation with red CCD''' # Bias subtract everything first redbias(image, biassec=biassec, trimsec=trimsec) redbias(arcs, biassec=biassec, trimsec=trimsec) redbias(flats, biassec=biassec, trimsec=trimsec) # Create and apply flat-field make_flat(flats, outflat, gain=gain, rdnoise=rdnoise) iraf.ccdproc(image[0], ccdtype='', noproc=no, fixpix=no, overscan=no, trim=no, zerocor=no, darkcor=no, flatcor=yes, illumcor=no, fringecor=no, readcor=no, scancor=no, flat=outflat) arcimages=','.join(arcs) iraf.ccdproc(arcs, ccdtype='', noproc=no, fixpix=no, overscan=no, trim=no, zerocor=no, darkcor=no, flatcor=yes, illumcor=no, fringecor=no, readcor=no, scancor=no, flat=outflat) # Extract spectrum of standard if object==None: object=get_head(image, 'OBJECT') iraf.apall(image[0], output=object, references='', interactive=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background='fit', weights='variance', pfit='fit1d', readnoise=rdnoise, gain=gain) # Extract arc and fit wavelength solution iraf.imarith(arcs[0], '+', arcs[1], 'Arc-Sum.fits') reference_arc('Arc-Sum.fits', arc, image[0]) # Apply wavelength solution to standard iraf.refspec(object, references=arc, sort="", group="", override=yes, confirm=no, assign=yes) iraf.dispcor(object, '%s.w' % object, confirm=no, listonly=no) # Remove absorption features and smooth iraf.splot('%s.w' % object, 1, 1) iraf.gauss('temp1[*,1,1]', '%s.smooth' % object, 3.0) iraf.sarith('%s.w' % object, '/', '%s.smooth' % object, '%s.s' % object) # Create and apply telluric correction iraf.sarith('%s.w' % object, '/', 'temp1', 'telluric') iraf.splot('telluric', 1, 1) iraf.telluric('%s.s' % object, '%s.t' % object, 'telluric', xcorr=no, tweakrms=no, interactive=no, sample='6850:6950,7575:7700') # Define bandpasses for standard star calculation iraf.standard('%s.t' % object, '%s.std' % object, extinction='onedstds$kpnoextinct.dat', caldir=caldir, observatory='Lick', interact=yes, star_name=object, airmass='', exptime='') # Determine sensitivity function iraf.sensfunc('%s.std' % object, '%s.sens' % object, extinction='onedstds$kpnoextinct.dat', newextinction='extinct.dat', observatory='Lick', function='legendre', order=3, interactive=yes) return
def vega(spectrum, band, path, hlineinter, airmass, t1, log, over): # Use "telluric" to remove H lines from standard star, then remove normalization added by telluric # specify the extension for vega_ext.fits from the band if band == 'K': ext = '1' if band == 'H': ext = '2' if band == 'J': ext = '3' if band == 'Z': ext = '4' if os.path.exists("tell_nolines" + band + ".fits"): if over: os.remove("tell_nolines" + band + ".fits") tell_info = iraf.telluric(input=spectrum + "[1]", output='tell_nolines' + band, cal=sys.prefix + '/vega_ext.fits[' + ext + ']', answer='yes', ignoreaps='yes', xcorr='yes', airmass=airmass, tweakrms='yes', inter=hlineinter, threshold=0.1, lag=3, shift=0., dshift=0.05, scale=.75, dscale=0.05, offset=0., smooth=1, cursor='', mode='al', Stdout=1) else: print "Output file exists and -over not set - skipping H line correction" else: tell_info = iraf.telluric(input=spectrum + "[1]", output='tell_nolines' + band, cal=sys.prefix + '/vega_ext.fits[' + ext + ']', answer='yes', ignoreaps='yes', xcorr='yes', airmass=airmass, tweakrms='yes', inter=hlineinter, threshold=0.1, lag=3, shift=0., dshift=0.05, scale=1., dscale=0.05, offset=0, smooth=1, cursor='', mode='al', Stdout=1) # record shift and scale info for future reference t1.write(str(tell_info) + '\n') # need this loop to identify telluric output containing warning about pix outside calibration limits (different formatting) if "limits" in tell_info[-1].split()[-1]: norm = tell_info[-2].split()[-1] else: norm = tell_info[-1].split()[-1] if os.path.exists("ftell_nolines" + band + ".fits"): if over: os.remove("ftell_nolines" + band + ".fits") iraf.imarith(operand1='tell_nolines' + band, op='/', operand2=norm, result='ftell_nolines' + band, title='', divzero=0.0, hparams='', pixtype='', calctype='', verbose='yes', noact='no', mode='al') else: print "Output file exists and -over not set - skipping H line normalization" else: iraf.imarith(operand1='tell_nolines' + band, op='/', operand2=norm, result='ftell_nolines' + band, title='', divzero=0.0, hparams='', pixtype='', calctype='', verbose='yes', noact='no', mode='al')
def lris_extract(science, standards, dostandard=yes): '''Extract and flux calibrate LRIS spectra (assuming they have been processed into 2D images using LRIS_pipe above).''' if dostandard: lris_standard(standards) for src in science: bimages = iraffiles("%s_??_B.fits" % src) rimages = iraffiles("%s_??_R.fits" % src) joinstr = "" for bimage in bimages: bimage = bimage.split(".")[0] # Find appropriate standard for this image bstd = get_head("%s.fits" % bimage, "STDNAME") # Extract 1D spectra if get_head("%s.fits" % bimage, "SKYSUB"): iraf.apall(bimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none", reference=bstd) else: iraf.apall(bimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit", reference=bstd) # Normalize by the standard continuua iraf.sarith("%s.ms" % bimage, "/", "../standards/s%s.ms.fits" % bstd, "s%s.ms" % bimage, w1=INDEF, w2=INDEF) # Telluric correct iraf.telluric("s%s.ms" % bimage, "ts%s.ms" % bimage, "../standards/telluric.%s.fits" % bstd, tweakrms=yes, interactive=yes, sample='6850:6950,7575:7700,8750:9925') # Flux calibration iraf.calibrate("ts%s.ms" % bimage, "fts%s.ms" % bimage, extinct=yes, flux=yes, extinction="home$extinct/maunakeaextinct.dat", observatory="Keck", sens="../standards/%s.sens" % bstd, airmass='', exptime='') joinstr += "fts%s.ms," % bimage for rimage in rimages: rimage = rimage.split(".")[0] # Find appropriate standard for this image rstd = get_head("%s.fits" % rimage, "STDNAME") # Extract 1D spectra if get_head("%s.fits" % rimage, "SKYSUB"): iraf.apall(rimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none", reference=rstd) else: iraf.apall(rimage, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit", reference=rstd) # Normalize by the standard continuua iraf.sarith("%s.ms" % rimage, "/", "../standards/s%s.ms.fits" % rstd, "s%s.ms" % rimage, w1=5500, w2=INDEF) # Telluric correct iraf.telluric("s%s.ms" % rimage, "ts%s.ms" % rimage, "../standards/telluric.%s.fits" % rstd, tweakrms=yes, interactive=yes, sample='6850:6950,7575:7700') # Flux calibration iraf.calibrate("ts%s.ms" % rimage, "fts%s.ms" % rimage, extinct=yes, flux=yes, extinction="home$extinct/maunakeaextinct.dat", observatory="Keck", sens="../standards/%s.sens" % rstd, airmass='', exptime='') joinstr += "fts%s.ms," % rimage # Combine iraf.scombine(joinstr[:-1], "%s.ms.fits" % src, combine="average", reject="avsigclip", w1=INDEF, w2=INDEF, dw=INDEF, nw=INDEF, scale="median", zero="none", weight="none", sample="5450:5600", lsigma=3.0, hsigma=3.0, gain=RCCDGAIN, rdnoise=RCCDRNOISE) # Plot to enable final tweaks iraf.splot("%s.ms.fits" % src) return
def telluric_corr_target(): """ Remove telluric lines (badly!) """ if os.path.exists('tcdimcomb.ms.fits'): os.remove('tcdimcomb.ms.fits') print 'Removing file tcdimcomb.ms.fits' # List of input spectra to correct iraf.telluric.setParam('input', 'cdimcomb.ms.fits') # List of output corrected spectra iraf.telluric.setParam('output', 'tcdimcomb.ms.fits') # List of telluric calibration spectra iraf.telluric.setParam('cal', 'model_tell_spec.fits') # Airmass - of telluric spectrum I think, should read from header of model_tell_spec.fits # iraf.telluric.setParam('airmass', airmass) # Search interactively? iraf.telluric.setParam('answer', 'yes') # Ignore aperture numbers in calibration spectra? iraf.telluric.setParam('ignoreaps', 'yes') # Cross correlate for shift? iraf.telluric.setParam('xcorr', 'yes') # Tweak to minimize RMS? iraf.telluric.setParam('tweakrms', 'yes') # Interactive tweaking? iraf.telluric.setParam('interactive', 'yes') # Sample ranges # Don't fit bit between H and K iraf.telluric.setParam('sample', '15000:18000,19700:23800') # Threshold for calibration iraf.telluric.setParam('threshold', 0.) # Cross correlation lag (pixels) iraf.telluric.setParam('lag', 10) # Initial shift of calibration spectrum (pixels) iraf.telluric.setParam('shift', 0.) # Initial scale factor multiplying airmass ratio iraf.telluric.setParam('scale', 1.) # Initial shift search step iraf.telluric.setParam('dshift', 5.) # Initial scale factor search step iraf.telluric.setParam('dscale', 0.2) # Initial offset for graphs iraf.telluric.setParam('offset', 1.) # Smoothing box for graphs iraf.telluric.setParam('smooth', 3) iraf.telluric() return None
def telluric_correction(targetdir,telluricdir,stype): """ Removes telluric lines from 1D spectrum Assumes both science and telluric spectrum have been extracted and wavelength calibrated, i.e. file dimcomb.ms.fits exists in telluric directory. """ print 'Target directory is ' + targetdir if os.path.exists( os.path.join(targetdir,'dimcomb.ms.fits') ): print "Wavelength calibrated target spectrum 'dimcomb.ms.fits' exists" print 'Telluric directory is ' + telluricdir if os.path.exists( os.path.join(telluricdir,'dimcomb.ms.fits') ): print "Wavelength calibrated telluric spectrum 'dimcomb.ms.fits' exists" print 'Generating black-body spectrum...' print 'Telluric star type ' + stype # from this site http://www.gemini.edu/sciops/instruments/nir/photometry/temps_colors.txt if stype == 'A0V': bbtemp = 9480.0 if stype == 'A1V': bbtemp = 9230.0 if stype == 'A2V': bbtemp = 8810.0 if stype == 'A3V': bbtemp = 8270.0 if stype == 'A4V': bbtemp = 8200.0 if stype == 'A5V': bbtemp = 8160.0 print 'Fitting with blackbody, temperature = ' + str(bbtemp) + 'K' iraf.noao(_doprint=0) iraf.artdata (_doprint=0) if os.path.exists( os.path.join(telluricdir,'blackbody.fits') ): os.remove( os.path.join(telluricdir,'blackbody.fits') ) iraf.mk1dspec.setParam('input', os.path.join(telluricdir,'blackbody.fits') ) iraf.mk1dspec.setParam('title','blackbody') iraf.mk1dspec.setParam('ncols',1024) iraf.mk1dspec.setParam('wstart',13900) iraf.mk1dspec.setParam('wend',24000) iraf.mk1dspec.setParam('temperature',bbtemp) iraf.mk1dspec() print 'Generated blackbody spectrum' # Divide telluric star spectrum by black-body if os.path.exists( os.path.join(telluricdir,'tdimcomb.ms.fits') ): os.remove( os.path.join(telluricdir,'tdimcomb.ms.fits') ) iraf.onedspec(_doprint=0) """ To divide by blackbody I want to turn off the cross-correlation - which I think would only work if both spectra had similar features. I don't want to scale the spectrum - which scales the airmass using Beer's Law - or shift it. If the temperature is correct I should be able to simply divide. If not then I should change the temperature """ iraf.telluric.setParam('input',os.path.join(telluricdir,'dimcomb.ms.fits') ) # List of input spectra to correct iraf.telluric.setParam('output',os.path.join(telluricdir,'tdimcomb.ms.fits') ) # List of output corrected spectra iraf.telluric.setParam('cal',os.path.join(telluricdir,'blackbody.fits') ) # List of telluric calibration spectra iraf.telluric.setParam('answer','yes') # Search interactively? iraf.telluric.setParam('xcorr', 'no') # Cross correlate for shift? iraf.telluric.setParam('tweakrms', 'no') # Twak to minise rms? iraf.telluric.setParam('interactive', 'yes') # Interactive? iraf.telluric.setParam('threshold',0.0) # Threshold for calibration iraf.telluric.setParam('offset',1) # Displayed offset between spectra iraf.telluric.setParam('sample','15000:18000,19700:23800') iraf.telluric.setParam('dshift',5.0) iraf.telluric.setParam('smooth',3.0) iraf.telluric() """ When your calibration spectrum has zero or negative intensity values, you have to set the "threshold" parameter accordingly. As explained in the help page for the TELLURIC task, you can think of the "threshold" value as the minimum intensity value TELLURIC will accept from your calibration spectra. Any intensity value lower than the threshold value will be replaced by the threshold. """ """ I've turned cross-correlation off, since I don't really understand it. Tweak is on, but doesn't seem to do that much. Still not sure if it's understanding the airmass """ print 'Now correcting target spectrum...' if os.path.exists( os.path.join(targetdir,'tdimcomb+bkgd.ms.fits') ): os.remove( os.path.join(targetdir,'tdimcomb+bkgd.ms.fits') ) iraf.telluric.setParam('input',os.path.join(targetdir,'dimcomb+bkgd.ms.fits') ) # List of input spectra to correct iraf.telluric.setParam('output',os.path.join(targetdir,'tdimcomb+bkgd.ms.fits') ) # List of output corrected spectra iraf.telluric.setParam('cal',os.path.join(telluricdir,'tdimcomb.ms.fits') ) # List of telluric calibration spectra iraf.telluric.setParam('answer','yes') # Search interactively? iraf.telluric.setParam('threshold',0.0) iraf.telluric.setParam('xcorr', 'no') # Cross correlate for shift? iraf.telluric.setParam('tweakrms', 'yes') # Tweak to minise rms? iraf.telluric.setParam('interactive', 'yes') # Interactive? iraf.telluric.setParam('offset',6) # Displayed offset between spectra hdulist = fits.open(os.path.join(targetdir,'imcomb.ms.fits')) hdr = hdulist[0].header hdulist.close() iraf.telluric.setParam('airmass',hdr['AIRMASS']) iraf.telluric() return None
def lris_standard(standards, xcorr=yes): '''Extract standard stars and calculate sensitivity functions.''' for ofile, nstd in standards: shutil.copy(ofile, "%s.fits" % nstd) # Extract standard if get_head("%s.fits" % nstd, "SKYSUB"): iraf.apall(nstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="none") else: iraf.apall(nstd, output="", inter=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background="fit") if xcorr: # Cross correlate to tweak wavelength iraf.xcsao("%s.ms" % nstd, templates=XCTEMPLATE, correlate="wavelength", logfiles="%s.xcsao" % ofile) # If a solution was found, apply shift try: xcsaof = open("%s.xcsao" % ofile) shift = float(xcsaof.readlines()[6].split()[14]) except: shift = 0.0 iraf.specshift("%s.ms" % nstd, -shift) # Create telluric iraf.splot("%s.ms" % nstd) # Remove telluric and absorption, save as a%s.ms iraf.sarith("%s.ms" % nstd, "/", "a%s.ms" % nstd, "telluric.%s.fits" % nstd) iraf.imreplace("telluric.%s.fits" % nstd, 1.0, lower=0.0, upper=0.0) iraf.splot("telluric.%s.fits" % nstd) # Remove stellar features and resave # Create smoothed standard iraf.gauss("a%s.ms[*,1,1]" % nstd, "s%s.ms" % nstd, 5.0) iraf.sarith("%s.ms" % nstd, "/", "s%s.ms" % nstd, "ds%s.ms" % nstd) # Apply telluric correction iraf.telluric( "ds%s.ms" % nstd, "tds%s.ms" % nstd, "telluric.%s.fits" % nstd, xcorr=no, tweakrms=no, interactive=no, sample='4000:4010,6850:6975,7150:7350,7575:7725,8050:8400,8900:9725' ) # Define bandpasses for standard star calculation obj = get_head("%s.fits" % nstd, "OBJECT") iraf.standard("tds%s.ms" % nstd, "%s.std" % nstd, extinction='home$extinct/maunakeaextinct.dat', caldir='home$standards/', observatory='Keck', interac=yes, star_name=obj, airmass='', exptime='') # Determine sensitivity function iraf.sensfunc('%s.std' % nstd, '%s.sens' % nstd, extinction='home$extinct/maunakeaextinct.dat', newextinction='extinct.dat', observatory='Keck', function='legendre', order=4, interactive=yes) return
def red_standard(image, arcs, flats, object=None, biassec=REDBIAS, trimsec=REDTRIM, outflat='Flat-Red.fits', gain=REDGAIN, rdnoise=REDRDNOISE, arc='Arc-Red.fits', caldir='home$standards/'): '''Reduce and calibrate standard star observation with red CCD''' # Bias subtract everything first redbias(image, biassec=biassec, trimsec=trimsec) redbias(arcs, biassec=biassec, trimsec=trimsec) redbias(flats, biassec=biassec, trimsec=trimsec) # Create and apply flat-field make_flat(flats, outflat, gain=gain, rdnoise=rdnoise) iraf.ccdproc(image[0], ccdtype='', noproc=no, fixpix=no, overscan=no, trim=no, zerocor=no, darkcor=no, flatcor=yes, illumcor=no, fringecor=no, readcor=no, scancor=no, flat=outflat) arcimages = ','.join(arcs) iraf.ccdproc(arcs, ccdtype='', noproc=no, fixpix=no, overscan=no, trim=no, zerocor=no, darkcor=no, flatcor=yes, illumcor=no, fringecor=no, readcor=no, scancor=no, flat=outflat) # Extract spectrum of standard if object == None: object = get_head(image, 'OBJECT') iraf.apall(image[0], output=object, references='', interactive=yes, find=yes, recenter=yes, resize=yes, edit=yes, trace=yes, fittrace=yes, extract=yes, extras=yes, review=no, background='fit', weights='variance', pfit='fit1d', readnoise=rdnoise, gain=gain) # Extract arc and fit wavelength solution iraf.imarith(arcs[0], '+', arcs[1], 'Arc-Sum.fits') reference_arc('Arc-Sum.fits', arc, image[0]) # Apply wavelength solution to standard iraf.refspec(object, references=arc, sort="", group="", override=yes, confirm=no, assign=yes) iraf.dispcor(object, '%s.w' % object, confirm=no, listonly=no) # Remove absorption features and smooth iraf.splot('%s.w' % object, 1, 1) iraf.gauss('temp1[*,1,1]', '%s.smooth' % object, 3.0) iraf.sarith('%s.w' % object, '/', '%s.smooth' % object, '%s.s' % object) # Create and apply telluric correction iraf.sarith('%s.w' % object, '/', 'temp1', 'telluric') iraf.splot('telluric', 1, 1) iraf.telluric('%s.s' % object, '%s.t' % object, 'telluric', xcorr=no, tweakrms=no, interactive=no, sample='6850:6950,7575:7700') # Define bandpasses for standard star calculation iraf.standard('%s.t' % object, '%s.std' % object, extinction='onedstds$kpnoextinct.dat', caldir=caldir, observatory='Lick', interact=yes, star_name=object, airmass='', exptime='') # Determine sensitivity function iraf.sensfunc('%s.std' % object, '%s.sens' % object, extinction='onedstds$kpnoextinct.dat', newextinction='extinct.dat', observatory='Lick', function='legendre', order=3, interactive=yes) return