Example #1
0
def ReduceTwo(speclist, flatlist='', biaslist='', HeNeAr_file='',
               stdstar='', trace_recenter=False, ntracesteps=15,
               airmass_file='apoextinct.dat',
               flat_mode='spline', flat_order=9, flat_response=True,
               apwidth=8, skysep=3, skywidth=7, skydeg=0,
               HeNeAr_prev=False, HeNeAr_interac=True,
               HeNeAr_tol=20, HeNeAr_order=3, display_HeNeAr=False,
               std_mode='spline', std_order=12, display_std=False,
               trim=True, write_reduced=True,
               display=True, display_final=True):


    if (len(biaslist) > 0):
        bias = pydis.biascombine(biaslist, trim=trim)
    else:
        bias = 0.0

    if (len(biaslist) > 0) and (len(flatlist) > 0):
        flat,fmask_out = pydis.flatcombine(flatlist, bias, trim=trim,
                                           mode=flat_mode,display=False,
                                           flat_poly=flat_order, response=flat_response)
    else:
        flat = 1.0
        fmask_out = (1,)

    if HeNeAr_prev is False:
        prev = ''
    else:
        prev = HeNeAr_file+'.lines'

    # do the HeNeAr mapping first, must apply to all science frames
    if (len(HeNeAr_file) > 0):
        wfit = pydis.HeNeAr_fit(HeNeAr_file, trim=trim, fmask=fmask_out,
                                interac=HeNeAr_interac, previous=prev,mode='poly',
                                display=display_HeNeAr, tol=HeNeAr_tol,
                                fit_order=HeNeAr_order)

    # read in the list of target spectra
    # assumes specfile is a list of file names of object
    #-> wrap with array and flatten because Numpy sucks with one-element arrays...
    specfile = np.array([np.loadtxt(speclist, dtype='string')]).flatten()

    for i in range(len(specfile)):
        spec = specfile[i]
        print("> Processing file "+spec+" ["+str(i)+"/"+str(len(specfile))+"]")
        # raw, exptime, airmass, wapprox = pydis.OpenImg(spec, trim=trim)
        img = pydis.OpenImg(spec, trim=trim)
        raw = img.data
        exptime = img.exptime
        airmass = img.airmass
        wapprox = img.wavelength

        # remove bias and flat, divide by exptime
        data = ((raw - bias) / flat) / exptime

        if display is True:
            plt.figure()
            plt.imshow(np.log10(data), origin = 'lower',aspect='auto',cmap=cm.Greys_r)
            plt.title(spec+' (flat and bias corrected)')
            plt.show()

        # with reduced data, trace BOTH apertures
        trace_1 = pydis.ap_trace(data,fmask=fmask_out, nsteps=ntracesteps,
                                 recenter=trace_recenter, interac=True)
        trace_2 = pydis.ap_trace(data,fmask=fmask_out, nsteps=ntracesteps,
                                 recenter=trace_recenter, interac=True)


        xbins = np.arange(data.shape[1])
        if display is True:
            plt.figure()
            plt.imshow(np.log10(data), origin='lower',aspect='auto',cmap=cm.Greys_r)
            plt.plot(xbins, trace_1,'b',lw=1)
            plt.plot(xbins, trace_1-apwidth,'r',lw=1)
            plt.plot(xbins, trace_1+apwidth,'r',lw=1)
            plt.plot(xbins, trace_1-apwidth-skysep,'g',lw=1)
            plt.plot(xbins, trace_1-apwidth-skysep-skywidth,'g',lw=1)
            plt.plot(xbins, trace_1+apwidth+skysep,'g',lw=1)
            plt.plot(xbins, trace_1+apwidth+skysep+skywidth,'g',lw=1)

            plt.plot(xbins, trace_2,'b',lw=1)
            plt.plot(xbins, trace_2-apwidth,'r',lw=1)
            plt.plot(xbins, trace_2+apwidth,'r',lw=1)
            plt.plot(xbins, trace_2-apwidth-skysep,'g',lw=1)
            plt.plot(xbins, trace_2-apwidth-skysep-skywidth,'g',lw=1)
            plt.plot(xbins, trace_2+apwidth+skysep,'g',lw=1)
            plt.plot(xbins, trace_2+apwidth+skysep+skywidth,'g',lw=1)

            plt.title('(Both Traces, with aperture and sky regions)')
            plt.show()


        t_indx = 1
        # now do the processing for both traces as if separate stars
        for trace in [trace_1, trace_2]:
            tnum = '_' + str(t_indx)
            t_indx = t_indx + 1

            # extract the spectrum, measure sky values along trace, get flux errors
            ext_spec, sky, fluxerr = pydis.ap_extract(data, trace, apwidth=apwidth,
                                            skysep=skysep,skywidth=skywidth,
                                            skydeg=skydeg,coaddN=1)

            if (len(HeNeAr_file) > 0):
                wfinal = pydis.mapwavelength(trace, wfit, mode='poly')
            else:
                # if no line lamp given, use approx from the img header
                wfinal = wapprox

            # subtract local sky level, divide by exptime to get flux units
            #     (counts / sec)
            flux_red = (ext_spec - sky)

            # now correct the spectrum for airmass extinction
            flux_red_x = pydis.AirmassCor(wfinal, flux_red, airmass,
                                    airmass_file=airmass_file)

            # now get flux std IF stdstar is defined
            # !! assume first object in list is std star !!
            if (len(stdstar) > 0) and (i==0):
                sens_flux = pydis.DefFluxCal(wfinal, flux_red_x, stdstar=stdstar,
                                       mode=std_mode, polydeg=std_order, display=display_std)
                sens_wave = wfinal

            elif (len(stdstar) == 0) and (i==0):
                # if 1st obj not the std, then just make array of 1's to multiply thru
                sens_flux = np.ones_like(flux_red_x)
                sens_wave = wfinal

            # final step in reduction, apply sensfunc
            ffinal,efinal = pydis.ApplyFluxCal(wfinal, flux_red_x, fluxerr,
                                               sens_wave, sens_flux)

            if write_reduced is True:
                pydis._WriteSpec(spec+tnum, wfinal, ffinal, efinal, trace)

                now = datetime.datetime.now()

                lout = open(spec+tnum+'.log','w')
                lout.write('#  This file contains the reduction parameters \n'+
                           '#  used in autoreduce for '+spec+'\n')
                lout.write('DATE-REDUCED = '+str(now)+'\n')
                lout.write('HeNeAr_tol   = '+str(HeNeAr_tol)+'\n')
                lout.write('HeNeAr_order = '+str(HeNeAr_order)+'\n')
                lout.write('trace1       = '+str(False)+'\n')
                lout.write('ntracesteps  = '+str(ntracesteps)+'\n')
                lout.write('trim         = '+str(trim)+'\n')
                lout.write('response     = '+str(flat_response)+'\n')
                lout.write('apwidth      = '+str(apwidth)+'\n')
                lout.write('skysep       = '+str(skysep)+'\n')
                lout.write('skywidth     = '+str(skywidth)+'\n')
                lout.write('skydeg       = '+str(skydeg)+'\n')
                lout.write('stdstar      = '+str(stdstar)+'\n')
                lout.write('airmass_file = '+str(airmass_file)+'\n')
                lout.close()

            if display_final is True:
                # the final figure to plot
                plt.figure()
                # plt.plot(wfinal, ffinal)
                plt.errorbar(wfinal, ffinal, yerr=efinal)
                plt.xlabel('Wavelength')
                plt.ylabel('Flux')
                plt.title(spec)
                #plot within percentile limits
                plt.ylim( (np.percentile(ffinal,2),
                           np.percentile(ffinal,98)) )
                plt.show()
    return
