Exemplo n.º 1
0
    def __call__(self, img):

        mylog = mylogger.logging.getLogger("PyBDSM.Cleanup")

        ### plotresults for all gaussians together
        if img.opts.plot_allgaus and has_pl:
            pl.figure()
            pl.title('All gaussians including wavelet images')
            allgaus = img.gaussians
            if hasattr(img, 'atrous_gaussians'):
              for gg in img.atrous_gaussians:
                allgaus += gg

            for g in allgaus:
              ellx, elly = func.drawellipse(g)
              pl.plot(ellx, elly, 'r')

            from math import log10
            bdir = img.basedir + '/misc/'
            if not os.path.isdir(bdir): os.makedirs(bdir)
            im_mean = img.clipped_mean
            im_rms = img.clipped_rms
            low = 1.1*abs(img.min_value)
            low1 = 1.1*abs(N.min(im_mean-im_rms*5.0))
            if low1 > low: low = low1
            vmin = log10(im_mean-im_rms*5.0 + low)
            vmax = log10(im_mean+im_rms*15.0 + low)
            im = N.log10(img.ch0_arr + low)

            pl.imshow(N.transpose(im), origin='lower', interpolation='nearest',vmin=vmin, vmax=vmax, \
                      cmap=cm.gray); pl.colorbar()
            pl.savefig(bdir+'allgaussians.png')
            pl.close()

        img.completed_Ops.append('cleanup')
Exemplo n.º 2
0
def make_casa_str(img, glist):
    """Makes a list of string entries for a casa clean box file."""
    import functions as func
    outstr_list = []
    sep = ' '
    scale = 2.0
    for gindx, g in enumerate(glist[0]):
        x, y = g.centre_pix
        xsize, ysize, ang = g.size_pix # FWHM
        ellx, elly = func.drawellipse(g)
        blc = [int(min(ellx)), int(min(elly))]
        trc = [int(max(ellx)), int(max(elly))]

        blc[0] -= (x - blc[0]) * scale
        blc[1] -= (y - blc[1]) * scale
        trc[0] += (trc[0] - x) * scale
        trc[1] += (trc[1] - y) * scale
        # Format is: <id> <blcx> <blcy> <trcx> <trcy>
        # Note that we use gindx rather than g.gaus_num so that
        # all Gaussians will have a unique id, even if wavelet
        # Gaussians are included.
        outstr_list.append(str(gindx+1) + sep + str(blc[0]) + sep +
                           str(blc[1]) + sep + str(trc[0]) + sep +
                           str(trc[1]) +'\n')
    return outstr_list
Exemplo n.º 3
0
def make_casa_str(img, glist):
    """Makes a list of string entries for a casa region file."""
    import functions as func
    outstr_list = ['#CRTFv0 CASA Region Text Format version 0\n']
    sep = ' '
    scale = 2.0 # scale box to 2 times FWHM of Gaussian
    for gindx, g in enumerate(glist[0]):
        x, y = g.centre_pix
        ellx, elly = func.drawellipse(g)
        blc = [min(ellx), min(elly)]
        trc = [max(ellx), max(elly)]

        blc[0] -= (x - blc[0]) * scale
        blc[1] -= (y - blc[1]) * scale
        trc[0] += (trc[0] - x) * scale
        trc[1] += (trc[1] - y) * scale

        blc_sky = img.pix2sky(blc)
        trc_sky = img.pix2sky(trc)

        blc_sky_str = convert_radec_str(blc_sky[0], blc_sky[1])
        trc_sky_str = convert_radec_str(trc_sky[0], trc_sky[1])

        # Format is: box [ [<blcx>, <blcy>], [<trcx>, <trcy>] ]
        # Note that we use gindx rather than g.gaus_num so that
        # all Gaussians will have a unique id, even if wavelet
        # Gaussians are included.
        outstr_list.append('box [[' + ', '.join(blc_sky_str) + '], [' +
                           ', '.join(trc_sky_str) + ']] coord=J2000\n')
    return outstr_list
Exemplo n.º 4
0
    def __call__(self, img):

        mylog = mylogger.logging.getLogger("PyBDSM.Cleanup")

        ### plotresults for all gaussians together
        if img.opts.plot_allgaus and has_pl:
            pl.figure()
            pl.title('All gaussians including wavelet images')
            allgaus = img.gaussians
            if hasattr(img, 'atrous_gaussians'):
                for gg in img.atrous_gaussians:
                    allgaus += gg

            for g in allgaus:
                ellx, elly = func.drawellipse(g)
                pl.plot(ellx, elly, 'r')

            from math import log10
            bdir = img.basedir + '/misc/'
            if not os.path.isdir(bdir): os.makedirs(bdir)
            im_mean = img.clipped_mean
            im_rms = img.clipped_rms
            low = 1.1 * abs(img.min_value)
            low1 = 1.1 * abs(N.min(im_mean - im_rms * 5.0))
            if low1 > low: low = low1
            vmin = log10(im_mean - im_rms * 5.0 + low)
            vmax = log10(im_mean + im_rms * 15.0 + low)
            im = N.log10(img.ch0_arr + low)

            pl.imshow(N.transpose(im), origin='lower', interpolation='nearest',vmin=vmin, vmax=vmax, \
                      cmap=cm.gray)
            pl.colorbar()
            pl.savefig(bdir + 'allgaussians.png')
            pl.close()

        img.completed_Ops.append('cleanup')
