示例#1
0
    def convolve(self, kernel):
        """ Convovles the map, dealing with bad pixels

        Parameters
        ----------
        kernel: ndarray
          Input smoothing filter in real space.  Should be much smaller
          than the input map, or this will be quite slow.  Note that
          you want this to be transposed to follow the fits convention.

        Notes
        -----
          Currently does not alter the error information, just the
          actual map.  Uses brute-force (non-FFT) convolution, since
          this is usually faster for small kernels.
        """

        from astropy.nddata import convolve

        badpix = self.where_bad()
        nbad = len(badpix[0])

        # v0.2 of astropy.nddata.convolve modifies kernel, so make
        # a copy
        if nbad == 0:
            # Hey, no bad pixels.  probably a simulation, but easy
            self.image = convolve(self.image, kernel.copy(), boundary='wrap')
        else:
            self.image[badpix] = np.nan
            self.image = convolve(self.image, kernel.copy(), boundary='wrap')
示例#2
0
def convolve_images(images_with_headers):
    """
    Convolves all of the images to a common resolution using a simple
    gaussian kernel.

    Parameters
    ----------
    images_with_headers: zipped list structure
        A structure containing headers and image data for all FITS input
        images.

    """

    print("Convolving images")
    fwhm_input = get_fwhm_value(images_with_headers)
    print("fwhm_input = " + `fwhm_input`)

    for i in range(0, len(images_with_headers)):

        native_pixelscale = get_native_pixelscale(images_with_headers[i][1], get_instrument(images_with_headers[i][1]))
        sigma_input = fwhm_input / (2* math.sqrt(2*math.log (2) ) * native_pixelscale)
        print("Native pixel scale: " + `native_pixelscale`)
        print("Instrument: " + `get_instrument(images_with_headers[i][1])`)

        original_filename = os.path.basename(images_with_headers[i][2])
        original_directory = os.path.dirname(images_with_headers[i][2])
        new_directory = original_directory + "/convolved/"
        convolved_filename = new_directory + original_filename  + "_convolved.fits"
        input_directory = original_directory + "/registered/"
        input_filename = input_directory + original_filename  + "_registered.fits"
        print("Convolved filename: " + convolved_filename)
        print("Input filename: " + input_filename)
        if not os.path.exists(new_directory):
            os.makedirs(new_directory)

        # NOTETOSELF: there has been a loss of data from the data cubes at an earlier
        # step. The presence of 'EXTEND' and 'DSETS___' keywords in the header no
        # longer means that there is any data in hdulist[1].data. I am using a
        # workaround for now, but this needs to be looked at.
        hdulist = fits.open(input_filename)
        header = hdulist[0].header
        image_data = hdulist[0].data
        #if ('EXTEND' in header and 'DSETS___' in header):
            #image_data = hdulist[1].data
        #else:
            #image_data = hdulist[0].data
        hdulist.close()

        gaus_kernel_inp = make_kernel([3,3], kernelwidth=sigma_input, kerneltype='gaussian', trapslope=None, force_odd=True)

        # Do the convolution and save it as a new .fits file
        conv_result = convolve(image_data, gaus_kernel_inp)
        header['FWHM'] = (fwhm_input, 'The FWHM value used in the convolution step.')

        hdu = fits.PrimaryHDU(conv_result, header)
        print("Creating " + convolved_filename)
        hdu.writeto(convolved_filename, clobber=True)