Example #2
0
def autoreduce(speclist, flatlist='', biaslist='', HeNeAr_file='',
               stdstar='', trace_recenter=False, trace_interac=True,
               trace1=False, ntracesteps=15,
               airmass_file='apoextinct.dat',
               flat_mode='spline', flat_order=9, flat_response=True,
               apwidth=8, skysep=3, skywidth=7, skydeg=0,
               HeNeAr_prev=False, HeNeAr_interac=True,
               HeNeAr_tol=20, HeNeAr_order=3, display_HeNeAr=False,
               std_mode='spline', std_order=12, display_std=False,
               trim=True, write_reduced=True,
               display=True, display_final=True,
               silent=True):
    """
    A wrapper routine to carry out the full steps of the spectral
    reduction and calibration. Steps include:
    1) combines bias and flat images
    2) maps wavelength in the HeNeAr image
    3) perform simple image reduction: Data = (Raw - Bias)/Flat
    4) trace spectral aperture
    5) extract spectrum
    6) measure sky along extracted spectrum
    7) apply flux calibration
    8) write output files

    Parameters
    ----------
    speclist : str
        Path to file containing list of science images.
    flatlist : str
        Path to file containing list of flat images.
    biaslist : str
        Path to file containing list of bias images.
    HeNeAr_file : str
        Path to the HeNeAr calibration image
    stdstar : str
        Name of the standard star to use for flux calibration. Currently
        the IRAF library onedstds/spec50cal is used for flux calibration.
        Assumes the first star in "speclist" is the standard star. If
        nothing is entered for "stdstar", no flux calibration will be
        computed. (Default is '')
    trace1 : bool, optional
        use trace1=True if only perform aperture trace on first object in
        speclist. Useful if e.g. science targets are faint, and first
        object is a bright standard star. Note: assumes star placed at
        same position in spatial direction. (Default is False)
    trace_recenter : bool, optional
        If trace1=True, set this to True to allow for small linear
        adjustments to the trace (default is False)
    trace_interac : bool, optional
        Set to True if user should interactively select aperture center
        for each object spectrum. (Default is True)
    ntracesteps : int, optional
        Number of bins in X direction to chop image into. Use
        fewer bins if ap_trace is having difficulty, such as with faint
        targets (default here is 25, minimum is 4)
    apwidth : int, optional
        The width along the Y axis of the trace to extract. Note: a fixed
        width is used along the whole trace. (default here is 3 pixels)
    skysep : int, optional
        The separation in pixels from the aperture to the sky window.
        (Default is 25)
    skywidth : int, optional
        The width in pixels of the sky windows on either side of the
        aperture. (Default is 75)
    HeNeAr_interac : bool, optional
        Should the HeNeAr identification be done interactively (manually)?
        (Default here is False)
    HeNeAr_tol : int, optional
        When in automatic mode, the tolerance in pixel units between
        linelist entries and estimated wavelengths for the first few
        lines matched... use carefully. (Default here is 20)
    HeNeAr_order : int, optional
        The polynomial order to use to interpolate between identified
        peaks in the HeNeAr (Default is 2)
    display_HeNeAr : bool, optional
    std_mode : str, optional
        Fit mode to use with the flux standard star. Options are 'spline'
        and 'poly' (Default is 'spline')
    std_order : int, optional
        The order of polynomial to fit, if std_mode='poly'. (Default is 12)
    display_std : bool, optional
        If set, display plots of the flux standard being fit (Default is
        False)
    trim : bool, optional
        Trim the image using the DATASEC keyword in the header, assuming
        has format of [0:1024,0:512] (Default is True)
    write_reduced : bool, optional
        Set to True to write output files, including the .spec file with
        columns (wavelength, flux); the .trace file with columns
        (X pixel number, Y pixel of trace); .log file with record of
        settings used in this routine for reduction. (Default is True)
    display : bool, optional
        Set to True to display intermediate steps along the way.
        (Default is True)
    display_final : bool, optional
        Set to False to suppress plotting the final reduced spectrum to
        the screen. Useful for running in quiet batch mode. (Default is
        True)

    """

    if (len(biaslist) > 0):
        bias = pydis.biascombine(biaslist, trim=trim, silent=silent)
    else:
        bias = 0.0

    if (len(biaslist) > 0) and (len(flatlist) > 0):
        flat,fmask_out = pydis.flatcombine(flatlist, bias, trim=trim,
                                           mode=flat_mode,display=False,
                                           flat_poly=flat_order, response=flat_response)
    else:
        flat = 1.0
        fmask_out = (1,)


    if HeNeAr_prev is False:
        prev = ''
    else:
        prev = HeNeAr_file+'.lines'

    # do the HeNeAr mapping first, must apply to all science frames
    if (len(HeNeAr_file) > 0):
        wfit = pydis.HeNeAr_fit(HeNeAr_file, trim=trim, fmask=fmask_out,
                                interac=HeNeAr_interac, previous=prev,mode='poly',
                                display=display_HeNeAr, tol=HeNeAr_tol,
                                fit_order=HeNeAr_order)


    # read in the list of target spectra
    # assumes specfile is a list of file names of object
    specfile = np.array([np.loadtxt(speclist, dtype='string')]).flatten()

    for i in range(len(specfile)):
        spec = specfile[i]
        
        if silent is False:
            print("> Processing file "+spec+" ["+str(i)+"/"+str(len(specfile))+"]")

        # raw, exptime, airmass, wapprox = pydis.OpenImg(spec, trim=trim)
        img = pydis.OpenImg(spec, trim=trim)
        raw = img.data
        exptime = img.exptime
        airmass = img.airmass
        wapprox = img.wavelength


        # remove bias and flat, divide by exptime
        data = ((raw - bias) / flat) / exptime

        if display is True:
            plt.figure()
            plt.imshow(np.log10(data), origin = 'lower',aspect='auto',cmap=cm.Greys_r)
            plt.title(spec+' (flat and bias corrected)')
            plt.show()

        # with reduced data, trace the aperture
        if (i==0) or (trace1 is False):
            trace = pydis.ap_trace(data,fmask=fmask_out, nsteps=ntracesteps,
                             recenter=trace_recenter, interac=trace_interac)

        # extract the spectrum, measure sky values along trace, get flux errors
        ext_spec, sky, fluxerr = pydis.ap_extract(data, trace, apwidth=apwidth,
                                            skysep=skysep,skywidth=skywidth,
                                            skydeg=skydeg,coaddN=1)

        xbins = np.arange(data.shape[1])
        if display is True:
            plt.figure()
            plt.imshow(np.log10(data), origin='lower',aspect='auto',cmap=cm.Greys_r)
            plt.plot(xbins, trace,'b',lw=1)
            plt.plot(xbins, trace-apwidth,'r',lw=1)
            plt.plot(xbins, trace+apwidth,'r',lw=1)
            plt.plot(xbins, trace-apwidth-skysep,'g',lw=1)
            plt.plot(xbins, trace-apwidth-skysep-skywidth,'g',lw=1)
            plt.plot(xbins, trace+apwidth+skysep,'g',lw=1)
            plt.plot(xbins, trace+apwidth+skysep+skywidth,'g',lw=1)

            plt.title('(with trace, aperture, and sky regions)')
            plt.show()


        if (len(HeNeAr_file) > 0):
            wfinal = pydis.mapwavelength(trace, wfit, mode='poly')
        else:
            # if no line lamp given, use approx from the img header
            wfinal = wapprox

        # plt.figure()
        # plt.plot(wfinal,'r')
        # plt.show()

        # subtract local sky level, divide by exptime to get flux units
        #     (counts / sec)
        flux_red = (ext_spec - sky)

        # now correct the spectrum for airmass extinction
        flux_red_x = pydis.AirmassCor(wfinal, flux_red, airmass,
                                airmass_file=airmass_file)

        # now get flux std IF stdstar is defined
        # !! assume first object in list is std star !!
        if (len(stdstar) > 0) and (i==0):
            sens_flux = pydis.DefFluxCal(wfinal, flux_red_x, stdstar=stdstar,
                                   mode=std_mode, polydeg=std_order, display=display_std)
            sens_wave = wfinal

        elif (len(stdstar) == 0) and (i==0):
            # if 1st obj not the std, then just make array of 1's to multiply thru
            sens_flux = np.ones_like(flux_red_x)
            sens_wave = wfinal

        # final step in reduction, apply sensfunc
        ffinal,efinal = pydis.ApplyFluxCal(wfinal, flux_red_x, fluxerr,
                                           sens_wave, sens_flux)


        if write_reduced is True:
            pydis._WriteSpec(spec, wfinal, ffinal, efinal, trace)

            now = datetime.datetime.now()

            lout = open(spec+'.log','w')
            lout.write('#  This file contains the reduction parameters \n'+
                       '#  used in autoreduce for '+spec+'\n')
            lout.write('DATE-REDUCED = '+str(now)+'\n')
            lout.write('HeNeAr_tol   = '+str(HeNeAr_tol)+'\n')
            lout.write('HeNeAr_order = '+str(HeNeAr_order)+'\n')
            lout.write('trace1       = '+str(trace1)+'\n')
            lout.write('ntracesteps  = '+str(ntracesteps)+'\n')
            lout.write('trim         = '+str(trim)+'\n')
            lout.write('response     = '+str(flat_response)+'\n')
            lout.write('apwidth      = '+str(apwidth)+'\n')
            lout.write('skysep       = '+str(skysep)+'\n')
            lout.write('skywidth     = '+str(skywidth)+'\n')
            lout.write('skydeg       = '+str(skydeg)+'\n')
            lout.write('stdstar      = '+str(stdstar)+'\n')
            lout.write('airmass_file = '+str(airmass_file)+'\n')
            lout.close()


        if display_final is True:
            # the final figure to plot
            plt.figure()
            # plt.plot(wfinal, ffinal)
            plt.errorbar(wfinal, ffinal, yerr=efinal)
            plt.xlabel('Wavelength')
            plt.ylabel('Flux')
            plt.title(spec)
            #plot within percentile limits
            plt.ylim( (np.percentile(ffinal,2),
                       np.percentile(ffinal,98)) )
            plt.show()

    return