Exemplo n.º 5
0
def plotresults(img,
                ch0_image=True,
                rms_image=True,
                mean_image=True,
                ch0_islands=True,
                gresid_image=True,
                sresid_image=False,
                gmodel_image=True,
                smodel_image=False,
                pyramid_srcs=False,
                source_seds=False,
                ch0_flagged=False,
                pi_image=False,
                psf_major=False,
                psf_minor=False,
                psf_pa=False,
                broadcast=False):
    """Show the results of a fit."""
    global img_ch0, img_rms, img_mean, img_gaus_mod, img_shap_mod
    global img_gaus_resid, img_shap_resid, pixels_per_beam, pix2sky
    global vmin, vmax, vmin_cur, vmax_cur, ch0min, ch0max, img_pi
    global low, fig, images, src_list, srcid_cur, sky2pix, markers
    global img_psf_maj, img_psf_min, img_psf_pa, do_broadcast, samp_client
    global samp_key, samp_gaul_table_url, samp_srl_table_url

    if not has_pl:
        print "\033[31;1mWARNING\033[0m: Matplotlib not found. Plotting is disabled."
        return
    if hasattr(img, 'samp_client'):
        samp_client = img.samp_client
        samp_key = img.samp_key
        if hasattr(img, 'samp_srl_table_url'):
            samp_srl_table_url = img.samp_srl_table_url
        else:
            samp_srl_table_url = None
        if hasattr(img, 'samp_gaul_table_url'):
            samp_gaul_table_url = img.samp_gaul_table_url
        else:
            samp_gaul_table_url = None
    else:
        samp_clent = None
        samp_key = None
        samp_srl_table_url = None
        samp_gaul_table_url = None
    do_broadcast = broadcast

    # Define the images. The images are used both by imshow and by the
    # on_press() and coord_format event handlers
    pix2sky = img.pix2sky
    sky2pix = img.sky2pix
    gfactor = 2.0 * N.sqrt(2.0 * N.log(2.0))
    pixels_per_beam = 2.0 * N.pi * (img.beam2pix(img.beam)[0] *
                                    img.beam2pix(img.beam)[1]) / gfactor**2

    # Construct lists of images, titles, etc.
    images = []
    titles = []
    names = []
    markers = []
    img_gaus_mod = None  # default needed for key press event
    img_shap_mod = None  # default needed for key press event
    if ch0_image:
        img_ch0 = img.ch0_arr
        images.append(img_ch0)
        titles.append('Original (ch0) Image\n(arbitrary logarithmic scale)')
        names.append('ch0')
    if ch0_islands:
        img_ch0 = img.ch0_arr
        images.append(img_ch0)
        if hasattr(img, 'ngaus'):
            if hasattr(img, 'ch0_pi_arr'):
                ch0_str = 'Islands (hatched boundaries; red = PI only) and\nGaussians'
            else:
                ch0_str = 'Islands (hatched boundaries) and\nGaussians'
            if hasattr(img, 'atrous_gaussians'):
                ch0_str += ' (red = wavelet)'
            titles.append(ch0_str)
        else:
            titles.append('Islands (hatched boundaries)')
        names.append('ch0')
    if ch0_flagged:
        if not hasattr(img, 'ngaus'):
            print 'Image was not fit with Gaussians. Skipping display of flagged Gaussians.'
        else:
            img_ch0 = img.ch0_arr
            images.append(img_ch0)
            titles.append('Flagged Gaussians')
        names.append('ch0')
    if pi_image:
        if not hasattr(img, 'ch0_pi_arr'):
            print 'Polarization module not run. Skipping PI image.'
        else:
            img_pi = img.ch0_pi_arr
            images.append(img_pi)
            titles.append('Polarized Intensity Image')
            names.append('ch0_pi')
    if rms_image:
        img_rms = img.rms_arr
        images.append(img_rms)
        titles.append('Background rms Image')
        names.append('rms')
    if gresid_image:
        if not hasattr(img, 'ngaus'):
            print 'Image was not fit with Gaussians. Skipping residual Gaussian image.'
        else:
            img_gaus_resid = img.resid_gaus_arr
            images.append(img_gaus_resid)
            titles.append('Gaussian Residual Image')
            names.append('gaus_resid')
    if gmodel_image:
        if not hasattr(img, 'ngaus'):
            print 'Image was not fit with Gaussians. Skipping model Gaussian image.'
        else:
            img_gaus_mod = img.model_gaus_arr
            images.append(img_gaus_mod)
            titles.append('Gaussian Model Image')
            names.append('gaus_mod')
    if mean_image:
        img_mean = img.mean_arr
        images.append(img_mean)
        titles.append('Background mean Image')
        names.append('mean')
    if sresid_image:
        if img.opts.shapelet_do == False:
            print 'Image was not decomposed into shapelets. Skipping residual shapelet image.'
        else:
            img_shap_resid = img.ch0_arr - img.model_shap_arr
            images.append(img_shap_resid)
            titles.append('Shapelet Residual Image')
            names.append('shap_resid')
    if smodel_image:
        if img.opts.shapelet_do == False:
            print 'Image was not decomposed into shapelets. Skipping model shapelet image.'
        else:
            img_shap_mod = img.model_shap_arr
            images.append(img_shap_mod)
            titles.append('Shapelet Model Image')
            names.append('shap_mod')
    if source_seds:
        if img.opts.spectralindex_do == False:
            print 'Source SEDs were not fit. Skipping source SED plots.'
        else:
            src_list = img.sources
            sed_src = get_src(src_list, 0)
            if sed_src == None:
                print 'No sources found. Skipping source SED plots.'
            else:
                images.append('seds')
                titles.append('')
                names.append('seds')
                srcid_cur = 0
    if pyramid_srcs:
        if img.opts.atrous_do == False:
            print 'Image was not decomposed into wavelets. Skipping wavelet images.'
        else:
            # Get the unique j levels and store them. Only make subplots for
            # occupied j levels
            print 'Pyramidal source plots not yet supported.'