示例#3
0
    def plot_image(self, wavelength0, overplot=False, inclination=None, cmap=None, ax=None,
            axes_units='AU',
            polarization=False, polfrac=False,
            psf_fwhm=None,
            vmin=None, vmax=None, dynamic_range=1e6, colorbar=False):
        """ Show one image from an MCFOST model

        Parameters
        ----------
        wavelength : string
            note this is a string!! in microns. TBD make it take strings or floats
        inclination : float
            Which inclination to plot, in the case where there are multiple images?
            If not specified, defaults to the median inclination of whichever RT mode
            inclinations were computed.
        overplot : bool
            Should we overplot on current axes (True) or display a new figure? Default is False
        cmap : matplotlib Colormap instance
            Color map to use for display.
        ax : matplotlib Axes instance
            Axis to display into.
        vmin, vmax :    scalars
            Min and max values for image display. Always shows in log stretch
        dynamic_range : float
            default vmin is vmax/dynamic range. Default dynamic range is 1e6.
        axes_units : str
            Units to label the axes in. May be 'AU', 'arcsec', 'deg', or 'pixels'
        psf_fwhm : float or None
            convolve with PSF of this FWHM? Default is None for no convolution
        colorbar : bool
            Also draw a colorbar



        To Do:
        * Add convolution with PSFs
        * Add coronagraphic occulters

        """

        wavelength = self._standardize_wavelength(wavelength0)
        if inclination is None:
            inclination = self.parameters.inclinations[len(self.parameters.inclinations)/2]

        if not overplot:
            if ax is None: plt.clf()
            else: plt.cla()


        if ax is None: ax = plt.gca()

        # Read in the data and select the image of

        imHDU = self.images[wavelength]


        inclin_index = mcfost.utils.find_closest(self.parameters.inclinations, inclination)
        image = imHDU.data[0,0,inclin_index,:,:]


        # Set up color mapping
        if cmap is None:
            from copy import deepcopy
            #cmap = plt.cm.gist_heat
            cmap = deepcopy(plt.cm.gist_gray)
            cmap.set_over('white')
            cmap.set_under('black')
            cmap.set_bad('black')
        if vmax is None: vmax = image.max()
        if vmin is None: vmin=vmax/dynamic_range
        norm = matplotlib.colors.LogNorm(vmin=vmin, vmax=vmax, clip=True)


        # calculate the display extent of the image

        # check if the image header has CDELT keywords, if so use those in preference to
        # the plate scale specified in the parameter file.
        # This will gracefully handle the case of the user overriding the default pixel
        # scale on the command line to MCFOST.
        cd1 = imHDU.header['CDELT1']
        cd2 = imHDU.header['CDELT2']
        pixelscale = np.asarray([cd1,cd2])  # in degrees

        if axes_units.lower() == 'deg':
            pass
        elif axes_units.lower() == 'arcsec':
            pixelscale *= 3600
        elif axes_units.lower() == 'au':
            pixelscale *= 3600 * self.parameters.distance
        elif axes_units.lower() == 'pixels' or axes_units.lower() == 'pixel':
            pixelscale = np.ones(2)
        else:
            raise ValueError("Unknown unit for axes_units: "+axes_units)

        halfsize = (np.asarray(image.shape))/2 * pixelscale
        extent = [-halfsize[0], halfsize[0], -halfsize[1], halfsize[1]]






        # Optional: convolve with PSF
        if psf_fwhm is not None:
            raise NotImplementedError("This code not yet implemented")
            import optics
            #psf = optics.airy_2d(aperture=10.0, wavelength=1.6e-6, pixelscale=0.020, shape=(99,99))
            psf = pyfits.getdata('/Users/mperrin/Dropbox/AAS2013/models_pds144n/manual/keck_psf_tmp4.fits')
            from astropy.nddata import convolve
            convolved = convolve(image, psf, normalize_kernel=True)

            image = convolved

        if polfrac:
            ax = plt.subplot(121)

        # Display the image!
        ax = mcfost.utils.imshow_with_mouseover(ax, image,  norm=norm, cmap=cmap, extent=extent)
        ax.set_xlabel("Offset [{unit}]".format(unit=axes_units))
        ax.set_ylabel("Offset [{unit}]".format(unit=axes_units))
        ax.set_title("Image for "+wavelength+" $\mu$m")


        if polarization==True:
            # overplot polarization vectors

            # don't show every pixel's vectors:
            showevery = 5

            imQ = imHDU.data[1,0,inclin_index,:,:] * -1  #MCFOST sign convention requires flip for +Q = up
            imU = imHDU.data[2,0,inclin_index,:,:] * -1  #MCFOST sign convention, ditto

            imQn = imQ/image
            imUn = imU/image
            polfrac_ar = np.sqrt(imQn**2 + imUn**2)
            theta = 0.5* np.arctan2(imUn, imQn) + np.pi/2
            vecX = polfrac_ar * np.cos(theta) *-1
            vecY = polfrac_ar * np.sin(theta)

            Y, X = np.indices(image.shape)
            Q = plt.quiver(X[::showevery, ::showevery], Y[::showevery, ::showevery], vecX[::showevery, ::showevery], vecY[::showevery, ::showevery],
                    headwidth=0, headlength=0, headaxislength=0.0, pivot='middle', color='white')
            plt.quiverkey(Q, 0.85, 0.95, 0.5, "50% pol.", coordinates='axes', labelcolor='white', labelpos='E', fontproperties={'size':'small'}) #, width=0.003)
    #        ax = plt.subplot(152)
    #        ax.imshow(imQn, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
    #        ax.set_title('Q')
    #        ax = plt.subplot(153)
    #        ax.imshow(imUn, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
    #        ax.set_title('U')
    #        ax = plt.subplot(154)
    #        ax.imshow(vecX, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
    #        ax.set_title('vecX')
    #        ax = plt.subplot(155)
    #        ax.imshow(vecY, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
    #        ax.set_title('vecY')
    #        ax.colorbar()

        #plt.colorbar()

            if polfrac:
                # Display a 2nd panel showing the polarization fraction
                ax2 = plt.subplot(122)

                cmap2 = plt.cm.gist_heat
                cmap2 = plt.cm.jet
                cmap2.set_over('red')
                cmap2.set_under('black')
                cmap2.set_bad('black')

                ax2 = mcfost.utils.imshow_with_mouseover(ax2, polfrac_ar, vmin=0, vmax=1,  cmap=cmap2)
                ax2.set_title("Polarization fraction")

                cax = plt.axes([0.92, 0.25, 0.02, 0.5])
                plt.colorbar(ax2.images[0], cax=cax, orientation='vertical')

        if colorbar==True:
            cb = plt.colorbar(mappable=ax.images[0])
            cb.set_label("Intensity [$W/m^2/pixel$]")