Example #3
0
def ReduceCoAdd(speclist, flatlist, biaslist, HeNeAr_file,
               stdstar='', trace1=False, ntracesteps=15,
               flat_mode='spline', flat_order=9, flat_response=True,
               apwidth=6,skysep=1,skywidth=7, skydeg=0,
               HeNeAr_prev=False, HeNeAr_interac=False,
               HeNeAr_tol=20, HeNeAr_order=2, displayHeNeAr=False,
               trim=True, write_reduced=True, display=True):
    """
    A special version of autoreduce, that assumes all the target images
    want to be median co-added and then extracted. All images have flat
    and bias removed first, then are combined. Trace and Extraction
    happens only on the final combined image.

    Assumes file names in speclist are the standard star, followed by all the target
    images you want to co-add.


    """
    #-- the basic crap, used for all frames
    bias = pydis.biascombine(biaslist, trim=trim)
    flat,fmask_out = pydis.flatcombine(flatlist, bias, trim=trim, mode=flat_mode,display=False,
                                 flat_poly=flat_order, response=flat_response)
    if HeNeAr_prev is False:
        prev = ''
    else:
        prev = HeNeAr_file+'.lines'
    wfit = pydis.HeNeAr_fit(HeNeAr_file, trim=trim, fmask=fmask_out, interac=HeNeAr_interac,
                      previous=prev,mode='poly',
                      display=displayHeNeAr, tol=HeNeAr_tol, fit_order=HeNeAr_order)

    #-- the standard star, set the stage
    specfile = np.array([np.loadtxt(speclist, dtype='string')]).flatten()
    spec = specfile[0]
    # raw, exptime, airmass, wapprox = pydis.OpenImg(spec, trim=trim)
    img = pydis.OpenImg(spec, trim=trim)
    raw = img.data
    exptime = img.exptime
    airmass = img.airmass
    wapprox = img.wavelength

    data = ((raw - bias) / flat) / exptime

    trace = pydis.ap_trace(data,fmask=fmask_out, nsteps=ntracesteps)
    # extract the spectrum, measure sky values along trace, get flux errors
    ext_spec, sky, fluxerr = pydis.ap_extract(data, trace, apwidth=apwidth,
                                        skysep=skysep,skywidth=skywidth,
                                        skydeg=skydeg,coaddN=1)
    xbins = np.arange(data.shape[1])
    wfinal = pydis.mapwavelength(trace, wfit, mode='poly')
    flux_red_x = (ext_spec - sky)
    sens_flux = pydis.DefFluxCal(wfinal, flux_red_x, stdstar=stdstar,
                           mode='spline',polydeg=12)
    sens_wave = wfinal
    ffinal,efinal = pydis.ApplyFluxCal(wfinal, flux_red_x, fluxerr, sens_wave, sens_flux)

    #-- the target star exposures, stack and proceed
    for i in range(1,len(specfile)):
        spec = specfile[i]
        # raw, exptime, airmass, wapprox = pydis.OpenImg(spec, trim=trim)
        img = pydis.OpenImg(spec, trim=trim)
        raw = img.data
        exptime = img.exptime
        airmass = img.airmass
        wapprox = img.wavelength
        data_i = ((raw - bias) / flat) / exptime
        if (i==1):
            all_data = data_i
        elif (i>1):
            all_data = np.dstack( (all_data, data_i))
    data = np.median(all_data, axis=2)
    # extract the spectrum, measure sky values along trace, get flux errors
    ext_spec, sky, fluxerr = pydis.ap_extract(data, trace, apwidth=apwidth,
                                        skysep=skysep,skywidth=skywidth,
                                        skydeg=skydeg,coaddN=len(specfile))
    xbins = np.arange(data.shape[1])
    wfinal = pydis.mapwavelength(trace, wfit, mode='poly')
    flux_red_x = (ext_spec - sky)
    ffinal,efinal = pydis.ApplyFluxCal(wfinal, flux_red_x, fluxerr, sens_wave, sens_flux)

    plt.figure()
    plt.plot(wfinal, ffinal)
    plt.title("CO-ADD DONE")
    plt.ylim( (np.percentile(ffinal,5),
               np.percentile(ffinal,95)) )
    plt.show()

    return wfinal, ffinal, efinal
