Esempio n. 1
0
class SingletViewer(WxMPLFitsViewer):
    """
    Displays a single FITS image at a time.
    """

    def __init__(self, parent):
        super(SingletViewer, self).__init__(parent)
        self.xy_changed = Signal()

    def _refresh_markers(self,cutout):
        self._displayables_by_cutout[cutout].clear_markers()
        self.mark_sources(self.current_cutout)

    def mark_apertures(self, cutout):
        logger.info("marking apertures on cutout.")
        x, y = cutout.pixel_source_point
        try:
            radii = (cutout.apcor.aperture, cutout.apcor.sky, cutout.apcor.swidth+cutout.apcor.sky)
        except:
            radii = (4, 15,30)
        self._displayables_by_cutout[cutout].place_annulus(x, y, radii, colour='r')

    def mark_sources(self, cutout):
        assert cutout in self._displayables_by_cutout

        x, y = cutout.pixel_source_point
        try:
            fwhm = float(cutout.astrom_header.get("FWHM",10))
        except:
            fwhm = 4.0
        radius = 2 * round(fwhm)

        colour = "b"
        if cutout.reading.from_input_file:
            if cutout.reading.null_observation:
                colour = "r"
            else:
                colour = "g"

        self._displayables_by_cutout[cutout].place_marker(x, y, radius,
                                                          colour=colour)

    def register_xy_changed_event_handler(self, handler):
        self.xy_changed.connect(handler)

    def _create_displayable(self, cutout):
        return DisplayableImageSinglet(cutout.hdulist)

    def _attach_handlers(self, displayable):
        displayable.xy_changed.connect(self.xy_changed.fire)
        displayable.focus_released.connect(self.release_focus)

    def _detach_handlers(self, displayable):
        if displayable is not None:
            displayable.xy_changed.disconnect(self.xy_changed.fire)
            displayable.focus_released.disconnect(self.release_focus)
Esempio n. 2
0
    def __init__(self, hdulist, figure, rect):
        self.hdulist = hdulist

        self.figure = figure
        self.axes = self._create_axes(rect)
        self.figure.add_axes(self.axes)

        self.marker = None

        self.display_changed = Signal()
        self.xy_changed = Signal()
        self.focus_released = Signal()

        self._colormap = GrayscaleColorMap()
        self._mpl_event_handlers = {}
        self._interaction_context = None
Esempio n. 3
0
class SingletViewer(WxMPLFitsViewer):
    """
    Displays a single FITS image at a time.
    """

    def __init__(self, parent):
        super(SingletViewer, self).__init__(parent)
        self.xy_changed = Signal()

    def _refresh_markers(self,cutout):
        self._displayables_by_cutout[cutout].clear_markers()
        self.mark_sources(self.current_cutout)

    def mark_sources(self, cutout):
        assert cutout in self._displayables_by_cutout

        x, y = cutout.pixel_source_point
        fwhm = float(cutout.astrom_header.get("FWHM",10))
        radius = 2 * round(fwhm)

        colour = "b"
        if cutout.reading.from_input_file:
            if cutout.reading.null_observation:
                colour = "r"
            else:
                colour = "g"

        self._displayables_by_cutout[cutout].place_marker(x, y, radius,
                                                          colour=colour)

    def register_xy_changed_event_handler(self, handler):
        self.xy_changed.connect(handler)

    def _create_displayable(self, cutout):
        return DisplayableImageSinglet(cutout.hdulist)

    def _attach_handlers(self, displayable):
        displayable.xy_changed.connect(self.xy_changed.fire)
        displayable.focus_released.connect(self.release_focus)

    def _detach_handlers(self, displayable):
        if displayable is not None:
            displayable.xy_changed.disconnect(self.xy_changed.fire)
            displayable.focus_released.disconnect(self.release_focus)
Esempio n. 4
0
    def __init__(self, hdulist, figure, rect):
        self.hdulist = hdulist
        self.figure = figure
        self.axes = self._create_axes(rect)
        #self.figure.add_axes(self.axes)

        self.marker = None

        self.display_changed = Signal()
        self.xy_changed = Signal()
        self.focus_released = Signal()

        self._colormap = GrayscaleColorMap()
        self._mpl_event_handlers = {}
        self._interaction_context = None
        self.number_of_images_displayed = 0
        self.frame_number = None