示例#4
0
def plot_image(wavelength, parfilename=None,par=None, dir="./", overplot=False, inclination=80, cmap=None, ax=None, 
        polarization=False, polfrac=False,
        psf_fwhm=None, 
        vmin=None, vmax=None, dynamic_range=1e6):
    """ Show one image from an MCFOST model

    Parameters
    ----------
    wavelength : string
        note this is a string!! in microns. TBD make it take strings or floats
    inclination : float
        Which inclination to plot, in the case where there are multiple images? For RT computations
        with just one, then this parameter is essentially ignored
    overplot : bool
        Should we overplot on current axes (True) or display a new figure? Default is False
    cmap : matplotlib Colormap instance
        Color map to use for display.
    ax : matplotlib Axes instance
        Axis to display into.
    vmin, vmax :    scalars
        Min and max values for image display. Always shows in log stretch
    dynamic_range : float
        default vmin is vmax/dynamic range. Default dynamic range is 1e6.
    psf_fwhm : float or None 
        convolve with PSF of this FWHM? Default is None for no convolution
    parfilename : string, optional
    par : dict, optional
    dir :  string

    """
    if not overplot:
        if ax is None: plt.clf()
        else: plt.cla()


    if ax is None: ax = plt.gca()
    if par is None:
        par = paramfiles.Paramfile(parfilename,dir)
    if cmap is None:
        cmap = plt.cm.gist_heat
        cmap = plt.cm.gist_gray
        cmap.set_over('white')
        cmap.set_under('black')
        cmap.set_bad('black')

    rt_im = fits.getdata(os.path.join(dir,"data_"+wavelength,"RT.fits.gz"))
    inclin_index = utils.find_closest(par.inclinations, inclination)
    #print "using image %s, inc=%f" % (  str(inclin_index), par['im:inclinations'][inclin_index]  )

    #ax = plt.subplot(151)
    image = rt_im[0,0,inclin_index,:,:]
    if vmax is None:
    #image.shape = image.shape[2:] # drop leading zero-length dimensions...
        vmax = image.max()
    if vmin is None:
        vmin=vmax/dynamic_range
    norm = matplotlib.colors.LogNorm(vmin=vmin, vmax=vmax, clip=True)

    if psf_fwhm is not None:
        raise NotImplementedError("This code not yet implemented")
        import optics
        #psf = optics.airy_2d(aperture=10.0, wavelength=1.6e-6, pixelscale=0.020, shape=(99,99))
        psf = pyfits.getdata('/Users/mperrin/Dropbox/AAS2013/models_pds144n/manual/keck_psf_tmp4.fits')
        from astropy.nddata import convolve
        convolved = convolve(image, psf, normalize_kernel=True)

        image = convolved

    if polfrac:
        ax = plt.subplot(121)

    ax = utils.imshow_with_mouseover(ax, image,  norm=norm, cmap=cmap)
    ax.set_xlabel("Offset [pix]")
    ax.set_ylabel("Offset [pix]")
    ax.set_title(wavelength+" $\mu$m")


    if polarization==True:

        # dont' show every pixel's vectors:
        showevery = 5

        imQ = rt_im[1,0,inclin_index,:,:] * -1  #MCFOST sign convention requires flip for +Q = up
        imU = rt_im[2,0,inclin_index,:,:] * -1  #MCFOST sign convention

        imQn = imQ/image
        imUn = imU/image
        polfrac_ar = np.sqrt(imQn**2 + imUn**2)
        theta = 0.5* np.arctan2(imUn, imQn) + np.pi/2
        vecX = polfrac_ar * np.cos(theta) *-1
        vecY = polfrac_ar * np.sin(theta)

        Y, X = np.indices(image.shape)
        Q = plt.quiver(X[::showevery, ::showevery], Y[::showevery, ::showevery], vecX[::showevery, ::showevery], vecY[::showevery, ::showevery],
                headwidth=0, headlength=0, headaxislength=0.0, pivot='middle', color='white')
        plt.quiverkey(Q, 0.85, 0.95, 0.5, "50% pol.", coordinates='axes', labelcolor='white', labelpos='E', fontproperties={'size':'small'}) #, width=0.003)