#             j_list = []
#             for p in img.pyrsrcs:
#                 for l in p.jlevels:
#                     j_list.append(l)
#             j_set = set(j_list)
#             j_with_gaus = list(j_set)
#             index_first_waveplot = len(images)
#             for i in range(len(j_with_gaus)):
#                 images.append('wavelets')
#                 names.append('pyrsrc'+str(i))
    if psf_major or psf_minor or psf_pa:
        if img.opts.psf_vary_do == False:
            print 'PSF variation not calculated. Skipping PSF variation images.'
        else:
            if psf_major:
                img_psf_maj = img.psf_vary_maj_arr * fwsig
                images.append(img_psf_maj)
                titles.append('PSF Major Axis FWHM (pixels)')
                names.append('psf_maj')
            if psf_minor:
                img_psf_min = img.psf_vary_min_arr * fwsig
                images.append(img_psf_min)
                titles.append('PSF Minor Axis FWHM (pixels)')
                names.append('psf_min')
            if psf_pa:
                img_psf_pa = img.psf_vary_pa_arr
                images.append(img_psf_pa)
                titles.append('PSF Pos. Angle FWhM (degrees)')
                names.append('psf_pa')

    if images == []:
        print 'No images to display.'
        return

    im_mean = img.clipped_mean
    im_rms = img.clipped_rms
    if img.resid_gaus == None:
        low = 1.1 * abs(img.min_value)
    else:
        low = N.max(
            [1.1 * abs(img.min_value), 1.1 * abs(N.nanmin(img.resid_gaus))])
    if low <= 0.0:
        low = 1E-6
    vmin_est = im_mean - im_rms * 5.0 + low
    if vmin_est <= 0.0:
        vmin = N.log10(low)
    else:
        vmin = N.log10(vmin_est)
    vmax = N.log10(im_mean + im_rms * 30.0 + low)
    ch0min = vmin
    ch0max = N.log10(img.max_value + low)
    vmin_cur = vmin
    vmax_cur = vmax
    origin = 'lower'
    colours = ['m', 'b', 'c', 'g', 'y', 'k']  # reserve red ('r') for wavelets
    styles = ['-', '-.', '--']
    print '=' * 72
    print 'NOTE -- With the mouse pointer in plot window:'
    print '  Press "i" ........ : Get integrated flux densities and mean rms'
    print '                       values for the visible portion of the image'
    print '  Press "m" ........ : Change min and max scaling values'
    print '  Press "n" ........ : Show / hide island IDs'
    print '  Press "0" ........ : Reset scaling to default'
    if 'seds' in images:
        print '  Press "c" ........ : Change source for SED plot'
    if ch0_islands and hasattr(img, 'ngaus'):
        print '  Click Gaussian ... : Print Gaussian and source IDs (zoom_rect mode, '
        print '                       toggled with the "zoom" button and indicated in '
        print '                       the lower right corner, must be off)'
        if 'seds' in images:
            print '                       The SED plot will also show the chosen source.'
    print '_' * 72

    if len(images) > 1:
        numx = 2
    else:
        numx = 1
    numy = int(N.ceil(float(len(images)) / float(numx)))
    fig = pl.figure(figsize=(max(15, 10.0 * float(numy) / float(numx)), 10.0))
    fig.canvas.set_window_title('PyBDSM Fit Results for ' + img.filename)
    gray_palette = cm.gray
    gray_palette.set_bad('k')

    for i, image in enumerate(images):
        if image != 'wavelets' and image != 'seds':
            if i == 0:
                cmd = 'ax' + str(i+1) + ' = pl.subplot(' + str(numx) + \
                    ', ' + str(numy) + ', ' + str(i+1) + ')'
            else:
                cmd = 'ax' + str(i+1) + ' = pl.subplot(' + str(numx) + \
                    ', ' + str(numy) + ', ' + str(i+1) + ', sharex=ax1' + \
                    ', sharey=ax1)'
            exec cmd
            if 'PSF' in titles[i]:
                im = image
            else:
                im = N.log10(image + low)
            if 'Islands' in titles[i]:
                island_offsets_x = []
                island_offsets_y = []
                border_color = []
                ax = pl.gca()
                for iisl, isl in enumerate(img.islands):
                    xb, yb = isl.border
                    if hasattr(isl, '_pi'):
                        for c in range(len(xb)):
                            border_color.append('r')
                    else:
                        for c in range(len(xb)):
                            border_color.append('#afeeee')
                    island_offsets_x += xb.tolist()
                    island_offsets_y += yb.tolist()
                    marker = ax.text(N.max(xb) + 2,
                                     N.max(yb),
                                     str(isl.island_id),
                                     color='#afeeee',
                                     clip_on=True)
                    marker.set_visible(not marker.get_visible())
                    markers.append(marker)
                    # draw the gaussians with one colour per source or island
                    # (if gaul2srl was not run)
                    if hasattr(img, 'nsrc'):
                        nsrc = len(isl.sources)
                        for isrc in range(nsrc):
                            col = colours[isrc % 6]
                            style = styles[isrc / 6 % 3]
                            src = isl.sources[isrc]
                            for g in src.gaussians:
                                if hasattr(g, 'valid'):
                                    valid = g.valid
                                else:
                                    valid = True
                                if g.jlevel == 0 and valid and g.gaus_num >= 0:
                                    gidx = g.gaus_num
                                    e = Ellipse(xy=g.centre_pix,
                                                width=g.size_pix[0],
                                                height=g.size_pix[1],
                                                angle=g.size_pix[2] + 90.0)
                                    ax.add_artist(e)
                                    e.set_picker(3)
                                    e.set_clip_box(ax.bbox)
                                    e.set_facecolor(col)
                                    e.set_alpha(0.5)
                                    e.gaus_id = gidx
                                    e.src_id = src.source_id
                                    e.jlevel = g.jlevel
                                    e.isl_id = g.island_id
                                    e.tflux = g.total_flux
                                    e.pflux = g.peak_flux
                                    e.centre_sky = g.centre_sky
                if len(img.islands) > 0:
                    island_offsets = zip(N.array(island_offsets_x),
                                         N.array(island_offsets_y))
                    isl_borders = collections.AsteriskPolygonCollection(
                        4,
                        offsets=island_offsets,
                        color=border_color,
                        transOffset=ax.transData,
                        sizes=(10.0, ))
                    ax.add_collection(isl_borders)

                if hasattr(img, 'gaussians'):
                    for atrg in img.gaussians:
                        if atrg.jlevel > 0 and atrg.gaus_num >= 0:
                            col = 'r'
                            style = '-'
                            gidx = atrg.gaus_num
                            e = Ellipse(xy=atrg.centre_pix,
                                        width=atrg.size_pix[0],
                                        height=atrg.size_pix[1],
                                        angle=atrg.size_pix[2] + 90.0)
                            ax.add_artist(e)
                            e.set_picker(3)
                            e.set_clip_box(ax.bbox)
                            e.set_edgecolor(col)
                            e.set_facecolor('none')
                            e.set_alpha(0.8)
                            e.gaus_id = gidx
                            e.src_id = atrg.source_id
                            e.jlevel = atrg.jlevel
                            e.isl_id = atrg.island_id
                            e.tflux = atrg.total_flux
                            e.pflux = atrg.peak_flux
                            e.centre_sky = atrg.centre_sky

            if 'Flagged' in titles[i]:
                for iisl, isl in enumerate(img.islands):
                    ax = pl.gca()
                    style = '-'
                    for ig, g in enumerate(isl.fgaul):
                        col = colours[ig % 6]
                        ellx, elly = func.drawellipse(g)
                        gline, = ax.plot(ellx,
                                         elly,
                                         color=col,
                                         linestyle=style,
                                         picker=3)
                        gline.flag = g.flag

            if 'PSF' in titles[i]:
                cmd = 'ax' + str(i+1) + ".imshow(N.transpose(im), origin=origin, "\
                      "interpolation='nearest', cmap=gray_palette)"
            else:
                cmd = 'ax' + str(i+1) + ".imshow(N.transpose(im), origin=origin, "\
                      "interpolation='nearest',vmin=vmin, vmax=vmax, cmap=gray_palette)"
            exec cmd
            cmd = 'ax' + str(i +
                             1) + '.format_coord = format_coord_' + names[i]
            exec cmd
            pl.title(titles[i])
        elif image == 'seds':
            cmd = 'ax' + str(i+1) + ' = pl.subplot(' + str(numx) + \
                ', ' + str(numy) + ', ' + str(i+1) + ')'
            exec cmd
            ax = pl.gca()
            plot_sed(sed_src, ax)

        elif image == 'wavelets':
            if i == index_first_waveplot:
                for j in range(len(j_with_gaus)):
                    cmd = 'ax' + str(j+i+1) + ' = pl.subplot(' + str(numx) + \
                        ', ' + str(numy) + ', ' + str(j+i+1) + ', sharex=ax1, '+\
                        'sharey=ax1)'
                    exec cmd
                    pl.title('Pyramidal Sources for\nWavelet Scale J = ' +
                             str(j_with_gaus[j]))
            for pyr in img.pyrsrcs:
                for iisl, isl in enumerate(pyr.islands):
                    jj = pyr.jlevels[iisl]
                    jindx = j_with_gaus.index(jj)
                    col = colours[pyr.pyr_id % 6]
                    ind = N.where(~isl.mask_active)
                    cmd = "ax" + str(jindx + index_first_waveplot + 1) + \
                        ".plot(ind[0]+isl.origin[0], "\
                        "ind[1]+isl.origin[1], '.', color=col)"
                    exec cmd

    fig.canvas.mpl_connect('key_press_event', on_press)
    fig.canvas.mpl_connect('pick_event', on_pick)
    pl.show()
    pl.close('all')