Example #4
0
def ReduceCoAdd(speclist, flatlist, biaslist, HeNeAr_file,
               stdstar='', trace1=False, ntracesteps=15,
               flat_mode='spline', flat_order=9, flat_response=True,
               apwidth=6,skysep=1,skywidth=7, skydeg=0,
               HeNeAr_prev=False, HeNeAr_interac=False,
               HeNeAr_tol=20, HeNeAr_order=2, displayHeNeAr=False,
               trim=True, write_reduced=True, display=True):
    """
    A special version of autoreduce, that assumes all the target images
    want to be median co-added and then extracted. All images have flat
    and bias removed first, then are combined. Trace and Extraction
    happens only on the final combined image.

    Assumes file names in speclist are the standard star, followed by all the target
    images you want to co-add.


    """
    #-- the basic crap, used for all frames
    bias = pydis.biascombine(biaslist, trim=trim)
    flat,fmask_out = pydis.flatcombine(flatlist, bias, trim=trim, mode=flat_mode,display=False,
                                 flat_poly=flat_order, response=flat_response)
    
    
    
    
    
    
    
    
    
    
    # Going to need to add in something HERE for that multi henear stuffs!    
    if HeNeAr_prev is False:
        prev = ''
    else:
        prev = HeNeAr_file+'.lines'
    wfit = pydis.HeNeAr_fit(HeNeAr_file, trim=trim, fmask=fmask_out, interac=HeNeAr_interac,
                      previous=prev,mode='poly',
                      display=displayHeNeAr, tol=HeNeAr_tol, fit_order=HeNeAr_order)














    #-- the standard star, set the stage
    specfile = np.loadtxt(speclist,dtype='string')
    spec = specfile[0]
    # raw, exptime, airmass, wapprox = pydis.OpenImg(spec, trim=trim)
    img = pydis.OpenImg(spec, trim=trim)
    raw = img.data
    exptime = img.exptime
    airmass = img.airmass
    wapprox = img.wavelength

    data = ((raw - bias) / flat) / exptime

    trace = pydis.ap_trace(data,fmask=fmask_out, nsteps=ntracesteps)
    # extract the spectrum, measure sky values along trace, get flux errors
    ext_spec, sky, fluxerr = pydis.ap_extract(data, trace, apwidth=apwidth,
                                        skysep=skysep,skywidth=skywidth,
                                        skydeg=skydeg,coaddN=1)
    xbins = np.arange(data.shape[1])
    wfinal = pydis.mapwavelength(trace, wfit, mode='poly')
    flux_red_x = (ext_spec - sky)
    sens_flux = pydis.DefFluxCal(wfinal, flux_red_x, stdstar=stdstar,
                           mode='spline',polydeg=12)
    sens_wave = wfinal
    ffinal,efinal = pydis.ApplyFluxCal(wfinal, flux_red_x, fluxerr, sens_wave, sens_flux)

    #-- the target star exposures, stack and proceed
    for i in range(1,len(specfile)):
        spec = specfile[i]
        # raw, exptime, airmass, wapprox = pydis.OpenImg(spec, trim=trim)
        img = pydis.OpenImg(spec, trim=trim)
        raw = img.data
        exptime = img.exptime
        airmass = img.airmass
        wapprox = img.wavelength
        data_i = ((raw - bias) / flat) / exptime
        if (i==1):
            all_data = data_i
        elif (i>1):
            all_data = np.dstack( (all_data, data_i))
    data = np.median(all_data, axis=2)
    # extract the spectrum, measure sky values along trace, get flux errors
    ext_spec, sky, fluxerr = pydis.ap_extract(data, trace, apwidth=apwidth,
                                        skysep=skysep,skywidth=skywidth,
                                        skydeg=skydeg,coaddN=len(specfile))
    xbins = np.arange(data.shape[1])
    wfinal = pydis.mapwavelength(trace, wfit, mode='poly')
    flux_red_x = (ext_spec - sky)
    ffinal,efinal = pydis.ApplyFluxCal(wfinal, flux_red_x, fluxerr, sens_wave, sens_flux)

    plt.figure()
    plt.plot(wfinal, ffinal)
    plt.title("CO-ADD DONE")
    plt.ylim( (np.percentile(ffinal,5),
                   np.percentile(ffinal,95)) )
    plt.show()

    return wfinal, ffinal, efinal
Example #5
0
def autoHeNeAr(calimage,
               trim=True,
               maxdist=0.5,
               linelist='apohenear.dat',
               fmask=(0, ),
               display=False,
               noflatmask=False):
    '''
    (REWORD later)
    Find emission lines, match triangles to dictionary (hash table),
    filter out junk, check wavelength order, assign wavelengths!

    Parameters
    ----------
    calimage : str
        the calibration (HeNeAr) image file name you want to solve

    '''

    # !!! this should be changed to pydis.OpenImg ?
    hdu = fits.open(calimage)
    if trim is False:
        img = hdu[0].data
    if trim is True:
        datasec = hdu[0].header['DATASEC'][1:-1].replace(':', ',').split(',')
        d = map(float, datasec)
        img = hdu[0].data[d[2] - 1:d[3], d[0] - 1:d[1]]

    # this approach will be very DIS specific
    disp_approx = np.float(hdu[0].header['DISPDW'])
    wcen_approx = np.float(hdu[0].header['DISPWC'])

    # the red chip wavelength is backwards (DIS specific)
    clr = hdu[0].header['DETECTOR']
    if (clr.lower() == 'red'):
        sign = -1.0
    else:
        sign = 1.0
    hdu.close(closed=True)

    if noflatmask is True:
        ycomp = img.sum(axis=1)  # compress to spatial axis only
        illum_thresh = 0.5  # value compressed data must reach to be used for flat normalization
        ok = np.where((ycomp >= np.median(ycomp) * illum_thresh))
        fmask = ok[0]

    slice_width = 5.
    # take a slice thru the data in center row of chip
    slice = img[img.shape[0] / 2. - slice_width:img.shape[0] / 2. +
                slice_width, :].sum(axis=0)

    # use the header info to do rough solution (linear guess)
    wtemp = (np.arange(len(slice), dtype='float') -
             np.float(len(slice)) / 2.0) * disp_approx * sign + wcen_approx

    # if display is True:
    #     print('disp_approx',disp_approx)
    #     print('wcen_approx',wcen_approx)
    #     print(wtemp)
    #     print(wtemp[0])
    #     plt.figure()
    #     plt.plot(wtemp, slice)
    #     plt.show()

    pcent_pix, wcent_pix = pydis.find_peaks(wtemp,
                                            slice,
                                            pwidth=10,
                                            pthreshold=80,
                                            minsep=2)

    # if display is True:
    # print('>>>>>')
    # print(pcent_pix)
    # print(wcent_pix)
    # print(wcent_pix[1])
    # print('<<<<<')
    # plt.figure()
    # plt.scatter(pcent_pix, wcent_pix, alpha=0.5, s=50)
    # plt.show()

    # build observed triangles from HeNeAr file, in wavelength units
    tri_keys, tri_wave = _MakeTris(wcent_pix)
    '''print'>', (np.shape(wcent_pix),np.shape(tri_keys), np.shape(tri_wave))'''

    # make the same observed tri using pixel units.
    # ** should correspond directly **
    _, tri_pix = _MakeTris(pcent_pix)
    '''print('>> ',np.shape(pcent_pix), np.shape(tri_pix))'''

    # construct the standard object triangles (maybe could be restructured)
    dir = os.path.dirname(os.path.realpath(__file__)) + '/resources/linelists/'
    std_keys, std_wave = _BuildLineDict(dir + linelist)

    # now step thru each observed "tri", see if it matches any in "std"
    # within some tolerance (maybe say 5% for all 3 ratios?)

    # for each observed tri
    for i in range(tri_keys.shape[0]):
        obs = tri_keys[i, :]
        dist = []
        # search over every library tri, find nearest (BRUTE FORCE)
        for j in range(std_keys.shape[0]):
            ref = std_keys[j, :]
            dist.append(np.sum((obs - ref)**2.)**0.5)

        if (min(dist) < maxdist):
            indx = dist.index(min(dist))
            # replace the observed wavelengths with the catalog values
            tri_wave[i, :] = std_wave[indx, :]
        else:
            # need to do something better here too
            tri_wave[i, :] = np.array([np.nan, np.nan, np.nan])

    ok = np.where((np.isfinite(tri_wave)))

    out_wave = tri_wave[ok]
    out_pix = tri_pix[ok]

    out_wave.sort()
    out_pix.sort()

    xcent_big, ycent_big, wcent_big = pydis.line_trace(img,
                                                       out_pix,
                                                       out_wave,
                                                       fmask=fmask,
                                                       display=False)

    wfit = pydis.lines_to_surface(img,
                                  xcent_big,
                                  ycent_big,
                                  wcent_big,
                                  mode='spline')

    if display is True:
        plt.figure()
        plt.scatter(out_pix, out_wave)
        plt.plot(
            np.arange(len(slice)),
            pydis.mapwavelength(np.ones_like(slice) * img.shape[0] / 2.,
                                wfit,
                                mode='spline'))
        plt.title('autoHeNeAr Find')
        plt.xlabel('Pixel')
        plt.ylabel('Wavelength')
        plt.show()

    return wfit
