def makeArcDark(arcdarklist, arcdark, calflat, over, log): # combine the daytime arc darks for image in arcdarklist: image = str(image).strip() if over: iraf.delete("n" + image + ".fits") iraf.nfprepare(image, rawpath='./', shiftimage="s" + calflat, bpm="rgn" + calflat + "_sflat_bpm.pl", fl_vardq='yes', fl_corr='no', fl_nonl='no', logfile=log) arcdarklist = checkLists(arcdarklist, '.', 'n', '.fits') if over: iraf.delete("gn" + arcdark + ".fits") if len(arcdarklist) > 1: iraf.gemcombine(listit(arcdarklist, "n"), output="gn" + arcdark, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log) else: iraf.copy('n' + arcdark + '.fits', 'gn' + arcdark + '.fits') open("arcdarkfile", "w").write("gn" + arcdark)
def ronchi(ronchilist, ronchiflat, calflat, over, flatdark, log): """Establish Spatial-distortion calibration with nfsdist. NFSDIST uses the information in the "Ronchi" Calibration images to calibrate the spatial dimension of the NIFS IFU field. The Ronchi frame is a dispersed flat field image with a slit-mask in the field so that the illumination on the IFU is in a pattern of ~10 different slitlets that are stacked in the y-dimension on the field. Proper alignment of the slits across the image slicer pattern can be used for spatial rectification of the on-sky science data. The spatial solution determined by NFSDIST is linked to the science data in NFFITCOORDS. """ # Update ronchi flat frames with offset value and generate variance and data quality extensions. # Output: "n"+image+".fits". for image in ronchilist: image = str(image).strip() if over: iraf.delete("n"+image+'.fits') iraf.nfprepare(image,rawpath=".", shiftimage="s"+calflat, \ bpm="rgn"+calflat+"_sflat_bpm.pl", fl_vardq="yes",fl_corr="no",fl_nonl="no", \ logfile=log) ronchilist = checkLists(ronchilist, '.', 'n', '.fits') # Combine nfprepared ronchi flat images "n"+image+".fits". Output: combined file will # have the name of the first ronchi flat file, "gn"+ronchiflat+".fits". if over: iraf.delete("gn"+ronchiflat+".fits") if len(ronchilist) > 1: iraf.gemcombine(listit(ronchilist,"n"),output="gn"+ronchiflat,fl_dqpr="yes", \ masktype="none",fl_vardq="yes",logfile=log) else: iraf.copy("n"+ronchiflat+".fits","gn"+ronchiflat+".fits") # NSREDUCE combined ronchi frame, "gn"+ronchiflat+".fits", to extract the slices into unique MEF extensions and # apply an approximate wavelength calibration to each slice. Output: "rgn"+ronchiflat+".fits". if over: iraf.delete("rgn"+ronchiflat+".fits") iraf.nsreduce("gn"+ronchiflat, outpref="r", dark="rgn"+flatdark+"_dark", flatimage="rgn"+calflat+"_flat", fl_cut="yes", fl_nsappw="yes", fl_flat="yes", fl_sky="no", fl_dark="yes", fl_vardq="no", logfile=log) if os.path.exists("ronchifile"): if over: iraf.delete("ronchifile") iraf.delete("rgn"+ronchiflat) else: print "\nOutput file exists and -over not set - ",\ "not performing ronchi calibration with iraf.nfsdist.\n" return else: # Determine the spatial distortion correction. Output: overwrites "rgn"+ronchiflat+".fits" and makes # changes to files in /database directory. iraf.nfsdist("rgn"+ronchiflat,fwidth=6.0, cradius=8.0, glshift=2.8, minsep=6.5, thresh=2000.0, nlost=3, fl_inter='no',logfile=log) # Put the name of the spatially referenced ronchi flat "rgn"+ronchiflat into a # text file called ronchifile to be used by the pipeline later. Also associated files # are in the "database/" directory. open("ronchifile", "w").write("rgn"+ronchiflat)
def makeArcDark(arcdarklist, arcdark, calflat, over, log): """"Prepare with iraf.nfprepare and combine the daytime arc darks. Processing with NFPREPARE will rename the data extension and add variance and data quality extensions. By default (see NSHEADERS) the extension names are SCI for science data, VAR for variance, and DQ for data quality (0 = good). Generation of the data quality plane (DQ) is important in order to fix hot and dark pixels on the NIFS detector in subsequent steps in the data reduction process. Various header keywords (used later) are also added in NFPREPARE. NFPREPARE will also add an MDF file (extension MDF) describing the NIFS image slicer pattern and how the IFU maps to the sky field. """ # Update arc dark frames with mdf offset value and generate variance and data quality extensions. for image in arcdarklist: image = str(image).strip() if over: iraf.delete("n"+image+".fits") iraf.nfprepare(image, rawpath='.', shiftimage="s"+calflat, \ bpm=sflat_bpm,fl_vardq='yes',fl_corr='no',fl_nonl='no', logfile=log) arcdarklist = checkLists(arcdarklist, '.', 'n', '.fits') # Combine arc dark frames, "n"+image+".fits". Output combined file will have the name of the first arc dark file. if over: iraf.delete("gn"+arcdark+".fits") if len(arcdarklist) > 1: iraf.gemcombine(listit(arcdarklist,"n"),output="gn"+arcdark, fl_dqpr='yes',fl_vardq='yes',masktype="none",logfile=log) else: iraf.copy('n'+arcdark+'.fits', 'gn'+arcdark+'.fits') # Put the name of the combined and prepared arc dark frame "gn"+arcdark into a text # file called arcdarkfile to be used by the pipeline later. open("arcdarkfile", "w").write("gn"+arcdark)
def combineImages(inlist, out, log, over): # gemcombine a list of images print inlist if os.path.exists(out + ".fits"): if over: iraf.delete(out + ".fits") else: print "Output file exists and -over not set - skipping combine_ima" return iraf.gemcombine(listit(inlist, "n"), output=out, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log)
def combineImages(inlist, out, log, over): """Gemcombine multiple frames. Output: -->gn.""" if os.path.exists(out + ".fits"): if over: iraf.delete(out + ".fits") else: logging.info( "Output file exists and -over not set - skipping combine_ima") return iraf.gemcombine(listit(inlist, "n"), output=out, fl_dqpr='yes', fl_vardq='yes', masktype="none", combine="median", logfile=log)
def makeTelluric(objlist, log, over): # Extracts 1-D spectra and combines them # This step is currently only done interactively for image in objlist: image = str(image).strip() if os.path.exists("xtfbrgn" + image + ".fits"): if over: iraf.delete("xtfbrgn" + image + ".fits") else: print "Output file exists and -over not set - skipping extraction in make_telluric" continue diam = 0.5 iraf.nfextract("tfbrgn" + image, outpref="x", diameter=diam, fl_int='yes', logfile=log) #combine all the 1D spectra to one final output file telluric = str(objlist[0]).strip() if os.path.exists("gxtfbrgn" + telluric + ".fits"): if over: iraf.delete("gxtfbrgn" + telluric + ".fits") else: print "Output file exists and -over not set - skipping gemcombine in make_telluric" return iraf.gemcombine(listit(objlist, "xtfbrgn"), output="gxtfbrgn" + telluric, statsec="[*]", combine="median", logfile=log, masktype="none", fl_vardq="yes") # Write the name of the final file to a standard file in the telluric directory open("telluricfile", "w").write("gxtfbrgn" + telluric)
def extractOneD(inputList, kind, log, over, extractionXC=15.0, extractionYC=33.0, extractionRadius=2.5): """Extracts 1-D spectra with iraf.nfextract and combines them with iraf.gemcombine. iraf.nfextract is currently only done interactively. Output: -->xtfbrsn and gxtfbrsn NFEXTRACT - Extract NIFS spectra. This could be used to extract a 1D spectra from IFU data and is particularly useful for extracting the bright spectra of telluric calibrator stars. Note that this routine only works on data that has been run through NFTRANSFORM. """ for frame in inputList: frame = str(frame).strip() if os.path.exists("xtfbrsn" + frame + ".fits"): if over: iraf.delete("xtfbrsn" + frame + ".fits") else: logging.info( "Output file exists and -over not set - skipping nfextract in extract1D" ) continue iraf.nfextract("tfbrsn" + frame, outpref="x", xc=extractionXC, yc=extractionYC, diameter=extractionRadius, fl_int='no', logfile=log) inputList = checkLists(inputList, '.', 'xtfbrsn', '.fits') # Combine all the 1D spectra to one final output file with the name of the first input file. combined = str(inputList[0]).strip() if len(inputList) > 1: if os.path.exists("gxtfbrsn" + combined + ".fits"): if over: iraf.delete("gxtfbrsn" + combined + ".fits") else: logging.info( "Output file exists and -over not set - skipping gemcombine in extract1D" ) return iraf.gemcombine(listit(inputList, "xtfbrsn"), output="gxtfbrsn" + combined, statsec="[*]", combine="median", masktype="none", fl_vardq="yes", logfile=log) else: if over: iraf.delete("gxtfbrsn" + combined + ".fits") iraf.copy(input="xtfbrsn" + combined + ".fits", output="gxtfbrsn" + combined + ".fits") if kind == 'Telluric': # Put the name of the final combined file into a text file called # telluricfile to be used by the pipeline later. open("telluricfile", "w").write("gxtfbrsn" + combined) elif kind == 'Science': open("combinedOneD", "w").write("gxtfbrsn" + combined)
call(["cp",darks,"darks.lis"]) #interact=sys.argv[8] if interact=='no': iraf.imdelete ("dark.fits", verify='no') iraf.delete ("fdarks.lis", verify='no') out4=out_to_a_file('fdarks.lis',"[email protected] ") ######### # # gemcombine fdarks # ########## iraf.gemcombine ("@fdarks.lis", "dark.fits", combine="average", fl_vardq='yes', logfile='f2.logfile', fl_dqprop='yes') iraf.display("dark.fits[sci]",3) sleep(5) # Dark subtract the prepared sky images # nsheaders sets nireduce.statsec = "[300:1748,300:1748]" iraf.delete ("fsky.lis", verify='no') ##sections "*****@*****.**" > "fsky.lis" # out4=out_to_a_file('fsky.lis',"[email protected] ") iraf.imdelete ("*****@*****.**", verify='no') iraf.niri.nireduce ("@fsky.lis", outprefix="d", fl_sky='no', fl_autosky='no', \
def ronchi(ronchilist, ronchiflat, calflat, over, flatdark, log): for image in ronchilist: image = str(image).strip() if over: iraf.delete("n" + image + '.fits') iraf.nfprepare(image, rawpath="", shiftimage="s" + calflat, bpm="rgn" + calflat + "_sflat_bpm.pl", fl_vardq="yes", fl_corr="no", fl_nonl="no", logfile=log) ronchilist = checkLists(ronchilist, '.', 'n', '.fits') # Determine the number of input Ronchi calibration mask files so that # the routine runs automatically for single or multiple files. if over: iraf.delete("gn" + ronchiflat + ".fits") if len(ronchilist) > 1: iraf.gemcombine(listit(ronchilist, "n"), output="gn" + ronchiflat, fl_dqpr="yes", masktype="none", fl_vardq="yes", logfile=log) else: iraf.copy("n" + ronchiflat + ".fits", "gn" + ronchiflat + ".fits") if over: iraf.delete("rgn" + ronchiflat + ".fits") iraf.nsreduce("gn" + ronchiflat, outpref="r", dark="rgn" + flatdark + "_dark", flatimage="rgn" + calflat + "_flat", fl_cut="yes", fl_nsappw="yes", fl_flat="yes", fl_sky="no", fl_dark="yes", fl_vardq="no", logfile=log) if over: iraf.delete("brgn" + ronchiflat + ".fits") iraf.nfsdist("rgn" + ronchiflat, fwidth=6.0, cradius=8.0, glshift=2.8, minsep=6.5, thresh=2000.0, nlost=3, fl_inter="no", logfile=log) # Put the name of the distortion file into a file of fixed name to be # used by the pipeline open("ronchifile", "w").write("rgn" + ronchiflat)
def reduceArc(arclist, arc, log, over): # flat field and cut the arc data shiftima = open("shiftfile", "r").readlines()[0].strip() sflat_bpm = open("sflat_bpmfile", "r").readlines()[0].strip() flat = open("flatfile", "r").readlines()[0].strip() dark = open("arcdarkfile", "r").readlines()[0].strip() for image in arclist: image = str(image).strip() if os.path.exists("n" + image + ".fits"): if over: iraf.delete("n" + image + ".fits") else: print "Output file exists and -over not set - skipping combine_ima" return iraf.nfprepare(image, rawpath="", shiftimage=shiftima, fl_vardq="yes", bpm=sflat_bpm, logfile=log) if os.path.exists("gn" + image + ".fits"): if over: iraf.delete("gn" + image + ".fits") else: print "Output file exists and -over not set - skipping apply_flat_arc" return arclist = checkLists(arclist, '.', 'n', '.fits') if len(arclist) > 1: iraf.gemcombine(listit(arclist, "n"), output="gn" + arc, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log) else: iraf.copy("n" + arc + ".fits", "gn" + arc + ".fits") if os.path.exists("rgn" + image + ".fits"): if over: iraf.delete("rgn" + image + ".fits") else: print "Output file exists and -over not set - skipping apply_flat_arc" return fl_dark = "no" if dark != "": fl_dark = "yes" hdulist = pyfits.open(arc + '.fits') if 'K_Long' in hdulist[0].header['GRATING']: iraf.nsreduce("gn" + arc, darki=dark, fl_cut="yes", fl_nsappw="yes", crval=23000., fl_dark="yes", fl_sky="no", fl_flat="yes", flatimage=flat, fl_vardq="no", logfile=log) else: iraf.nsreduce("gn" + arc, darki=dark, fl_cut="yes", fl_nsappw="yes", fl_dark="yes", fl_sky="no", fl_flat="yes", flatimage=flat, fl_vardq="no", logfile=log)
def makeFlat(flatlist, flatdarklist, calflat, flatdark, over, log): # make flat and bad pixel mask for image in flatlist: image = str(image).strip() if os.path.exists('n' + image + '.fits'): if over: os.remove('n' + image + '.fits') iraf.nfprepare(image + '.fits', rawpath='.', shiftim="s" + calflat, fl_vardq='yes', fl_int='yes', fl_corr='no', fl_nonl='no', logfile=log) else: print "Output exists and -over- not set - skipping nfprepare of flats" else: iraf.nfprepare(image + '.fits', rawpath='.', shiftim="s" + calflat, fl_vardq='yes', fl_int='yes', fl_corr='no', fl_nonl='no', logfile=log) flatlist = checkLists(flatlist, '.', 'n', '.fits') for image in flatdarklist: image = str(image).strip() if os.path.exists('n' + image + '.fits'): if over: iraf.delete('n' + image + '.fits') iraf.nfprepare(image + '.fits', rawpath='.', shiftim="s" + calflat, fl_vardq='yes', fl_int='yes', fl_corr='no', fl_nonl='no', logfile=log) else: print "Output exists and -over- not set - skipping nfprepare of flatdarks" else: iraf.nfprepare(image + '.fits', rawpath='.', shiftim="s" + calflat, fl_vardq='yes', fl_int='yes', fl_corr='no', fl_nonl='no', logfile=log) flatdarklist = checkLists(flatdarklist, '.', 'n', '.fits') if os.path.exists('gn' + calflat + '.fits'): if over: iraf.delete("gn" + calflat + ".fits") iraf.gemcombine(listit(flatlist, "n"), output="gn" + calflat, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log) else: print "Output exists and -over- not set - skipping gemcombine of flats" else: iraf.gemcombine(listit(flatlist, "n"), output="gn" + calflat, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log) if os.path.exists('gn' + flatdark + '.fits'): if over: iraf.delete("gn" + flatdark + ".fits") iraf.gemcombine(listit(flatdarklist, "n"), output="gn" + flatdark, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log) else: print "Output exists and -over- not set - skipping gemcombine of flatdarks" else: iraf.gemcombine(listit(flatdarklist, "n"), output="gn" + flatdark, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log) if os.path.exists('rgn' + calflat + '.fits'): if over: iraf.delete("rgn" + calflat + ".fits") iraf.nsreduce("gn" + calflat, fl_cut='yes', fl_nsappw='yes', fl_vardq='yes', fl_sky='no', fl_dark='no', fl_flat='no', logfile=log) else: print "Output exists and -over- not set - skipping" else: iraf.nsreduce("gn" + calflat, fl_cut='yes', fl_nsappw='yes', fl_vardq='yes', fl_sky='no', fl_dark='no', fl_flat='no', logfile=log) if over: iraf.delete("rgn" + flatdark + ".fits") iraf.nsreduce("gn" + flatdark, fl_cut='yes', fl_nsappw='yes', fl_vardq='yes', fl_sky='no', fl_dark='no', fl_flat='no', logfile=log) if over: iraf.delete("rgn" + flatdark + "_dark.fits") iraf.delete("rgn" + calflat + "_sflat.fits") iraf.delete("rgn" + calflat + "_sflat_bpm.pl") iraf.nsflat("rgn" + calflat, darks="rgn" + flatdark, flatfile="rgn" + calflat + "_sflat", darkfile="rgn" + flatdark + "_dark", fl_save_dark='yes', process="fit", thr_flo=0.15, thr_fup=1.55, fl_vardq='yes', logfile=log) #rectify the flat for slit function differences - make the final flat. if over: iraf.delete("rgn" + calflat + "_flat.fits") iraf.nsslitfunction("rgn" + calflat, "rgn" + calflat + "_flat", flat="rgn" + calflat + "_sflat", dark="rgn" + flatdark + "_dark", combine="median", order=3, fl_vary='no', logfile=log) # Put the name of the distortion file into a file of fixed name to be used by the pipeline open("flatfile", "w").write("rgn" + calflat + "_flat") open("sflatfile", "w").write("rgn" + calflat + "_sflat") open("sflat_bpmfile", "w").write("rgn" + calflat + "_sflat_bpm.pl")
def reduceArc(arclist, arc, arcdarklist, arcdark, log, over): """Flat field and cut the arc data with iraf.nfprepare and iraf.nsreduce. Processing with NFPREPARE will rename the data extension and add variance and data quality extensions. By default (see NSHEADERS) the extension names are SCI for science data, VAR for variance, and DQ for data quality (0 = good). Generation of the data quality plane (DQ) is important in order to fix hot and dark pixels on the NIFS detector in subsequent steps in the data reduction process. Various header keywords (used later) are also added in NFPREPARE. NFPREPARE will also add an MDF file (extension MDF) describing the NIFS image slicer pattern and how the IFU maps to the sky field. NSREDUCE is used for basic reduction of raw data - it provides a single, unified interface to several tasks and also allows for the subtraction of dark frames and dividing by the flat. For NIFS reduction, NSREDUCE is used to call the NSCUT and NSAPPWAVE routines. NSREDUCE resides in the GNIRS package. """ # Store the name of the shift image in "shiftima". shiftima = open("shiftfile", "r").readlines()[0].strip() # Store the name of the bad pixel mask in "sflat_bpm". sflat_bpm = open("sflat_bpmfile", "r").readlines()[0].strip() # Store the name of the final flat field frame in "flat". flat = open("flatfile", "r").readlines()[0].strip() # Update arc images with offset value and generate variance and data # quality extensions. Results in "n"+image+".fits" for image in arclist: image = str(image).strip() if os.path.exists("n"+image+".fits"): if over: iraf.delete("n"+image+".fits") else: print "\nOutput file exists and -over not set - skipping nfprepare of arcs." continue iraf.nfprepare(image, rawpath=".", shiftimage=shiftima,bpm=sflat_bpm,\ fl_vardq="yes",fl_corr='no',fl_nonl='no',logfile=log) # Check that output files for all arc images exists from nfprepare; if output does not # exist remove corresponding arc images from arclist. arclist = checkLists(arclist, '.', 'n', '.fits') # Update arc dark frames with mdf offset value and generate variance and data # quality extensions. Results in "n"+image+".fits" for image in arcdarklist: image = str(image).strip() if os.path.exists("n"+image+".fits"): if over: iraf.delete("n"+image+".fits") else: print "\nOutput file exists and -over not set - skipping nfprepare of arcdarks." continue iraf.nfprepare(image, rawpath=".", shiftimage=shiftima, bpm=sflat_bpm, \ fl_vardq='yes',fl_corr='no',fl_nonl='no',logfile=log) # Check that output files for all arc images exists from nfprepare; if output does not # exist remove corresponding arc images from arclist. arcdarklist = checkLists(arcdarklist, '.', 'n', '.fits') # Combine arc frames, "n"+image+".fits". Output combined file will have the name of the first arc file. if os.path.exists("gn"+arc+".fits"): if over: iraf.delete("gn"+arc+".fits") if len(arclist) > 1: iraf.gemcombine(listit(arclist,"n"),output="gn"+arc, fl_dqpr='yes',fl_vardq='yes',masktype="none",logfile=log) else: iraf.copy('n'+arc+'.fits', 'gn'+arc+'.fits') else: print "\nOutput file exists and -over not set - skipping gemcombine of arcs." else: if len(arclist) > 1: iraf.gemcombine(listit(arclist,"n"),output="gn"+arc, fl_dqpr='yes',fl_vardq='yes',masktype="none",logfile=log) else: iraf.copy('n'+arc+'.fits', 'gn'+arc+'.fits') # Combine arc dark frames, "n"+image+".fits". Output combined file will have the name of the first arc dark file. if os.path.exists("gn"+arcdark+".fits"): if over: iraf.delete("gn"+arcdark+".fits") if len(arcdarklist) > 1: iraf.gemcombine(listit(arcdarklist,"n"),output="gn"+arcdark, fl_dqpr='yes',fl_vardq='yes',masktype="none",logfile=log) else: iraf.copy('n'+arcdark+'.fits', 'gn'+arcdark+'.fits') else: print "\nOutput file exists and -over not set - skipping gemcombine of arcdarks." else: if len(arcdarklist) > 1: iraf.gemcombine(listit(arcdarklist,"n"),output="gn"+arcdark, fl_dqpr='yes',fl_vardq='yes',masktype="none",logfile=log) else: iraf.copy('n'+arcdark+'.fits', 'gn'+arcdark+'.fits') # Put the name of the combined and prepared arc dark frame "gn"+arcdark into a text # file called arcdarkfile to be used by the pipeline later. open("arcdarkfile", "w").write("gn"+arcdark) # NSREDUCE on arc images "gn"+arc+".fits" to extract the slices and apply an approximate # wavelength calibration. Results in "rgn"+image+".fits" if os.path.exists("rgn"+arc+".fits"): if over: iraf.delete("rgn"+arc+".fits") else: print "Output file exists and -over not set - skipping apply_flat_arc." return fl_dark = "no" if arcdark != "": fl_dark = "yes" hdulist = astropy.io.fits.open(arc+'.fits') if 'K_Long' in hdulist[0].header['GRATING']: iraf.nsreduce("gn"+arc, darki=arcdark, fl_cut="yes", fl_nsappw="yes", crval = 23000., fl_dark="yes", fl_sky="no", fl_flat="yes", flatimage=flat, fl_vardq="no",logfile=log) else: iraf.nsreduce("gn"+arc, darki="gn"+arcdark, flatimage=flat, \ fl_vardq="no", fl_cut="yes", fl_nsappw="yes", fl_sky="no", fl_dark="yes", fl_flat="yes", \ logfile=log) # Put the name of the combined and prepared arc dark frame "gn"+arcdark into a text # file called arcdarkfile to be used by the pipeline later. open("arcdarkfile", "w").write("gn"+arcdark)
def makeFlat(flatlist, flatdarklist, calflat, flatdark, over, log): """Make flat and bad pixel mask. Use NFPREPARE on the lamps on/lamps off flats to update the raw data headers and attach the mask definition file (MDF) as a binary table on all files. Note that dark frames will not have an MDF attached by default. Instead, the appropriate MDF is added in NSREDUCE or NSFLAT to match the data being reduced. Use NSREDUCE to cut the calibration (flat/arc) spectra to the size specified by the MDF, placing different IFU slices in separate image extensions. Use NSFLAT to generate a normalized flat field (for each IFU slice or cross-dispersed order) from lamp flats. A mask (BPM) will also be generated by thresholding - this can be used to flag bad pixels in other data. Use NSSLITFUNCTION to produce the final flat. NSSLITFUNCTION extends the flatfield produced by correcting the NSFLAT normalization for inter-slice variations. The output from this task is used as the flatfield image for further reduction. """ # Update lamps on flat frames with mdf offset value and generate variance and data quality extensions. for image in flatlist: image = str(image).strip() if os.path.exists('n'+image+'.fits'): if over: os.remove('n'+image+'.fits') iraf.nfprepare(image+'.fits',rawpath='.',shiftim="s"+calflat, fl_vardq='yes',fl_corr='no',fl_nonl='no', logfile=log) else: print "Output exists and -over- not set - skipping nfprepare of lamps on flats" else: iraf.nfprepare(image+'.fits',rawpath='.',shiftim="s"+calflat, fl_vardq='yes',fl_corr='no',fl_nonl='no', logfile=log) flatlist = checkLists(flatlist, '.', 'n', '.fits') # Update lamps off flat images with offset value and generate variance and data quality extensions. for image in flatdarklist: image = str(image).strip() if os.path.exists('n'+image+'.fits'): if over: iraf.delete('n'+image+'.fits') iraf.nfprepare(image+'.fits',rawpath='.',shiftim="s"+calflat, fl_vardq='yes',fl_corr='no',fl_nonl='no', logfile=log) else: print "\nOutput exists and -over- not set - skipping nfprepare of lamps off flats." else: iraf.nfprepare(image+'.fits',rawpath='.',shiftim="s"+calflat, fl_vardq='yes',fl_corr='no',fl_nonl='no', logfile=log) flatdarklist = checkLists(flatdarklist, '.', 'n', '.fits') # Combine lamps on flat images, "n"+image+".fits". Output combined file will have name of the first flat file with "gn" prefix. if os.path.exists('gn'+calflat+'.fits'): if over: iraf.delete("gn"+calflat+".fits") iraf.gemcombine(listit(flatlist,"n"),output="gn"+calflat,fl_dqpr='yes', fl_vardq='yes',masktype="none",logfile=log) else: print "\nOutput exists and -over- not set - skipping gemcombine of lamps on flats." else: iraf.gemcombine(listit(flatlist,"n"),output="gn"+calflat,fl_dqpr='yes', fl_vardq='yes',masktype="none",logfile=log) # Combine lamps off flat images, "n"+image+".fits". Output combined file will have name of the first darkflat file with "gn" prefix. if os.path.exists('gn'+flatdark+'.fits'): if over: iraf.delete("gn"+flatdark+".fits") iraf.gemcombine(listit(flatdarklist,"n"),output="gn"+flatdark,fl_dqpr='yes', fl_vardq='yes',masktype="none",logfile=log) else: print "\nOutput exists and -over- not set - skipping gemcombine of lamps off flats." else: iraf.gemcombine(listit(flatdarklist,"n"),output="gn"+flatdark,fl_dqpr='yes', fl_vardq='yes',masktype="none",logfile=log) # NSREDUCE on lamps on flat images, "gn"+calflat+".fits", to extract the slices and apply an approximate wavelength calibration. if os.path.exists('rgn'+calflat+'.fits'): if over: iraf.delete("rgn"+calflat+".fits") iraf.nsreduce ("gn"+calflat,fl_cut='yes',fl_nsappw='yes',fl_vardq='yes', fl_sky='no',fl_dark='no',fl_flat='no',logfile=log) else: print "\nOutput exists and -over- not set - skipping nsreduce of lamps on flats." else: iraf.nsreduce ("gn"+calflat,fl_cut='yes',fl_nsappw='yes',fl_vardq='yes', fl_sky='no',fl_dark='no',fl_flat='no',logfile=log) # NSREDUCE on lamps off flat frames, "gn"+flatdark+".fits", to extract the slices and apply an approximate wavelength calibration. if os.path.exists('rgn'+flatdark+'.fits'): if over: iraf.delete("rgn"+flatdark+".fits") iraf.nsreduce ("gn"+flatdark,fl_cut='yes',fl_nsappw='yes',fl_vardq='yes', fl_sky='no',fl_dark='no',fl_flat='no',logfile=log) else: print "\nOutput exists and -over- not set - skipping nsreduce of lamps off flats." else: iraf.nsreduce ("gn"+flatdark,fl_cut='yes',fl_nsappw='yes',fl_vardq='yes', fl_sky='no',fl_dark='no',fl_flat='no',logfile=log) # Create slice-by-slice flat field image and BPM image from the darkflats, using NSFLAT. # Lower and upper limit of bad pixels are 0.15 and 1.55. if over: iraf.delete("rgn"+flatdark+"_dark.fits") iraf.delete("rgn"+calflat+"_sflat.fits") iraf.delete("rgn"+calflat+"_sflat_bpm.pl") # Get the spectral band so we can fine tune thr_flo and thr_fup. This fine tunes the number of # bad pixels caught to an approximately constant level for each band. A few bad pixels will # not be caught, but it was found that catching them marked large portions of the top and bottom # rows of pixels of each slice as bad pixels. header = astropy.io.fits.open(calflat+'.fits') grat = header[0].header['GRATING'][0:1] if grat == 'Z' or grat == 'J': flo = 0.07 fup = 1.55 inter = 'no' elif grat == 'H' or grat == 'K': flo = 0.05 fup = 1.55 inter = 'no' else: print "\n#####################################################################" print "#####################################################################" print "" print " WARNING in baselineCalibration: nsflat detected a non-standard wavelength " print " configuration. Running interactively. " print "" print "#####################################################################" print "#####################################################################\n" # Arbitrary; not tested with non-standard configurations. flo = 0.15 fup = 1.55 inter = 'yes' iraf.nsflat("rgn"+calflat,darks="rgn"+flatdark,flatfile="rgn"+calflat+"_sflat", \ darkfile="rgn"+flatdark+"_dark", fl_save_dark='yes',process="fit", \ thr_flo=flo,thr_fup=fup, fl_vardq='yes', fl_int=inter, logfile=log ) # Renormalize the slices to account for slice-to-slice variations using NSSLITFUNCTION - make the final flat field image. if over: iraf.delete("rgn"+calflat+"_flat.fits") iraf.nsslitfunction("rgn"+calflat,"rgn"+calflat+"_flat", \ flat="rgn"+calflat+"_sflat",dark="rgn"+flatdark+"_dark",combine="median", \ order=3,fl_vary='no',logfile=log) # Put the name of the final flat field and bad pixel mask (BPM) into text files of fixed name to be used by the pipeline later. open("flatfile", "w").write("rgn"+calflat+"_flat") # Final flat field open("sflatfile", "w").write("rgn"+calflat+"_sflat") # Flat field before renormalization (before nsslitfunction) open("sflat_bpmfile", "w").write("rgn"+calflat+"_sflat_bpm.pl") # Bad Pixel Mask
def makeWaveCal(arclist, arc, arcdarklist, arcdark, log, over, path): """Determine the wavelength solution of each slice of the observation and set the arc coordinate file. If the user wishes to change the coordinate file to a different one, they need only to change the "clist" variable to their line list in the coordli= parameter in the nswavelength call. Uses NSWAVELENGTH to calibrate arc data (after cutting and optionally applying a flatfield with NSREDUCE in a previous step). DATA REDUCTION HINT - For the nswavelength call, the different wavelength settings use different vaues for some of the parameters. For optimal auto results, use: K-band: thresho=50.0, cradius=8.0 --> (gives rms of 0.1 to 0.3) H-band: thresho=100.0, cradius=8.0 --> (gives rms of 0.05 to 0.15) J-band: thresho=100.0 --> (gives rms of 0.03 to 0.09) Z-band: Currently not working very well for non-interactive mode Note that better RMS fits can be obtained by running the wavelength calibration interactively and identifying all of the lines manually. Tedious, but will give more accurate results than the automatic mode (i.e., fl_inter-). Use fl_inter+ for manual mode. """ # Store the name of the shift image in "shiftima". shiftima = open("shiftfile", "r").readlines()[0].strip() # Store the name of the bad pixel mask in "sflat_bpm". sflat_bpm = open("sflat_bpmfile", "r").readlines()[0].strip() # Store the name of the final flat field frame in "flat". flat = open("flatfile", "r").readlines()[0].strip() # Update arc images with offset value and generate variance and data # quality extensions. Results in "n"+image+".fits" for image in arclist: image = str(image).strip() if os.path.exists("n" + image + ".fits"): if over: iraf.delete("n" + image + ".fits") else: print "\nOutput file exists and -over not set - skipping nfprepare of arcs." continue iraf.nfprepare(image, rawpath=".", shiftimage=shiftima,bpm=sflat_bpm,\ fl_vardq="yes",fl_corr='no',fl_nonl='no',logfile=log) # Check that output files for all arc images exists from nfprepare; if output does not # exist remove corresponding arc images from arclist. arclist = checkLists(arclist, '.', 'n', '.fits') # Update arc dark frames with mdf offset value and generate variance and data # quality extensions. Results in "n"+image+".fits" for image in arcdarklist: image = str(image).strip() if os.path.exists("n" + image + ".fits"): if over: iraf.delete("n" + image + ".fits") else: print "\nOutput file exists and -over not set - skipping nfprepare of arcdarks." continue iraf.nfprepare(image, rawpath=".", shiftimage=shiftima, bpm=sflat_bpm, \ fl_vardq='yes',fl_corr='no',fl_nonl='no',logfile=log) # Check that output files for all arc images exists from nfprepare; if output does not # exist remove corresponding arc images from arclist. arcdarklist = checkLists(arcdarklist, '.', 'n', '.fits') # Combine arc frames, "n"+image+".fits". Output combined file will have the name of the first arc file. if os.path.exists("gn" + arc + ".fits"): if over: iraf.delete("gn" + arc + ".fits") if len(arclist) > 1: iraf.gemcombine(listit(arclist, "n"), output="gn" + arc, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log) else: iraf.copy('n' + arc + '.fits', 'gn' + arc + '.fits') else: print "\nOutput file exists and -over not set - skipping gemcombine of arcs." else: if len(arclist) > 1: iraf.gemcombine(listit(arclist, "n"), output="gn" + arc, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log) else: iraf.copy('n' + arc + '.fits', 'gn' + arc + '.fits') # Combine arc dark frames, "n"+image+".fits". Output combined file will have the name of the first arc dark file. if os.path.exists("gn" + arcdark + ".fits"): if over: iraf.delete("gn" + arcdark + ".fits") if len(arcdarklist) > 1: iraf.gemcombine(listit(arcdarklist, "n"), output="gn" + arcdark, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log) else: iraf.copy('n' + arcdark + '.fits', 'gn' + arcdark + '.fits') else: print "\nOutput file exists and -over not set - skipping gemcombine of arcdarks." else: if len(arcdarklist) > 1: iraf.gemcombine(listit(arcdarklist, "n"), output="gn" + arcdark, fl_dqpr='yes', fl_vardq='yes', masktype="none", logfile=log) else: iraf.copy('n' + arcdark + '.fits', 'gn' + arcdark + '.fits') # Put the name of the combined and prepared arc dark frame "gn"+arcdark into a text # file called arcdarkfile to be used by the pipeline later. open("arcdarkfile", "w").write("gn" + arcdark) # NSREDUCE on arc images "gn"+arc+".fits" to extract the slices and apply an approximate # wavelength calibration. Results in "rgn"+image+".fits" if os.path.exists("rgn" + arc + ".fits"): if over: iraf.delete("rgn" + arc + ".fits") else: print "Output file exists and -over not set - skipping apply_flat_arc." return fl_dark = "no" if arcdark != "": fl_dark = "yes" hdulist = astropy.io.fits.open(arc + '.fits') if 'K_Long' in hdulist[0].header['GRATING']: iraf.nsreduce("gn" + arc, darki=arcdark, fl_cut="yes", fl_nsappw="yes", crval=23000., fl_dark="yes", fl_sky="no", fl_flat="yes", flatimage=flat, fl_vardq="no", logfile=log) else: iraf.nsreduce("gn"+arc, darki="gn"+arcdark, flatimage=flat, \ fl_vardq="no", fl_cut="yes", fl_nsappw="yes", fl_sky="no", fl_dark="yes", fl_flat="yes", \ logfile=log) # Put the name of the combined and prepared arc dark frame "gn"+arcdark into a text # file called arcdarkfile to be used by the pipeline later. open("arcdarkfile", "w").write("gn" + arcdark) if os.path.exists("wrgn" + arc + ".fits"): if over: iraf.delete("wrgn" + arc + ".fits") else: print "\nOutput file exists and -over not set - ",\ "not determining wavelength solution and recreating the wavelength reference arc.\n" return # Determine the wavelength setting. hdulist = astropy.io.fits.open("rgn" + arc + ".fits") band = hdulist[0].header['GRATING'][0:1] central_wavelength = float(hdulist[0].header['GRATWAVE']) # Set interactive mode. Default False for standard configurations (and True for non-standard wavelength configurations ). pauseFlag = False if band == "K" and central_wavelength == 2.20: clist = RUNTIME_DATA_PATH + "k_ar.dat" my_thresh = 50.0 elif band == "J": clist = RUNTIME_DATA_PATH + "j_ar.dat" my_thresh = 100.0 elif band == "H": clist = RUNTIME_DATA_PATH + "h_ar.dat" my_thresh = 100.0 elif band == "Z": clist = "nifs$data/ArXe_Z.dat" my_thresh = 100.0 else: # Print a warning that the pipeline is being run with non-standard grating. print "\n#####################################################################" print "#####################################################################" print "" print " WARNING in calibrate: found a non-standard (non Z, J, H or K) " print " wavelength configuration." print " NSWAVELENGTH will be run interactively." print "" print "#####################################################################" print "#####################################################################\n" clist = "gnirs$data/argon.dat" my_thresh = 100.0 interactive = 'yes' if not pauseFlag: # Establish wavelength calibration for arclamp spectra. Output: A series of # files in a "database/" directory containing the wavelength solutions of # each slice and a reduced arc frame "wrgn"+ARC+".fits". iraf.nswavelength("rgn"+arc, coordli=clist, nsum=10, thresho=my_thresh, \ trace='yes', fwidth=2.0, match=-6,cradius=8.0,fl_inter='no',nfound=10,nlost=10, \ logfile=log) else: a = raw_input("For now, interactive Z or non-standard wavelength calibrations are unsupported. " + \ "Bugs running IRAF tasks interactively from python mean iraf.nswavelength cannot be activated automatically. " + \ "Therefore please run iraf.nswavelength() interactively from Pyraf to do a wavelength calibration by hand.")
import getopt