#        ax = plt.subplot(152)
#        ax.imshow(imQn, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
#        ax.set_title('Q')
#        ax = plt.subplot(153)
#        ax.imshow(imUn, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
#        ax.set_title('U')
#        ax = plt.subplot(154)
#        ax.imshow(vecX, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
#        ax.set_title('vecX')
#        ax = plt.subplot(155)
#        ax.imshow(vecY, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
#        ax.set_title('vecY')
#        ax.colorbar()

    #plt.colorbar()

        if polfrac:
            ax2 = plt.subplot(122)

            cmap2 = plt.cm.gist_heat
            cmap2 = plt.cm.jet
            cmap2.set_over('red')
            cmap2.set_under('black')
            cmap2.set_bad('black')

            ax2 = imshow_with_mouseover(ax2, polfrac_ar, vmin=0, vmax=1,  cmap=cmap2)
            ax2.set_title("Polarization fraction")

            cax = plt.axes([0.92, 0.25, 0.02, 0.5])
            plt.colorbar(ax2.images[0], cax=cax, orientation='vertical')
示例#5
0
#-------------------------------------------------------------------------------------------------------------
# looping over images and convolving
for ii in range(Nfiles):
    fitsIN   = files[ii]
    PNfitsIN = pathAname(fitsIN)
    hdulist  = pyfits.open(fitsIN)  # reading HDU list of fits image
    arrIN    = hdulist[0].data   # loading image into array
    imgdim   = arrIN.shape

    if dim > min(imgdim): # checking that kernel dimension is smaller than fits image dimension
        print ':: '+sys.argv[0]+' :: ERROR Dimesion of the kernel is larger than the input image:'
        print fitsIN
        print ':: '+sys.argv[0]+' :: --> ABORTING'
        sys.exit()

    arrOUT = astro.convolve(arrIN, kernel)

    # creating and writing output fits file
    replacestr = '_convolvedFWHM'+str(sigma*2.35).replace('.','p')+'arcsec.fits'
    fitsOUT    = fitsIN.replace('.fits',replacestr)  # creating name of output fits image
    hduOUT     = pyfits.PrimaryHDU(arrOUT)
    hdulistOUT = pyfits.HDUList([hduOUT])

    # --- Editing header of file (keyword max 8 characters) ---
    hdulistOUT[0].header['inputimg'] = PNfitsIN[1]
    hdulistOUT[0].header['pixsize']  = (pixdim, '[arcsec/pix] size of pixels in FITSIN')
    hdulistOUT[0].header['kFWHM']    = (sigma*2.35, '[arcsec] FWHM of kernel (ksigma*2.35)')
    hdulistOUT[0].header['ksigma']   = (sigma, '[arcsec] width (sigma) of kernel')
    hdulistOUT[0].header['kwpix']    = (kernelwidth, '[pix] width (sigma) of kernel')
    hdulistOUT[0].header['kdim']     = (dim, '[pix] dimension of kernel: KDIMxKDIM')
    hdulistOUT[0].header['ktype']    = (kerneltype, 'Kernel used by astropy.nddata.make_kernel')
