Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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.")