Esempio n. 5
0
class ImageSinglet(object):
    """
    A single image on a matplotlib axes.  Provides interaction and is markable.

    """

    def __init__(self, hdulist, figure, rect):
        self.hdulist = hdulist
        self.figure = figure
        self.axes = self._create_axes(rect)
        #self.figure.add_axes(self.axes)

        self.marker = None

        self.display_changed = Signal()
        self.xy_changed = Signal()
        self.focus_released = Signal()

        self._colormap = GrayscaleColorMap()
        self._mpl_event_handlers = {}
        self._interaction_context = None
        self.number_of_images_displayed = 0
        self.frame_number = None

    @property
    def width(self):
        return _image_width(self.hdulist)

    @property
    def height(self):
        return _image_height(self.hdulist)

    def show_image(self, colorbar=False):
        # start xpans if needed
        ds9.ds9_xpans()
        # start ds9 if need, or connect to existing
        display = ds9.ds9(target='validate')
        if self.frame_number is None:
            # display.set('frame delete all')
            display.set('frame new')
            display.set('scale zscale')
            display.set('cmap invert yes')
            f = StringIO()
            self.hdulist.writeto(f)
            f.flush()
            f.seek(0)
            hdulist = fits.open(f)
            for hdu in hdulist:
                del(hdu.header['PV*'])
            display.set_pyfits(hdulist)
            self.frame_number = display.get('frame frameno')
            display.set('frame center {}'.format(self.frame_number))
            display.set('zoom to fit')
            display.set('wcs align yes')
        display.set('frame frameno {}'.format(self.frame_number))

        self._interaction_context = InteractionContext(self)

        self.number_of_images_displayed += 1

    def clear_markers(self):
        display = ds9.ds9(target='valdiate')
        display.set('regions delete all')

    def place_marker(self, x, y, radius, colour="b"):
        """
        Draws a marker with the specified dimensions.  Only one marker can
        be on the image at a time, so any existing marker will be replaced.
        """
        display = ds9.ds9(target='validate')
        colour_string = {'r': 'red', 'b': 'blue'}.get(colour, 'green')
        display.set('regions', 'image; circle({},{},{}) # color={}'.format(x,y,radius,colour_string))

        #if self.marker is not None:
        #    self.marker.remove_from_axes(self.axes)
        #
        #self.marker = Marker(x, y, radius, colour=colour)
        #self.marker.add_to_axes(self.axes)

        self.display_changed.fire()

    def place_error_ellipse(self, x, y, a, b, pa, color='b'):
        """
        Draws an ErrorEllipse with the given dimensions.  Can not be moved later.
        """
        display = ds9.ds9(target='validate')
        # display.set('regions delete all')
        display.set('regions', 'image; ellipse({},{},{},{},{}'.format(x,y,a,b,pa+90))
        #self.error_ellipse = ErrEllipse(x, y, a, b, pa, color=color)
        #self.error_ellipse.add_to_axes(self.axes)
        self.display_changed.fire()

    def update_marker(self, x, y, radius=None):
        if self.marker is None:
            if radius is None:
                raise MPLViewerError("No marker to update.")
            else:
                # For convenience go ahead and make one
                self.place_marker(x, y, radius)

        self.marker.center = (x, y)

        if radius is not None:
            self.marker.radius = radius

        self.xy_changed.fire(x, y)
        self.display_changed.fire()

    def release_focus(self):
        self.focus_released.fire()

    def update_colormap(self, dx, dy):
        contrast_diff = float(-dy) / self.height
        bias_diff = float(dx) / self.width

        self._colormap.update_contrast(contrast_diff)
        self._colormap.update_bias(bias_diff)

        self._refresh_displayed_colormap()

    def reset_colormap(self):
        self._colormap.set_defaults()
        self._refresh_displayed_colormap()

    def toggle_reticule(self):
        self.marker.toggle_reticule()
        self.display_changed.fire()

    def is_event_in_axes(self, event):
        return self.axes == event.inaxes

    def register_mpl_event_handler(self, eventname, handler):
        return 0
#        handler_id = self.figure.canvas.mpl_connect(eventname, handler)
#        self._mpl_event_handlers[handler_id] = (eventname, handler)
#        return handler_id

    def deregister_mpl_event_handler(self, id_):
        return
#        self.figure.canvas.mpl_disconnect(id_)
#        del self._mpl_event_handlers[id_]

    def apply_event_handlers(self, canvas):
        for eventname, handler in self._mpl_event_handlers.itervalues():
            canvas.mpl_connect(eventname, handler)

    def _create_axes(self, rect):
        """
        Args:
          rect: [left, bottom, width, height]
            Used to construct the matplotlib axes.
        """
        return None

    def _refresh_displayed_colormap(self):
        self.axes_image.set_cmap(self._colormap.as_mpl_cmap())
        self.axes_image.changed()
        self.display_changed.fire()