示例#6
0
    def plot_image(self,
                   wavelength0,
                   overplot=False,
                   inclination=None,
                   cmap=None,
                   ax=None,
                   axes_units='AU',
                   polarization=False,
                   polfrac=False,
                   psf_fwhm=None,
                   vmin=None,
                   vmax=None,
                   dynamic_range=1e6,
                   colorbar=False):
        """ Show one image from an MCFOST model

        Parameters
        ----------
        wavelength : string
            note this is a string!! in microns. TBD make it take strings or floats
        inclination : float
            Which inclination to plot, in the case where there are multiple images?
            If not specified, defaults to the median inclination of whichever RT mode
            inclinations were computed.
        overplot : bool
            Should we overplot on current axes (True) or display a new figure? Default is False
        cmap : matplotlib Colormap instance
            Color map to use for display.
        ax : matplotlib Axes instance
            Axis to display into.
        vmin, vmax :    scalars
            Min and max values for image display. Always shows in log stretch
        dynamic_range : float
            default vmin is vmax/dynamic range. Default dynamic range is 1e6.
        axes_units : str
            Units to label the axes in. May be 'AU', 'arcsec', 'deg', or 'pixels'
        psf_fwhm : float or None
            convolve with PSF of this FWHM? Default is None for no convolution
        colorbar : bool
            Also draw a colorbar


        To Do:
        * Add convolution with PSFs
        * Add coronagraphic occulters

        """

        wavelength = self._standardize_wavelength(wavelength0)
        if inclination is None:
            inclination = self.parameters.inclinations[len(
                self.parameters.inclinations) / 2]

        if not overplot:
            if ax is None: plt.clf()
            else: plt.cla()

        if ax is None: ax = plt.gca()

        # Read in the data and select the image of

        imHDU = self.images[wavelength]

        inclin_index = utils.find_closest(self.parameters.inclinations,
                                          inclination)
        image = imHDU.data[0, 0, inclin_index, :, :]

        # Set up color mapping
        if cmap is None:
            from copy import deepcopy
            #cmap = plt.cm.gist_heat
            cmap = deepcopy(plt.cm.gist_gray)
            cmap.set_over('white')
            cmap.set_under('black')
            cmap.set_bad('black')
        if vmax is None: vmax = image.max()
        if vmin is None: vmin = vmax / dynamic_range
        norm = matplotlib.colors.LogNorm(vmin=vmin, vmax=vmax, clip=True)

        # calculate the display extent of the image

        # check if the image header has CDELT keywords, if so use those in preference to
        # the plate scale specified in the parameter file.
        # This will gracefully handle the case of the user overriding the default pixel
        # scale on the command line to MCFOST.
        cd1 = imHDU.header['CDELT1']
        cd2 = imHDU.header['CDELT2']
        pixelscale = np.asarray([cd1, cd2])  # in degrees

        if axes_units.lower() == 'deg':
            pass
        elif axes_units.lower() == 'arcsec':
            pixelscale *= 3600
        elif axes_units.lower() == 'au':
            pixelscale *= 3600 * self.parameters.distance
        elif axes_units.lower() == 'pixels' or axes_units.lower() == 'pixel':
            pixelscale = np.ones(2)
        else:
            raise ValueError("Unknown unit for axes_units: " + axes_units)

        halfsize = (np.asarray(image.shape)) / 2 * pixelscale
        extent = [-halfsize[0], halfsize[0], -halfsize[1], halfsize[1]]

        # Optional: convolve with PSF
        if psf_fwhm is not None:
            raise NotImplementedError("This code not yet implemented")
            import optics
            #psf = optics.airy_2d(aperture=10.0, wavelength=1.6e-6, pixelscale=0.020, shape=(99,99))
            psf = pyfits.getdata(
                '/Users/mperrin/Dropbox/AAS2013/models_pds144n/manual/keck_psf_tmp4.fits'
            )
            from astropy.nddata import convolve
            convolved = convolve(image, psf, normalize_kernel=True)

            image = convolved

        if polfrac:
            ax = plt.subplot(121)

        # Display the image!
        ax = utils.imshow_with_mouseover(ax,
                                         image,
                                         norm=norm,
                                         cmap=cmap,
                                         extent=extent,
                                         origin='lower')
        ax.set_xlabel("Offset [{unit}]".format(unit=axes_units))
        ax.set_ylabel("Offset [{unit}]".format(unit=axes_units))
        ax.set_title("Image for " + wavelength + " $\mu$m")

        if polarization == True:
            # overplot polarization vectors

            # don't show every pixel's vectors:
            showevery = 5

            imQ = imHDU.data[
                1, 0,
                inclin_index, :, :] * -1  #MCFOST sign convention requires flip for +Q = up
            imU = imHDU.data[
                2, 0, inclin_index, :, :] * -1  #MCFOST sign convention, ditto

            imQn = imQ / image
            imUn = imU / image
            polfrac_ar = np.sqrt(imQn**2 + imUn**2)
            theta = 0.5 * np.arctan2(imUn, imQn) + np.pi / 2
            vecX = polfrac_ar * np.cos(theta) * -1
            vecY = polfrac_ar * np.sin(theta)

            Y, X = np.indices(image.shape)
            Q = plt.quiver(X[::showevery, ::showevery],
                           Y[::showevery, ::showevery],
                           vecX[::showevery, ::showevery],
                           vecY[::showevery, ::showevery],
                           headwidth=0,
                           headlength=0,
                           headaxislength=0.0,
                           pivot='middle',
                           color='white')
            plt.quiverkey(Q,
                          0.85,
                          0.95,
                          0.5,
                          "50% pol.",
                          coordinates='axes',
                          labelcolor='white',
                          labelpos='E',
                          fontproperties={'size': 'small'})  #, width=0.003)
            #        ax = plt.subplot(152)
            #        ax.imshow(imQn, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
            #        ax.set_title('Q')
            #        ax = plt.subplot(153)
            #        ax.imshow(imUn, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
            #        ax.set_title('U')
            #        ax = plt.subplot(154)
            #        ax.imshow(vecX, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
            #        ax.set_title('vecX')
            #        ax = plt.subplot(155)
            #        ax.imshow(vecY, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
            #        ax.set_title('vecY')
            #        ax.colorbar()

            #plt.colorbar()

            if polfrac:
                # Display a 2nd panel showing the polarization fraction
                ax2 = plt.subplot(122)

                cmap2 = plt.cm.gist_heat
                cmap2 = plt.cm.jet
                cmap2.set_over('red')
                cmap2.set_under('black')
                cmap2.set_bad('black')

                ax2 = utils.imshow_with_mouseover(ax2,
                                                  polfrac_ar,
                                                  vmin=0,
                                                  vmax=1,
                                                  cmap=cmap2)
                ax2.set_title("Polarization fraction")

                cax = plt.axes([0.92, 0.25, 0.02, 0.5])
                plt.colorbar(ax2.images[0], cax=cax, orientation='vertical')

        if colorbar == True:
            cb = plt.colorbar(mappable=ax.images[0])
            cb.set_label("Intensity [$W/m^2/pixel$]")