Example #6
0
            plt.title('(with trace, aperture, and sky regions)')
            plt.show()







    #henear fit here! !!! Add other image mapping aferwards?  
    # assume each HeNeAr line found very carefully in the first image only moves slightly in the wavelength direction, 
    #so maybe just look for local max +/- 5 or 10 pixels from initial positions?


        if (len(HeNeAr_file) > 0):
            wfinal = pydis.mapwavelength(trace, wfit, mode='poly')
        else:
            # if no line lamp given, use approx from the img header
            wfinal = wapprox










        # plt.figure()
        # plt.plot(wfinal,'r')
Example #7
0
def ReduceTwo(speclist,
              flatlist='',
              biaslist='',
              HeNeAr_file='',
              stdstar='',
              trace_recenter=False,
              ntracesteps=15,
              airmass_file='apoextinct.dat',
              flat_mode='spline',
              flat_order=9,
              flat_response=True,
              apwidth=8,
              skysep=3,
              skywidth=7,
              skydeg=0,
              HeNeAr_prev=False,
              HeNeAr_interac=True,
              HeNeAr_tol=20,
              HeNeAr_order=3,
              display_HeNeAr=False,
              std_mode='spline',
              std_order=12,
              display_std=False,
              trim=True,
              write_reduced=True,
              display=True,
              display_final=True):

    if (len(biaslist) > 0):
        bias = pydis.biascombine(biaslist, trim=trim)
    else:
        bias = 0.0

    if (len(biaslist) > 0) and (len(flatlist) > 0):
        flat, fmask_out = pydis.flatcombine(flatlist,
                                            bias,
                                            trim=trim,
                                            mode=flat_mode,
                                            display=False,
                                            flat_poly=flat_order,
                                            response=flat_response)
    else:
        flat = 1.0
        fmask_out = (1, )

    if HeNeAr_prev is False:
        prev = ''
    else:
        prev = HeNeAr_file + '.lines'

    # do the HeNeAr mapping first, must apply to all science frames
    if (len(HeNeAr_file) > 0):
        wfit = pydis.HeNeAr_fit(HeNeAr_file,
                                trim=trim,
                                fmask=fmask_out,
                                interac=HeNeAr_interac,
                                previous=prev,
                                mode='poly',
                                display=display_HeNeAr,
                                tol=HeNeAr_tol,
                                fit_order=HeNeAr_order)

    # read in the list of target spectra
    # assumes specfile is a list of file names of object
    #-> wrap with array and flatten because Numpy sucks with one-element arrays...
    specfile = np.array([np.loadtxt(speclist, dtype='string')]).flatten()

    for i in range(len(specfile)):
        spec = specfile[i]
        print("> Processing file " + spec + " [" + str(i) + "/" +
              str(len(specfile)) + "]")
        # raw, exptime, airmass, wapprox = pydis.OpenImg(spec, trim=trim)
        img = pydis.OpenImg(spec, trim=trim)
        raw = img.data
        exptime = img.exptime
        airmass = img.airmass
        wapprox = img.wavelength

        # remove bias and flat, divide by exptime
        data = ((raw - bias) / flat) / exptime

        if display is True:
            plt.figure()
            plt.imshow(np.log10(data),
                       origin='lower',
                       aspect='auto',
                       cmap=cm.Greys_r)
            plt.title(spec + ' (flat and bias corrected)')
            plt.show()

        # with reduced data, trace BOTH apertures
        trace_1 = pydis.ap_trace(data,
                                 fmask=fmask_out,
                                 nsteps=ntracesteps,
                                 recenter=trace_recenter,
                                 interac=True)
        trace_2 = pydis.ap_trace(data,
                                 fmask=fmask_out,
                                 nsteps=ntracesteps,
                                 recenter=trace_recenter,
                                 interac=True)

        xbins = np.arange(data.shape[1])
        if display is True:
            plt.figure()
            plt.imshow(np.log10(data),
                       origin='lower',
                       aspect='auto',
                       cmap=cm.Greys_r)
            plt.plot(xbins, trace_1, 'b', lw=1)
            plt.plot(xbins, trace_1 - apwidth, 'r', lw=1)
            plt.plot(xbins, trace_1 + apwidth, 'r', lw=1)
            plt.plot(xbins, trace_1 - apwidth - skysep, 'g', lw=1)
            plt.plot(xbins, trace_1 - apwidth - skysep - skywidth, 'g', lw=1)
            plt.plot(xbins, trace_1 + apwidth + skysep, 'g', lw=1)
            plt.plot(xbins, trace_1 + apwidth + skysep + skywidth, 'g', lw=1)

            plt.plot(xbins, trace_2, 'b', lw=1)
            plt.plot(xbins, trace_2 - apwidth, 'r', lw=1)
            plt.plot(xbins, trace_2 + apwidth, 'r', lw=1)
            plt.plot(xbins, trace_2 - apwidth - skysep, 'g', lw=1)
            plt.plot(xbins, trace_2 - apwidth - skysep - skywidth, 'g', lw=1)
            plt.plot(xbins, trace_2 + apwidth + skysep, 'g', lw=1)
            plt.plot(xbins, trace_2 + apwidth + skysep + skywidth, 'g', lw=1)

            plt.title('(Both Traces, with aperture and sky regions)')
            plt.show()

        t_indx = 1
        # now do the processing for both traces as if separate stars
        for trace in [trace_1, trace_2]:
            tnum = '_' + str(t_indx)
            t_indx = t_indx + 1

            # extract the spectrum, measure sky values along trace, get flux errors
            ext_spec, sky, fluxerr = pydis.ap_extract(data,
                                                      trace,
                                                      apwidth=apwidth,
                                                      skysep=skysep,
                                                      skywidth=skywidth,
                                                      skydeg=skydeg,
                                                      coaddN=1)

            if (len(HeNeAr_file) > 0):
                wfinal = pydis.mapwavelength(trace, wfit, mode='poly')
            else:
                # if no line lamp given, use approx from the img header
                wfinal = wapprox

            # subtract local sky level, divide by exptime to get flux units
            #     (counts / sec)
            flux_red = (ext_spec - sky)

            # now correct the spectrum for airmass extinction
            flux_red_x = pydis.AirmassCor(wfinal,
                                          flux_red,
                                          airmass,
                                          airmass_file=airmass_file)

            # now get flux std IF stdstar is defined
            # !! assume first object in list is std star !!
            if (len(stdstar) > 0) and (i == 0):
                sens_flux = pydis.DefFluxCal(wfinal,
                                             flux_red_x,
                                             stdstar=stdstar,
                                             mode=std_mode,
                                             polydeg=std_order,
                                             display=display_std)
                sens_wave = wfinal

            elif (len(stdstar) == 0) and (i == 0):
                # if 1st obj not the std, then just make array of 1's to multiply thru
                sens_flux = np.ones_like(flux_red_x)
                sens_wave = wfinal

            # final step in reduction, apply sensfunc
            ffinal, efinal = pydis.ApplyFluxCal(wfinal, flux_red_x, fluxerr,
                                                sens_wave, sens_flux)

            if write_reduced is True:
                pydis._WriteSpec(spec + tnum, wfinal, ffinal, efinal, trace)

                now = datetime.datetime.now()

                lout = open(spec + tnum + '.log', 'w')
                lout.write(
                    '#  This file contains the reduction parameters \n' +
                    '#  used in autoreduce for ' + spec + '\n')
                lout.write('DATE-REDUCED = ' + str(now) + '\n')
                lout.write('HeNeAr_tol   = ' + str(HeNeAr_tol) + '\n')
                lout.write('HeNeAr_order = ' + str(HeNeAr_order) + '\n')
                lout.write('trace1       = ' + str(False) + '\n')
                lout.write('ntracesteps  = ' + str(ntracesteps) + '\n')
                lout.write('trim         = ' + str(trim) + '\n')
                lout.write('response     = ' + str(flat_response) + '\n')
                lout.write('apwidth      = ' + str(apwidth) + '\n')
                lout.write('skysep       = ' + str(skysep) + '\n')
                lout.write('skywidth     = ' + str(skywidth) + '\n')
                lout.write('skydeg       = ' + str(skydeg) + '\n')
                lout.write('stdstar      = ' + str(stdstar) + '\n')
                lout.write('airmass_file = ' + str(airmass_file) + '\n')
                lout.close()

            if display_final is True:
                # the final figure to plot
                plt.figure()
                # plt.plot(wfinal, ffinal)
                plt.errorbar(wfinal, ffinal, yerr=efinal)
                plt.xlabel('Wavelength')
                plt.ylabel('Flux')
                plt.title(spec)
                #plot within percentile limits
                plt.ylim((np.percentile(ffinal, 2), np.percentile(ffinal, 98)))
                plt.show()
    return