Esempio n. 6
0
class ImageSinglet(object):
    """
    A single image on a matplotlib axes.  Provides interaction and is
    markable.
    """

    def __init__(self, hdulist, figure, rect):
        self.hdulist = hdulist

        self.figure = figure
        self.axes = self._create_axes(rect)
        self.figure.add_axes(self.axes)

        self.marker = None

        self.display_changed = Signal()
        self.xy_changed = Signal()
        self.focus_released = Signal()

        self._colormap = GrayscaleColorMap()
        self._mpl_event_handlers = {}
        self._interaction_context = None

    @property
    def image_data(self):
        return _image_data(self.hdulist)

    @property
    def width(self):
        return _image_width(self.hdulist)

    @property
    def height(self):
        return _image_height(self.hdulist)

    def show_image(self, colorbar=False):
        self._interaction_context = InteractionContext(self)

        extent = (1, self.width, 1, self.height)
        self.axes_image = self.axes.imshow(zscale(self.image_data),
                                           origin="lower",
                                           extent=extent,
                                           cmap=self._colormap.as_mpl_cmap())

        if colorbar:
            # Create axes for colorbar.  Make it tightly fit the image.
            divider = make_axes_locatable(self.axes)
            cax = divider.append_axes("bottom", size="5%", pad=0.05)
            self.figure.colorbar(self.axes_image, orientation="horizontal",
                                 cax=cax)

    def place_marker(self, x, y, radius, colour="b"):
        """
        Draws a marker with the specified dimensions.  Only one marker can
        be on the image at a time, so any existing marker will be replaced.
        """
        if self.marker is not None:
            self.marker.remove_from_axes(self.axes)

        self.marker = Marker(x, y, radius, colour=colour)
        self.marker.add_to_axes(self.axes)

        self.display_changed.fire()

    def place_error_ellipse(self, x, y, a, b, pa, color='b'):
        """
        Draws an ErrorEllipse with the given dimensions.  Can not be moved later.
        """
        self.error_ellipse = ErrEllipse(x, y, a, b, pa, color=color)
        self.error_ellipse.add_to_axes(self.axes)
        self.display_changed.fire()

    def update_marker(self, x, y, radius=None):
        if self.marker is None:
            if radius is None:
                raise MPLViewerError("No marker to update.")
            else:
                # For convenience go ahead and make one
                self.place_marker(x, y, radius)

        self.marker.center = (x, y)

        if radius is not None:
            self.marker.radius = radius

        self.xy_changed.fire(x, y)
        self.display_changed.fire()

    def release_focus(self):
        self.focus_released.fire()

    def update_colormap(self, dx, dy):
        contrast_diff = float(-dy) / self.height
        bias_diff = float(dx) / self.width

        self._colormap.update_contrast(contrast_diff)
        self._colormap.update_bias(bias_diff)

        self._refresh_displayed_colormap()

    def reset_colormap(self):
        self._colormap.set_defaults()
        self._refresh_displayed_colormap()

    def toggle_reticule(self):
        self.marker.toggle_reticule()
        self.display_changed.fire()

    def is_event_in_axes(self, event):
        return self.axes == event.inaxes

    def register_mpl_event_handler(self, eventname, handler):
        handler_id = self.figure.canvas.mpl_connect(eventname, handler)
        self._mpl_event_handlers[handler_id] = (eventname, handler)
        return handler_id

    def deregister_mpl_event_handler(self, id_):
        self.figure.canvas.mpl_disconnect(id_)
        del self._mpl_event_handlers[id_]

    def apply_event_handlers(self, canvas):
        for eventname, handler in self._mpl_event_handlers.itervalues():
            canvas.mpl_connect(eventname, handler)

    def _create_axes(self, rect):
        """
        Args:
          rect: [left, bottom, width, height]
            Used to construct the matplotlib axes.
        """
        axes = plt.Axes(self.figure, rect)

        # Don't draw tick marks and labels
        axes.set_axis_off()

        # FITS images start at pixel 1,1 in the bottom-left corner
        axes.set_xlim([1, self.width])
        axes.set_ylim([1, self.height])

        # Add a border around the image.
        axes.add_patch(plt.Rectangle((1, 1), self.width - 1, self.height - 1,
                       linewidth=3, edgecolor="black", fill=False))

        return axes

    def _refresh_displayed_colormap(self):
        self.axes_image.set_cmap(self._colormap.as_mpl_cmap())
        self.axes_image.changed()
        self.display_changed.fire()
Esempio n. 7
0
    def __init__(self, parent, canvas):
        super(SingletViewer, self).__init__(parent, canvas)

        self.xy_changed = Signal()