Exemplo n.º 6
0
    def _flag_gaussian(self, g, beam, thr, peak, shape, opts, mask, image, size_bms):
        """The actual flagging routine. See above for description.
        """
        from math import sqrt, sin, cos, log, pi
        from const import fwsig
        import functions as func
        import scipy.ndimage as nd

        A, x1, x2, s1, s2, th = g
        s1, s2 = map(abs, [s1, s2])
        flag = 0
        if N.any(N.isnan(g)) or s1 == 0.0 or s2 == 0.0:
            return -1

        if s1 < s2:   # s1 etc are sigma
            ss1 = s2
            ss2 = s1
            th1 = divmod(th+90.0, 180)[1]
        else:
            ss1 = s1
            ss2 = s2
            th1 = divmod(th, 180)[1]
        th1 = th1/180.0*pi
        if ss1 > 1e4 and ss2 > 1e4:
          xbox = 1e9; ybox = 1e9
        else:
          xbox = 2.0*(abs(ss1*cos(th1)*cos(th1))+abs(ss2*ss2/ss1*sin(th1)*sin(th1)))/ \
                 sqrt(cos(th1)*cos(th1)+ss2*ss2/ss1/ss1*sin(th1)*sin(th1))
          ybox = 2.0*(abs(ss1*sin(th1)*sin(th1))+abs(ss2*ss2/ss1*cos(th1)*cos(th1)))/ \
                 sqrt(sin(th1)*sin(th1)+ss2*ss2/ss1/ss1*cos(th1)*cos(th1))

        ### now check all conditions
        border = opts.flag_bordersize
        x1ok = True
        x2ok = True
        flagmax = False
        if A < opts.flag_minsnr*thr: flag += 1
        if A > opts.flag_maxsnr*peak:
            flag += 2
            flagmax = True
        if x1 - border < 0 or x1 + border + 1 > shape[0]:
            flag += 4
            x1ok = False
        if x2 - border < 0 or x2 + border + 1 > shape[1]:
            flag += 8
            x2ok = False
        if x1ok and x2ok:
            if not flagmax:
                # Check image value at Gaussian center
                im_val_at_cen = nd.map_coordinates(image, [N.array([x1]), N.array([x2])])
                if A > opts.flag_maxsnr*im_val_at_cen:
                   flag += 2
            borx1_1 = x1 - border
            if borx1_1 < 0: borx1_1 = 0
            borx1_2 = x1 + border + 1
            if borx1_2 > shape[0]: borx1_2 = shape[0]
            if N.any(mask[borx1_1:borx1_2, x2]):
                flag += 4
            borx2_1 = x2 - border
            if borx2_1 < 0: borx2_1 = 0
            borx2_2 = x2 + border + 1
            if borx2_2 > shape[1]: borx2_2 = shape[1]
            if N.any(mask[x1, borx2_1:borx2_2]):
                flag += 8
        if xbox > opts.flag_maxsize_isl*shape[0]: flag += 16
        if ybox > opts.flag_maxsize_isl*shape[1]: flag += 32
        if s1*s2 > opts.flag_maxsize_bm*beam[0]*beam[1]: flag += 64
        if opts.flag_smallsrc:
          if s1*s2 < opts.flag_minsize_bm*beam[0]*beam[1]: flag += 128
        if not opts.flag_smallsrc:
                if s1*s2 == 0.: flag += 128

        if ss1/ss2 > 2.0:
            # Only check for fairly elliptical Gaussians, as this condition
            # is unreliable for more circular ones.
            ellx, elly = func.drawellipse([A, x1, x2, s1*opts.flag_maxsize_fwhm,
                                           s2*opts.flag_maxsize_fwhm, th])
            pt1 = [N.min(ellx), elly[N.argmin(ellx)]]
            pt2 = [ellx[N.argmax(elly)], N.max(elly)]
            pt3 = [N.max(ellx), elly[N.argmax(ellx)]]
            pt4 = [ellx[N.argmin(elly)], N.min(elly)]
            extremes = [pt1, pt2, pt3, pt4]
            for pt in extremes:
                if pt[0] < 0 or pt[0] >= shape[0] or pt[1] < 0 or pt[1] >= shape[1]:
                    flag += 256
                    break
                elif mask[tuple(pt)]:
                    flag += 256
                    break
        return flag