示例#7
0
def show_image(wavelength,
               parfilename=None,
               par=None,
               dir="./",
               overplot=False,
               inclination=80,
               cmap=None,
               ax=None,
               polarization=False,
               polfrac=False,
               psf_fwhm=None,
               vmin=None,
               vmax=None):
    """ Show one image from an MCFOST model

    Parameters
    ----------
    wavelength : string
        note this is a string!! in microns. TBD make it take strings or floats
    inclination : float
        Which inclination to plot, in the case where there are multiple images? For RT computations
        with just one, then this parameter is essentially ignored
    overplot : bool
        Should we overplot on current axes (True) or display a new figure? Default is False
    cmap : matplotlib Colormap instance
        Color map to use for display.
    ax : matplotlib Axes instance
        Axis to display into.
    vmin, vmax :    scalars
        Min and max values for image display. Always shows in log stretch
    psf_fwhm : float or None 
        convolve with PSF of this FWHM? Default is None for no convolution
    parfilename : string, optional
    par : dict, optional
    dir :  string

    """
    if not overplot:
        if ax is None: plt.clf()
        else: plt.cla()

    if ax is None: ax = plt.gca()
    if par is None:
        par = paramfiles.Paramfile(parfilename, dir)
    if cmap is None:
        cmap = plt.cm.gist_heat
        cmap = plt.cm.gist_gray
        cmap.set_over('white')
        cmap.set_under('black')
        cmap.set_bad('black')

    rt_im = fits.getdata(dir + os.sep + "data_" + wavelength + os.sep +
                         "RT.fits.gz")
    inclin_index = _find_closest(par.im_inclinations, inclination)
    #print "using image %s, inc=%f" % (  str(inclin_index), par['im:inclinations'][inclin_index]  )

    #ax = plt.subplot(151)
    image = rt_im[0, 0, inclin_index, :, :]
    if vmax is None:
        #image.shape = image.shape[2:] # drop leading zero-length dimensions...
        vmax = image.max()
    if vmin is None:
        vmin = vmax / 1e8
    norm = matplotlib.colors.LogNorm(vmin=vmin, vmax=vmax, clip=True)

    if psf_fwhm is not None:
        raise NotImplementedError("This code not yet implemented")
        import optics
        #psf = optics.airy_2d(aperture=10.0, wavelength=1.6e-6, pixelscale=0.020, shape=(99,99))
        psf = pyfits.getdata(
            '/Users/mperrin/Dropbox/AAS2013/models_pds144n/manual/keck_psf_tmp4.fits'
        )
        from astropy.nddata import convolve
        convolved = convolve(image, psf, normalize_kernel=True)

        image = convolved

    if polfrac:
        ax = plt.subplot(121)

    ax = utils.imshow_with_mouseover(ax, image, norm=norm, cmap=cmap)
    ax.set_xlabel("Offset [pix]")
    ax.set_ylabel("Offset [pix]")
    ax.set_title(wavelength + " $\mu$m")

    if polarization == True:

        # dont' show every pixel's vectors:
        showevery = 5

        imQ = rt_im[
            1, 0,
            inclin_index, :, :] * -1  #MCFOST sign convention requires flip for +Q = up
        imU = rt_im[2, 0, inclin_index, :, :] * -1  #MCFOST sign convention

        imQn = imQ / image
        imUn = imU / image
        polfrac_ar = np.sqrt(imQn**2 + imUn**2)
        theta = 0.5 * np.arctan2(imUn, imQn) + np.pi / 2
        vecX = polfrac_ar * np.cos(theta) * -1
        vecY = polfrac_ar * np.sin(theta)

        Y, X = np.indices(image.shape)
        Q = plt.quiver(X[::showevery, ::showevery],
                       Y[::showevery, ::showevery],
                       vecX[::showevery, ::showevery],
                       vecY[::showevery, ::showevery],
                       headwidth=0,
                       headlength=0,
                       headaxislength=0.0,
                       pivot='middle',
                       color='white')
        plt.quiverkey(Q,
                      0.85,
                      0.95,
                      0.5,
                      "50% pol.",
                      coordinates='axes',
                      labelcolor='white',
                      labelpos='E',
                      fontproperties={'size': 'small'})  #, width=0.003)
        #        ax = plt.subplot(152)
        #        ax.imshow(imQn, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
        #        ax.set_title('Q')
        #        ax = plt.subplot(153)
        #        ax.imshow(imUn, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
        #        ax.set_title('U')
        #        ax = plt.subplot(154)
        #        ax.imshow(vecX, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
        #        ax.set_title('vecX')
        #        ax = plt.subplot(155)
        #        ax.imshow(vecY, vmin=-1, vmax=1, cmap=matplotlib.cm.RdBu)
        #        ax.set_title('vecY')
        #        ax.colorbar()

        #plt.colorbar()

        if polfrac:
            ax2 = plt.subplot(122)

            cmap2 = plt.cm.gist_heat
            cmap2 = plt.cm.jet
            cmap2.set_over('red')
            cmap2.set_under('black')
            cmap2.set_bad('black')

            ax2 = imshow_with_mouseover(ax2,
                                        polfrac_ar,
                                        vmin=0,
                                        vmax=1,
                                        cmap=cmap2)
            ax2.set_title("Polarization fraction")

            cax = plt.axes([0.92, 0.25, 0.02, 0.5])
            plt.colorbar(ax2.images[0], cax=cax, orientation='vertical')