Esempio n. 8
0
class ImageSinglet(object):
    """
    A single image on a matplotlib axes.  Provides interaction and is markable.

    """

    def __init__(self, hdulist, figure, rect):
        self.hdulist = hdulist
        self.figure = figure
        self.axes = self._create_axes(rect)
        #self.figure.add_axes(self.axes)

        self.marker = None

        self.display_changed = Signal()
        self.xy_changed = Signal()
        self.focus_released = Signal()

        self._colormap = GrayscaleColorMap()
        self._mpl_event_handlers = {}
        self._interaction_context = None
        self.number_of_images_displayed = 0
        self.frame_number = None

    @property
    def width(self):
        return _image_width(self.hdulist)

    @property
    def height(self):
        return _image_height(self.hdulist)

    def show_image(self, colorbar=False):
        # start xpans if needed
        ds9.ds9_xpans()
        # start ds9 if need, or connect to existing
        display = ds9.ds9(target='validate')
        if self.frame_number is None:
            # display.set('frame delete all')
            display.set('frame new')
            display.set('scale zscale')
            display.set('cmap invert yes')
            f = StringIO()
            self.hdulist.writeto(f)
            f.flush()
            f.seek(0)
            hdulist = fits.open(f)
            for hdu in hdulist:
                del(hdu.header['PV*'])
            display.set_pyfits(hdulist)
            f.close()
            del(hdulist)
            self.frame_number = display.get('frame frameno')
            display.set('frame center {}'.format(self.frame_number))
            display.set('zoom to fit')
            display.set('wcs align yes')
        display.set('frame frameno {}'.format(self.frame_number))

        self._interaction_context = InteractionContext(self)

        self.number_of_images_displayed += 1

    def clear_markers(self):
        display = ds9.ds9(target='valdiate')
        display.set('regions delete all')

    def place_marker(self, x, y, radius, colour="b"):
        """
        Draws a marker with the specified dimensions.  Only one marker can
        be on the image at a time, so any existing marker will be replaced.
        """
        display = ds9.ds9(target='validate')
        colour_string = {'r': 'red', 'b': 'blue'}.get(colour, 'green')
        display.set('regions', 'image; circle({},{},{}) # color={}'.format(x,y,radius,colour_string))

        #if self.marker is not None:
        #    self.marker.remove_from_axes(self.axes)
        #
        #self.marker = Marker(x, y, radius, colour=colour)
        #self.marker.add_to_axes(self.axes)

        self.display_changed.fire()

    def place_error_ellipse(self, x, y, a, b, pa, color='b'):
        """
        Draws an ErrorEllipse with the given dimensions.  Can not be moved later.
        """
        display = ds9.ds9(target='validate')
        # display.set('regions delete all')
        display.set('regions', 'image; ellipse({},{},{},{},{}'.format(x,y,a,b,pa+90))
        #self.error_ellipse = ErrEllipse(x, y, a, b, pa, color=color)
        #self.error_ellipse.add_to_axes(self.axes)
        self.display_changed.fire()

    def update_marker(self, x, y, radius=None):
        if self.marker is None:
            if radius is None:
                raise MPLViewerError("No marker to update.")
            else:
                # For convenience go ahead and make one
                self.place_marker(x, y, radius)

        self.marker.center = (x, y)

        if radius is not None:
            self.marker.radius = radius

        self.xy_changed.fire(x, y)
        self.display_changed.fire()

    def release_focus(self):
        self.focus_released.fire()

    def update_colormap(self, dx, dy):
        contrast_diff = float(-dy) / self.height
        bias_diff = float(dx) / self.width

        self._colormap.update_contrast(contrast_diff)
        self._colormap.update_bias(bias_diff)

        self._refresh_displayed_colormap()

    def reset_colormap(self):
        self._colormap.set_defaults()
        self._refresh_displayed_colormap()

    def toggle_reticule(self):
        self.marker.toggle_reticule()
        self.display_changed.fire()

    def is_event_in_axes(self, event):
        return self.axes == event.inaxes

    def register_mpl_event_handler(self, eventname, handler):
        return 0
#        handler_id = self.figure.canvas.mpl_connect(eventname, handler)
#        self._mpl_event_handlers[handler_id] = (eventname, handler)
#        return handler_id

    def deregister_mpl_event_handler(self, id_):
        return
#        self.figure.canvas.mpl_disconnect(id_)
#        del self._mpl_event_handlers[id_]

    def apply_event_handlers(self, canvas):
        for eventname, handler in self._mpl_event_handlers.itervalues():
            canvas.mpl_connect(eventname, handler)

    def _create_axes(self, rect):
        """
        Args:
          rect: [left, bottom, width, height]
            Used to construct the matplotlib axes.
        """
        return None

    def _refresh_displayed_colormap(self):
        self.axes_image.set_cmap(self._colormap.as_mpl_cmap())
        self.axes_image.changed()
        self.display_changed.fire()
Esempio n. 9
0
 def __init__(self, parent):
     super(SingletViewer, self).__init__(parent)
     self.xy_changed = Signal()