Пример #1
0
def make_final_image(input_image, output_image,
                     desired_fwhm, clobber=False):
    """This routine makes the 'final' images for a data cube. At least the
    paths to the input image, output image, and output wavelength image are
    necessary for this. Beyond that, the user may also have the routine create
    uncertainty images as well.

    Images are convolved to the resolution 'desired_fwhm'. If the current fwhm
    is already higher than that, the routine will throw an error.

    A number of fits header keywords are necessary for this program to function
    properly. Any of these missing will throw an error.

    The output images are intensity-weighted, i.e. the wavelength image will be
    created such that the wavelengths at each pixel are the 'most likely'
    wavelength for the intensity at that pixel, etc.

    Inputs:
    input_image -> Path to the input image.
    output_image -> Path to the output image.
    desired_fwhm -> Desired FWHM for the resultant image to have.

    Optional Inputs:
    clobber -> Overwrite output images if they already exist. Default is False.

    """

    print "Making final data cube images for image "+input_image

    # Open the image
    image = FPImage(input_image)

    # Measure the sky background level in the input image
    skyavg, _truesig, skysig = image.skybackground()

    # Get various header keywords, crash if necessary
    intygrid = image.inty
    fwhm = image.fwhm
    wave0 = image.wave0
    calf = image.calf
    xcen = image.xcen
    ycen = image.ycen
    if fwhm is None:
        exit("Error! FWHM not measured for image "+input_image+".")
    if wave0 is None or calf is None:
        exit("Error! Wavelength solution does " +
             "not exist for image "+input_image+".")
    if xcen is None or ycen is None:
        exit("Error! Center values not measured " +
             "image "+input_image+".")
    if fwhm > desired_fwhm:
        exit("Error! Desired FWHM too low for image " +
             input_image+".")

    # Calculate the necessary FWHM for convolution
    fwhm_conv = np.sqrt(desired_fwhm**2-fwhm**2)
    # Magic number converts sigma to fwhm
    sig = fwhm_conv/2.3548
    # Extremely conservative "safe" kernel size
    ksize = np.ceil(4*sig)
    # Generate the gaussian kernel, shifted to shift the image
    kxgrid, kygrid = np.meshgrid(np.linspace(-ksize, ksize, 2*ksize+1),
                                 np.linspace(-ksize, ksize, 2*ksize+1))
    xshift, yshift = image.xshift, image.yshift
    rad2grid = (kxgrid + xshift)**2 + (kygrid + yshift)**2
    kern = np.exp(-rad2grid/(2*sig**2))

    # Normalize the kernel
    kern = kern/np.sum(kern)

    # Extract relevant arrays
    vargrid = image.vari
    badpixgrid = image.badp

    # Convolve the variances appropriately
    new_vargrid = convolve_variance(vargrid, badpixgrid, kern)

    # Add the sky background uncertainty to the uncertainty grid
    vargrid = vargrid+skysig**2

    # Create and convolve the wavelength array
    if image.wave is None:
        rgrid = image.rarray(xcen, ycen)
        wavegrid = wave0 / np.sqrt(1+rgrid**2/calf**2)
    else:
        wavegrid = image.wave
    new_wavegrid = convolve_wave(wavegrid, intygrid, badpixgrid, kern)

    # Convolve the intensity image
    new_intygrid = convolve_inty(intygrid, badpixgrid, kern)
    new_intygrid[new_intygrid == 0] = intygrid[new_intygrid == 0]
    new_intygrid[np.isnan(new_intygrid)] = intygrid[np.isnan(new_intygrid)]
    image.fwhm = desired_fwhm  # Update header FWHM keyword

    # Subtract the sky background from the image
    new_intygrid[new_intygrid != 0] -= skyavg

    # Create a new fits extension for the wavelength array
    if image.wave is None:
        waveheader = image.openimage[2].header.copy()
        waveheader['EXTVER'] = 4
        wavehdu = ImageHDU(data=new_wavegrid,
                           header=waveheader,
                           name="WAVE")
        image.openimage[1].header.set('WAVEEXT', 4,
                                      comment='Extension for Wavelength Frame')
        image.openimage.append(wavehdu)

    # Put all of the convolved images in the right extensions
    image.inty = new_intygrid
    image.vari = new_vargrid
    image.wave = new_wavegrid

    # Adjust header keywords (even though they're kinda irrelevant now)
    image.xcen += image.xshift
    image.ycen += image.yshift
    image.axcen += image.xshift
    image.aycen += image.yshift

    # Write the output file
    image.writeto(output_image, clobber=clobber)

    # Close images
    image.close()

    return