Exemplo n.º 7
0
def plotresults(img, ch0_image=True, rms_image=True, mean_image=True,
                ch0_islands=True, gresid_image=True, sresid_image=False,
                gmodel_image=True, smodel_image=False, pyramid_srcs=False,
                source_seds=False, ch0_flagged=False, pi_image=False,
                psf_major=False, psf_minor=False, psf_pa=False, broadcast=False):
    """Show the results of a fit."""
    global img_ch0, img_rms, img_mean, img_gaus_mod, img_shap_mod
    global img_gaus_resid, img_shap_resid, pixels_per_beam, pix2sky
    global vmin, vmax, vmin_cur, vmax_cur, ch0min, ch0max, img_pi
    global low, fig, images, src_list, srcid_cur, sky2pix, markers
    global img_psf_maj, img_psf_min, img_psf_pa, do_broadcast, samp_client
    global samp_key, samp_gaul_table_url, samp_srl_table_url

    if not has_pl:
        print "\033[31;1mWARNING\033[0m: Matplotlib not found. Plotting is disabled."
        return
    if hasattr(img, 'samp_client'):
        samp_client = img.samp_client
        samp_key = img.samp_key
        if hasattr(img, 'samp_srl_table_url'):
            samp_srl_table_url = img.samp_srl_table_url
        else:
            samp_srl_table_url = None
        if hasattr(img, 'samp_gaul_table_url'):
            samp_gaul_table_url = img.samp_gaul_table_url
        else:
            samp_gaul_table_url = None
    else:
        samp_clent = None
        samp_key = None
        samp_srl_table_url = None
        samp_gaul_table_url = None
    do_broadcast = broadcast

    # Define the images. The images are used both by imshow and by the
    # on_press() and coord_format event handlers
    pix2sky = img.pix2sky
    sky2pix = img.sky2pix
    gfactor = 2.0 * N.sqrt(2.0 * N.log(2.0))
    pixels_per_beam = 2.0 * N.pi * (img.beam2pix(img.beam)[0]
                                    * img.beam2pix(img.beam)[1]) / gfactor**2

    # Construct lists of images, titles, etc.
    images = []
    titles = []
    names = []
    markers = []
    img_gaus_mod = None # default needed for key press event
    img_shap_mod = None # default needed for key press event
    if ch0_image:
        img_ch0 = img.ch0_arr
        images.append(img_ch0)
        titles.append('Original (ch0) Image\n(arbitrary logarithmic scale)')
        names.append('ch0')
    if ch0_islands:
        img_ch0 = img.ch0_arr
        images.append(img_ch0)
        if hasattr(img, 'ngaus'):
            if hasattr(img, 'ch0_pi_arr'):
                ch0_str = 'Islands (hatched boundaries; red = PI only) and\nGaussians'
            else:
                ch0_str = 'Islands (hatched boundaries) and\nGaussians'
            if hasattr(img, 'atrous_gaussians'):
                ch0_str += ' (red = wavelet)'
            titles.append(ch0_str)
        else:
            titles.append('Islands (hatched boundaries)')
        names.append('ch0')
    if ch0_flagged:
        if not hasattr(img, 'ngaus'):
            print 'Image was not fit with Gaussians. Skipping display of flagged Gaussians.'
        else:
            img_ch0 = img.ch0_arr
            images.append(img_ch0)
            titles.append('Flagged Gaussians')
        names.append('ch0')
    if pi_image:
        if not hasattr(img, 'ch0_pi_arr'):
            print 'Polarization module not run. Skipping PI image.'
        else:
            img_pi = img.ch0_pi_arr
            images.append(img_pi)
            titles.append('Polarized Intensity Image')
            names.append('ch0_pi')
    if rms_image:
        img_rms = img.rms_arr
        images.append(img_rms)
        titles.append('Background rms Image')
        names.append('rms')
    if gresid_image:
        if not hasattr(img, 'ngaus'):
            print 'Image was not fit with Gaussians. Skipping residual Gaussian image.'
        else:
            img_gaus_resid = img.resid_gaus_arr
            images.append(img_gaus_resid)
            titles.append('Gaussian Residual Image')
            names.append('gaus_resid')
    if gmodel_image:
        if not hasattr(img, 'ngaus'):
            print 'Image was not fit with Gaussians. Skipping model Gaussian image.'
        else:
            img_gaus_mod = img.model_gaus_arr
            images.append(img_gaus_mod)
            titles.append('Gaussian Model Image')
            names.append('gaus_mod')
    if mean_image:
        img_mean = img.mean_arr
        images.append(img_mean)
        titles.append('Background mean Image')
        names.append('mean')
    if sresid_image:
        if img.opts.shapelet_do == False:
            print 'Image was not decomposed into shapelets. Skipping residual shapelet image.'
        else:
            img_shap_resid = img.ch0_arr - img.model_shap_arr
            images.append(img_shap_resid)
            titles.append('Shapelet Residual Image')
            names.append('shap_resid')
    if smodel_image:
        if img.opts.shapelet_do == False:
            print 'Image was not decomposed into shapelets. Skipping model shapelet image.'
        else:
            img_shap_mod = img.model_shap_arr
            images.append(img_shap_mod)
            titles.append('Shapelet Model Image')
            names.append('shap_mod')
    if source_seds:
        if img.opts.spectralindex_do == False:
            print 'Source SEDs were not fit. Skipping source SED plots.'
        else:
            src_list = img.sources
            sed_src = get_src(src_list, 0)
            if sed_src is None:
                print 'No sources found. Skipping source SED plots.'
            else:
                images.append('seds')
                titles.append('')
                names.append('seds')
                srcid_cur = 0
    if pyramid_srcs:
        if img.opts.atrous_do == False:
            print 'Image was not decomposed into wavelets. Skipping wavelet images.'
        else:
            # Get the unique j levels and store them. Only make subplots for
            # occupied j levels
            print 'Pyramidal source plots not yet supported.'