Example #8
0
def autoreduce(speclist,
               flatlist='',
               biaslist='',
               HeNeAr_file='',
               stdstar='',
               trace_recenter=False,
               trace_interac=True,
               trace1=False,
               ntracesteps=15,
               airmass_file='apoextinct.dat',
               flat_mode='spline',
               flat_order=9,
               flat_response=True,
               apwidth=8,
               skysep=3,
               skywidth=7,
               skydeg=0,
               HeNeAr_prev=False,
               HeNeAr_interac=True,
               HeNeAr_tol=20,
               HeNeAr_order=3,
               display_HeNeAr=False,
               std_mode='spline',
               std_order=12,
               display_std=False,
               trim=True,
               write_reduced=True,
               display=True,
               display_final=True,
               silent=True):
    """
    A wrapper routine to carry out the full steps of the spectral
    reduction and calibration. Steps include:
    1) combines bias and flat images
    2) maps wavelength in the HeNeAr image
    3) perform simple image reduction: Data = (Raw - Bias)/Flat
    4) trace spectral aperture
    5) extract spectrum
    6) measure sky along extracted spectrum
    7) apply flux calibration
    8) write output files

    Parameters
    ----------
    speclist : str
        Path to file containing list of science images.
    flatlist : str
        Path to file containing list of flat images.
    biaslist : str
        Path to file containing list of bias images.
    HeNeAr_file : str
        Path to the HeNeAr calibration image
    stdstar : str
        Name of the standard star to use for flux calibration. If
        nothing is entered for "stdstar", no flux calibration will be
        computed. (Default is '').
        NOTE1: must include the subdir for the star, e.g. 'spec50cal/feige34'.
        NOTE2: Assumes the first star in "speclist" is the standard star.
    trace1 : bool, optional
        use trace1=True if only perform aperture trace on first object in
        speclist. Useful if e.g. science targets are faint, and first
        object is a bright standard star. Note: assumes star placed at
        same position in spatial direction. (Default is False)
    trace_recenter : bool, optional
        If trace1=True, set this to True to allow for small linear
        adjustments to the trace (default is False)
    trace_interac : bool, optional
        Set to True if user should interactively select aperture center
        for each object spectrum. (Default is True)
    ntracesteps : int, optional
        Number of bins in X direction to chop image into. Use
        fewer bins if ap_trace is having difficulty, such as with faint
        targets (default here is 25, minimum is 4)
    apwidth : int, optional
        The width along the Y axis of the trace to extract. Note: a fixed
        width is used along the whole trace. (default here is 3 pixels)
    skysep : int, optional
        The separation in pixels from the aperture to the sky window.
        (Default is 25)
    skywidth : int, optional
        The width in pixels of the sky windows on either side of the
        aperture. (Default is 75)
    HeNeAr_interac : bool, optional
        Should the HeNeAr identification be done interactively (manually)?
        (Default here is False)
    HeNeAr_tol : int, optional
        When in automatic mode, the tolerance in pixel units between
        linelist entries and estimated wavelengths for the first few
        lines matched... use carefully. (Default here is 20)
    HeNeAr_order : int, optional
        The polynomial order to use to interpolate between identified
        peaks in the HeNeAr (Default is 2)
    display_HeNeAr : bool, optional
    std_mode : str, optional
        Fit mode to use with the flux standard star. Options are 'spline'
        and 'poly' (Default is 'spline')
    std_order : int, optional
        The order of polynomial to fit, if std_mode='poly'. (Default is 12)
    display_std : bool, optional
        If set, display plots of the flux standard being fit (Default is
        False)
    trim : bool, optional
        Trim the image using the DATASEC keyword in the header, assuming
        has format of [0:1024,0:512] (Default is True)
    write_reduced : bool, optional
        Set to True to write output files, including the .spec file with
        columns (wavelength, flux); the .trace file with columns
        (X pixel number, Y pixel of trace); .log file with record of
        settings used in this routine for reduction. (Default is True)
    display : bool, optional
        Set to True to display intermediate steps along the way.
        (Default is True)
    display_final : bool, optional
        Set to False to suppress plotting the final reduced spectrum to
        the screen. Useful for running in quiet batch mode. (Default is
        True)

    """

    if (len(biaslist) > 0):
        bias = pydis.biascombine(biaslist, trim=trim, silent=silent)
    else:
        bias = 0.0

    if (len(biaslist) > 0) and (len(flatlist) > 0):
        flat, fmask_out = pydis.flatcombine(flatlist,
                                            bias,
                                            trim=trim,
                                            mode=flat_mode,
                                            display=False,
                                            flat_poly=flat_order,
                                            response=flat_response)
    else:
        flat = 1.0
        fmask_out = (1, )

    if HeNeAr_prev is False:
        prev = ''
    else:
        prev = HeNeAr_file + '.lines'

    # do the HeNeAr mapping first, must apply to all science frames
    if (len(HeNeAr_file) > 0):
        wfit = pydis.HeNeAr_fit(HeNeAr_file,
                                trim=trim,
                                fmask=fmask_out,
                                interac=HeNeAr_interac,
                                previous=prev,
                                mode='poly',
                                display=display_HeNeAr,
                                tol=HeNeAr_tol,
                                fit_order=HeNeAr_order)

    # read in the list of target spectra
    # assumes specfile is a list of file names of object
    specfile = np.array([np.loadtxt(speclist, dtype='string')]).flatten()

    for i in range(len(specfile)):
        spec = specfile[i]

        if silent is False:
            print("> Processing file " + spec + " [" + str(i) + "/" +
                  str(len(specfile)) + "]")

        # raw, exptime, airmass, wapprox = pydis.OpenImg(spec, trim=trim)
        img = pydis.OpenImg(spec, trim=trim)
        raw = img.data
        exptime = img.exptime
        airmass = img.airmass
        wapprox = img.wavelength

        # remove bias and flat, divide by exptime
        data = ((raw - bias) / flat) / exptime

        if display is True:
            plt.figure()
            plt.imshow(np.log10(data),
                       origin='lower',
                       aspect='auto',
                       cmap=cm.Greys_r)
            plt.title(spec + ' (flat and bias corrected)')
            plt.show()

        # with reduced data, trace the aperture
        if (i == 0) or (trace1 is False):
            trace = pydis.ap_trace(data,
                                   fmask=fmask_out,
                                   nsteps=ntracesteps,
                                   recenter=trace_recenter,
                                   interac=trace_interac)

        # extract the spectrum, measure sky values along trace, get flux errors
        ext_spec, sky, fluxerr = pydis.ap_extract(data,
                                                  trace,
                                                  apwidth=apwidth,
                                                  skysep=skysep,
                                                  skywidth=skywidth,
                                                  skydeg=skydeg,
                                                  coaddN=1)

        xbins = np.arange(data.shape[1])
        if display is True:
            plt.figure()
            plt.imshow(np.log10(data),
                       origin='lower',
                       aspect='auto',
                       cmap=cm.Greys_r)
            plt.plot(xbins, trace, 'b', lw=1)
            plt.plot(xbins, trace - apwidth, 'r', lw=1)
            plt.plot(xbins, trace + apwidth, 'r', lw=1)
            plt.plot(xbins, trace - apwidth - skysep, 'g', lw=1)
            plt.plot(xbins, trace - apwidth - skysep - skywidth, 'g', lw=1)
            plt.plot(xbins, trace + apwidth + skysep, 'g', lw=1)
            plt.plot(xbins, trace + apwidth + skysep + skywidth, 'g', lw=1)

            plt.title('(with trace, aperture, and sky regions)')
            plt.show()

        if (len(HeNeAr_file) > 0):
            wfinal = pydis.mapwavelength(trace, wfit, mode='poly')
        else:
            # if no line lamp given, use approx from the img header
            wfinal = wapprox

        # plt.figure()
        # plt.plot(wfinal,'r')
        # plt.show()

        # subtract local sky level, divide by exptime to get flux units
        #     (counts / sec)
        flux_red = (ext_spec - sky)

        # now correct the spectrum for airmass extinction
        flux_red_x = pydis.AirmassCor(wfinal,
                                      flux_red,
                                      airmass,
                                      airmass_file=airmass_file)

        # now get flux std IF stdstar is defined
        # !! assume first object in list is std star !!
        if (len(stdstar) > 0) and (i == 0):
            sens_flux = pydis.DefFluxCal(wfinal,
                                         flux_red_x,
                                         stdstar=stdstar,
                                         mode=std_mode,
                                         polydeg=std_order,
                                         display=display_std)
            sens_wave = wfinal

        elif (len(stdstar) == 0) and (i == 0):
            # if 1st obj not the std, then just make array of 1's to multiply thru
            sens_flux = np.ones_like(flux_red_x)
            sens_wave = wfinal

        # final step in reduction, apply sensfunc
        ffinal, efinal = pydis.ApplyFluxCal(wfinal, flux_red_x, fluxerr,
                                            sens_wave, sens_flux)

        if write_reduced is True:
            pydis._WriteSpec(spec, wfinal, ffinal, efinal, trace)

            now = datetime.datetime.now()

            lout = open(spec + '.log', 'w')
            lout.write('#  This file contains the reduction parameters \n' +
                       '#  used in autoreduce for ' + spec + '\n')
            lout.write('DATE-REDUCED = ' + str(now) + '\n')
            lout.write('HeNeAr_tol   = ' + str(HeNeAr_tol) + '\n')
            lout.write('HeNeAr_order = ' + str(HeNeAr_order) + '\n')
            lout.write('trace1       = ' + str(trace1) + '\n')
            lout.write('ntracesteps  = ' + str(ntracesteps) + '\n')
            lout.write('trim         = ' + str(trim) + '\n')
            lout.write('response     = ' + str(flat_response) + '\n')
            lout.write('apwidth      = ' + str(apwidth) + '\n')
            lout.write('skysep       = ' + str(skysep) + '\n')
            lout.write('skywidth     = ' + str(skywidth) + '\n')
            lout.write('skydeg       = ' + str(skydeg) + '\n')
            lout.write('stdstar      = ' + str(stdstar) + '\n')
            lout.write('airmass_file = ' + str(airmass_file) + '\n')
            lout.close()

        if display_final is True:
            # the final figure to plot
            plt.figure()
            # plt.plot(wfinal, ffinal)
            plt.errorbar(wfinal, ffinal, yerr=efinal)
            plt.xlabel('Wavelength')
            plt.ylabel('Flux')
            plt.title(spec)
            #plot within percentile limits
            plt.ylim((np.percentile(ffinal, 2), np.percentile(ffinal, 98)))
            plt.show()

    return
Example #9
0
def autoHeNeAr(calimage, trim=True, maxdist=0.5, linelist='apohenear.dat',
               fmask=(0,), display=False):
    '''
    (REWORD later)
    Find emission lines, match triangles to dictionary (hash table),
    filter out junk, check wavelength order, assign wavelengths!

    Parameters
    ----------
    calimage : str
        the calibration (HeNeAr) image file name you want to solve

    '''

    # !!! this should be changed to pydis.OpenImg ?
    hdu = fits.open(calimage)
    if trim is False:
        img = hdu[0].data
    if trim is True:
        datasec = hdu[0].header['DATASEC'][1:-1].replace(':',',').split(',')
        d = map(float, datasec)
        img = hdu[0].data[d[2]-1:d[3],d[0]-1:d[1]]

    # this approach will be very DIS specific
    disp_approx = hdu[0].header['DISPDW']
    wcen_approx = hdu[0].header['DISPWC']

    # the red chip wavelength is backwards (DIS specific)
    clr = hdu[0].header['DETECTOR']
    if (clr.lower()=='red'):
        sign = -1.0
    else:
        sign = 1.0
    hdu.close(closed=True)

    # take a slice thru the data (+/- 10 pixels) in center row of chip
    slice = img[img.shape[0]/2-50:img.shape[0]/2+50,:].sum(axis=0)

    # use the header info to do rough solution (linear guess)
    wtemp = (np.arange(len(slice))-len(slice)/2) * disp_approx * sign + wcen_approx

    pcent_pix, wcent_pix = pydis.find_peaks(wtemp, slice, pwidth=15, pthreshold=90)

    # build observed triangles from HeNeAr file, in wavelength units
    tri_keys, tri_wave = _MakeTris(wcent_pix)

    # make the same observed tri using pixel units.
    # ** should correspond directly **
    _, tri_pix = _MakeTris(pcent_pix)

    # construct the standard object triangles (maybe could be restructured)
    std_keys, std_wave = _BuildLineDict(linelist=linelist)

    # now step thru each observed "tri", see if it matches any in "std"
    # within some tolerance (maybe say 5% for all 3 ratios?)

    # for each observed tri
    for i in range(tri_keys.shape[0]):
        obs = tri_keys[i,:]
        dist = []
        # search over every library tri, find nearest (BRUTE FORCE)
        for j in range(std_keys.shape[0]):
            ref = std_keys[j,:]
            dist.append( np.sum((obs-ref)**2.)**0.5 )

        if (min(dist)<maxdist):
            indx = dist.index(min(dist))
            # replace the observed wavelengths with the catalog values
            tri_wave[i,:] = std_wave[indx,:]
        else:
            # need to do something better here too
            tri_wave[i,:] = np.array([float('nan'), float('nan'), float('nan')])

    ok = np.where((np.isfinite(tri_wave)))

    out_wave = tri_wave[ok]
    out_pix = tri_pix[ok]

    out_wave.sort()
    out_pix.sort()

    xcent_big, ycent_big, wcent_big = pydis.line_trace(img, out_pix, out_wave,
                                                       fmask=fmask,display=True)

    wfit = pydis.lines_to_surface(img, xcent_big, ycent_big, wcent_big,
                            mode='spline')

    if display is True:
        plt.plot()
        plt.scatter(out_pix, out_wave)
        plt.plot(out_pix,
                 pydis.mapwavelength(np.ones_like(out_pix)*img.shape[0]/2,
                                     wfit, mode='spline'))
        plt.title('autoHeNeAr Find')
        plt.xlabel('Pixel')
        plt.ylabel('Wavelength')
        plt.show()

    return wfit