#             j_list = []
#             for p in img.pyrsrcs:
#                 for l in p.jlevels:
#                     j_list.append(l)
#             j_set = set(j_list)
#             j_with_gaus = list(j_set)
#             index_first_waveplot = len(images)
#             for i in range(len(j_with_gaus)):
#                 images.append('wavelets')
#                 names.append('pyrsrc'+str(i))
    if psf_major or psf_minor or psf_pa:
        if img.opts.psf_vary_do == False:
            print 'PSF variation not calculated. Skipping PSF variation images.'
        else:
            if psf_major:
                img_psf_maj = img.psf_vary_maj_arr*fwsig
                images.append(img_psf_maj)
                titles.append('PSF Major Axis FWHM (pixels)')
                names.append('psf_maj')
            if psf_minor:
                img_psf_min = img.psf_vary_min_arr*fwsig
                images.append(img_psf_min)
                titles.append('PSF Minor Axis FWHM (pixels)')
                names.append('psf_min')
            if psf_pa:
                img_psf_pa = img.psf_vary_pa_arr
                images.append(img_psf_pa)
                titles.append('PSF Pos. Angle FWhM (degrees)')
                names.append('psf_pa')

    if images == []:
        print 'No images to display.'
        return

    im_mean = img.clipped_mean
    im_rms = img.clipped_rms
    if img.resid_gaus is None:
        low = 1.1*abs(img.min_value)
    else:
        low = N.max([1.1*abs(img.min_value),1.1*abs(N.nanmin(img.resid_gaus))])
    if low <= 0.0:
        low = 1E-6
    vmin_est = im_mean - im_rms*5.0 + low
    if vmin_est <= 0.0:
        vmin = N.log10(low)
    else:
        vmin = N.log10(vmin_est)
    vmax = N.log10(im_mean + im_rms*30.0 + low)
    ch0min = vmin
    ch0max = N.log10(img.max_value + low)
    vmin_cur = vmin
    vmax_cur = vmax
    origin = 'lower'
    colours = ['m', 'b', 'c', 'g', 'y', 'k'] # reserve red ('r') for wavelets
    styles = ['-', '-.', '--']
    print '=' * 72
    print 'NOTE -- With the mouse pointer in plot window:'
    print '  Press "i" ........ : Get integrated flux densities and mean rms'
    print '                       values for the visible portion of the image'
    print '  Press "m" ........ : Change min and max scaling values'
    print '  Press "n" ........ : Show / hide island IDs'
    print '  Press "0" ........ : Reset scaling to default'
    if 'seds' in images:
        print '  Press "c" ........ : Change source for SED plot'
    if ch0_islands and hasattr(img, 'ngaus'):
        print '  Click Gaussian ... : Print Gaussian and source IDs (zoom_rect mode, '
        print '                       toggled with the "zoom" button and indicated in '
        print '                       the lower right corner, must be off)'
        if 'seds' in images:
            print '                       The SED plot will also show the chosen source.'
    print '_' * 72

    if len(images) > 1:
        numx = 2
    else:
        numx = 1
    numy = int(N.ceil(float(len(images))/float(numx)))
    fig = pl.figure(figsize=(max(15, 10.0*float(numy)/float(numx)), 10.0))
    fig.canvas.set_window_title('PyBDSM Fit Results for '+ img.filename)
    gray_palette = cm.gray
    gray_palette.set_bad('k')

    for i, image in enumerate(images):
        if image != 'wavelets' and image != 'seds':
            if i == 0:
                cmd = 'ax' + str(i+1) + ' = pl.subplot(' + str(numx) + \
                    ', ' + str(numy) + ', ' + str(i+1) + ')'
            else:
                cmd = 'ax' + str(i+1) + ' = pl.subplot(' + str(numx) + \
                    ', ' + str(numy) + ', ' + str(i+1) + ', sharex=ax1' + \
                    ', sharey=ax1)'
            exec cmd
            if 'PSF' in titles[i]:
                im = image
            else:
                im = N.log10(image + low)
            if 'Islands' in titles[i]:
                island_offsets_x = []
                island_offsets_y = []
                border_color = []
                ax = pl.gca()
                for iisl, isl in enumerate(img.islands):
                    xb, yb = isl.border
                    if hasattr(isl, '_pi'):
                        for c in range(len(xb)):
                            border_color.append('r')
                    else:
                        for c in range(len(xb)):
                            border_color.append('#afeeee')
                    island_offsets_x += xb.tolist()
                    island_offsets_y += yb.tolist()
                    marker = ax.text(N.max(xb)+2, N.max(yb), str(isl.island_id),
                                      color='#afeeee', clip_on=True)
                    marker.set_visible(not marker.get_visible())
                    markers.append(marker)
                    # draw the gaussians with one colour per source or island
                    # (if gaul2srl was not run)
                    if hasattr(img, 'nsrc'):
                        nsrc = len(isl.sources)
                        for isrc in range(nsrc):
                            col = colours[isrc % 6]
                            style = styles[isrc/6 % 3]
                            src = isl.sources[isrc]
                            for g in src.gaussians:
                                if hasattr(g, 'valid'):
                                    valid = g.valid
                                else:
                                    valid = True
                                if g.jlevel == 0 and valid and g.gaus_num >= 0:
                                    gidx = g.gaus_num
                                    e = Ellipse(xy=g.centre_pix, width=g.size_pix[0],
                                                height=g.size_pix[1], angle=g.size_pix[2]+90.0)
                                    ax.add_artist(e)
                                    e.set_picker(3)
                                    e.set_clip_box(ax.bbox)
                                    e.set_facecolor(col)
                                    e.set_alpha(0.5)
                                    e.gaus_id = gidx
                                    e.src_id = src.source_id
                                    e.jlevel = g.jlevel
                                    e.isl_id = g.island_id
                                    e.tflux = g.total_flux
                                    e.pflux = g.peak_flux
                                    e.centre_sky = g.centre_sky
                if len(img.islands) > 0:
                    island_offsets = zip(N.array(island_offsets_x), N.array(island_offsets_y))
                    isl_borders = collections.AsteriskPolygonCollection(4, offsets=island_offsets, color=border_color,
                                    transOffset=ax.transData, sizes=(10.0,))
                    ax.add_collection(isl_borders)

                if hasattr(img, 'gaussians'):
                    for atrg in img.gaussians:
                        if atrg.jlevel > 0 and atrg.gaus_num >= 0:
                            col = 'r'
                            style = '-'
                            gidx = atrg.gaus_num
                            e = Ellipse(xy=atrg.centre_pix, width=atrg.size_pix[0], height=atrg.size_pix[1], angle=atrg.size_pix[2]+90.0)
                            ax.add_artist(e)
                            e.set_picker(3)
                            e.set_clip_box(ax.bbox)
                            e.set_edgecolor(col)
                            e.set_facecolor('none')
                            e.set_alpha(0.8)
                            e.gaus_id = gidx
                            e.src_id = atrg.source_id
                            e.jlevel = atrg.jlevel
                            e.isl_id = atrg.island_id
                            e.tflux = atrg.total_flux
                            e.pflux = atrg.peak_flux
                            e.centre_sky = atrg.centre_sky

            if 'Flagged' in titles[i]:
                for iisl, isl in enumerate(img.islands):
                    ax = pl.gca()
                    style = '-'
                    for ig, g in enumerate(isl.fgaul):
                        col = colours[ig % 6]
                        ellx, elly = func.drawellipse(g)
                        gline, = ax.plot(ellx, elly, color = col,
                                         linestyle = style, picker=3)
                        gline.flag = g.flag

            if 'PSF' in titles[i]:
                cmd = 'ax' + str(i+1) + ".imshow(N.transpose(im), origin=origin, "\
                      "interpolation='nearest', cmap=gray_palette)"
            else:
                cmd = 'ax' + str(i+1) + ".imshow(N.transpose(im), origin=origin, "\
                      "interpolation='nearest',vmin=vmin, vmax=vmax, cmap=gray_palette)"
            exec cmd
            cmd = 'ax' + str(i+1) + '.format_coord = format_coord_'+names[i]
            exec cmd
            pl.title(titles[i])
        elif image == 'seds':
            cmd = 'ax' + str(i+1) + ' = pl.subplot(' + str(numx) + \
                ', ' + str(numy) + ', ' + str(i+1) + ')'
            exec cmd
            ax = pl.gca()
            plot_sed(sed_src, ax)

        elif image == 'wavelets':
            if i == index_first_waveplot:
                for j in range(len(j_with_gaus)):
                    cmd = 'ax' + str(j+i+1) + ' = pl.subplot(' + str(numx) + \
                        ', ' + str(numy) + ', ' + str(j+i+1) + ', sharex=ax1, '+\
                        'sharey=ax1)'
                    exec cmd
                    pl.title('Pyramidal Sources for\nWavelet Scale J = ' +
                             str(j_with_gaus[j]))
            for pyr in img.pyrsrcs:
              for iisl, isl in enumerate(pyr.islands):
                jj = pyr.jlevels[iisl]
                jindx = j_with_gaus.index(jj)
                col = colours[pyr.pyr_id % 6]
                ind = N.where(~isl.mask_active)
                cmd = "ax" + str(jindx + index_first_waveplot + 1) + \
                    ".plot(ind[0]+isl.origin[0], "\
                    "ind[1]+isl.origin[1], '.', color=col)"
                exec cmd

    fig.canvas.mpl_connect('key_press_event', on_press)
    fig.canvas.mpl_connect('pick_event', on_pick)
    pl.show()
    pl.close('all')