Example #10
0
def autoHeNeAr(calimage, trim=True, maxdist=0.5, linelist='apohenear.dat',
               fmask=(0,), display=False, noflatmask=False):
    '''
    (REWORD later)
    Find emission lines, match triangles to dictionary (hash table),
    filter out junk, check wavelength order, assign wavelengths!

    Parameters
    ----------
    calimage : str
        the calibration (HeNeAr) image file name you want to solve

    '''

    # !!! this should be changed to pydis.OpenImg ?
    hdu = fits.open(calimage)
    if trim is False:
        img = hdu[0].data
    if trim is True:
        datasec = hdu[0].header['DATASEC'][1:-1].replace(':',',').split(',')
        d = map(float, datasec)
        img = hdu[0].data[d[2]-1:d[3],d[0]-1:d[1]]

    # this approach will be very DIS specific
    disp_approx = np.float(hdu[0].header['DISPDW'])
    wcen_approx = np.float(hdu[0].header['DISPWC'])

    # the red chip wavelength is backwards (DIS specific)
    clr = hdu[0].header['DETECTOR']
    if (clr.lower()=='red'):
        sign = -1.0
    else:
        sign = 1.0
    hdu.close(closed=True)

    if noflatmask is True:
        ycomp = img.sum(axis=1) # compress to spatial axis only
        illum_thresh = 0.5 # value compressed data must reach to be used for flat normalization
        ok = np.where( (ycomp>= np.median(ycomp)*illum_thresh) )
        fmask = ok[0]

    slice_width = 5.
    # take a slice thru the data in center row of chip
    slice = img[img.shape[0]/2.-slice_width:img.shape[0]/2.+slice_width,:].sum(axis=0)

    # use the header info to do rough solution (linear guess)
    wtemp = (np.arange(len(slice),dtype='float') - np.float(len(slice))/2.0) * disp_approx * sign + wcen_approx

    # if display is True:
    #     print('disp_approx',disp_approx)
    #     print('wcen_approx',wcen_approx)
    #     print(wtemp)
    #     print(wtemp[0])
    #     plt.figure()
    #     plt.plot(wtemp, slice)
    #     plt.show()

    pcent_pix, wcent_pix = pydis.find_peaks(wtemp, slice, pwidth=10, pthreshold=80, minsep=2)

    # if display is True:
        # print('>>>>>')
        # print(pcent_pix)
        # print(wcent_pix)
        # print(wcent_pix[1])
        # print('<<<<<')
        # plt.figure()
        # plt.scatter(pcent_pix, wcent_pix, alpha=0.5, s=50)
        # plt.show()

    # build observed triangles from HeNeAr file, in wavelength units
    tri_keys, tri_wave = _MakeTris(wcent_pix)
    '''print'>', (np.shape(wcent_pix),np.shape(tri_keys), np.shape(tri_wave))'''

    # make the same observed tri using pixel units.
    # ** should correspond directly **
    _, tri_pix = _MakeTris(pcent_pix)
    '''print('>> ',np.shape(pcent_pix), np.shape(tri_pix))'''

    # construct the standard object triangles (maybe could be restructured)
    dir = os.path.dirname(os.path.realpath(__file__))+ '/resources/linelists/'
    std_keys, std_wave = _BuildLineDict(dir + linelist)

    # now step thru each observed "tri", see if it matches any in "std"
    # within some tolerance (maybe say 5% for all 3 ratios?)

    # for each observed tri
    for i in range(tri_keys.shape[0]):
        obs = tri_keys[i,:]
        dist = []
        # search over every library tri, find nearest (BRUTE FORCE)
        for j in range(std_keys.shape[0]):
            ref = std_keys[j,:]
            dist.append( np.sum((obs-ref)**2.)**0.5 )

        if (min(dist)<maxdist):
            indx = dist.index(min(dist))
            # replace the observed wavelengths with the catalog values
            tri_wave[i,:] = std_wave[indx,:]
        else:
            # need to do something better here too
            tri_wave[i,:] = np.array([np.nan, np.nan, np.nan])

    ok = np.where((np.isfinite(tri_wave)))

    out_wave = tri_wave[ok]
    out_pix = tri_pix[ok]

    out_wave.sort()
    out_pix.sort()

    xcent_big, ycent_big, wcent_big = pydis.line_trace(img, out_pix, out_wave,
                                                       fmask=fmask, display=False)

    wfit = pydis.lines_to_surface(img, xcent_big, ycent_big, wcent_big,
                            mode='spline')

    if display is True:
        plt.figure()
        plt.scatter(out_pix, out_wave)
        plt.plot(np.arange(len(slice)),
                 pydis.mapwavelength(np.ones_like(slice)*img.shape[0]/2.,
                                     wfit, mode='spline'))
        plt.title('autoHeNeAr Find')
        plt.xlabel('Pixel')
        plt.ylabel('Wavelength')
        plt.show()

    return wfit