Example #1
0
    def __init__(self):
        super(Desktop, self).__init__()
        
        # for tabs
        self.tab = Bunch.caselessDict()
        self.tabcount = 0
        self.notebooks = Bunch.caselessDict()

        for name in ('page-switch', 'page-select'):
            self.enable_callback(name)
Example #2
0
    def __init__(self):
        super(Desktop, self).__init__()
        
        # for tabs
        self.tab = Bunch.caselessDict()
        self.tabcount = 0
        self.notebooks = Bunch.caselessDict()

        self.toplevels = []
        
        for name in ('page-switch', 'page-select', 'all-closed'):
            self.enable_callback(name)
        self.popmenu = None
Example #3
0
    def __init__(self, app):
        super(Desktop, self).__init__()

        self.app = app
        # for tabs
        self.tab = Bunch.caselessDict()
        self.tabcount = 0
        self.workspace = Bunch.caselessDict()

        self.toplevels = []
        self._cur_dialogs = []

        for name in ('page-switch', 'all-closed'):
            self.enable_callback(name)
Example #4
0
    def __init__(self, fv):
        # superclass defines some variables for us, like logger
        super(Contents, self).__init__(fv)

        columns = [ ('Name', 'NAME'), ('Object', 'OBJECT'),
                    ('Date', 'DATE-OBS'), ('Time UT', 'UT'),
                     ]

        prefs = self.fv.get_preferences()
        self.settings = prefs.createCategory('plugin_Contents')
        self.settings.addDefaults(columns=columns, always_expand=True)
        self.settings.load(onError='silent')

        # For table-of-contents pane
        self.nameDict = Bunch.caselessDict()
        # TODO: this ought to be customizable by channel
        self.columns = self.settings.get('columns', columns)

        self.cell_sort_funcs = []
        for hdr, key in self.columns:
            self.cell_sort_funcs.append(self._mksrtfnN(key))

        self.gui_up = False
        fv.set_callback('add-image', self.add_image)
        fv.set_callback('remove-image', self.remove_image)
        fv.set_callback('delete-channel', self.delete_channel)
Example #5
0
    def __init__(self, fv):
        # superclass defines some variables for us, like logger
        super(Contents, self).__init__(fv)

        columns = [ ('Name', 'NAME'), ('Object', 'OBJECT'),
                    ('Date', 'DATE-OBS'), ('Time UT', 'UT'),
                     ]

        prefs = self.fv.get_preferences()
        self.settings = prefs.createCategory('plugin_Contents')
        self.settings.addDefaults(columns=columns, always_expand=True,
                                  highlight_tracks_keyboard_focus=False,
                                  color_alternate_rows=True)
        self.settings.load(onError='silent')

        # For table-of-contents pane
        self.name_dict = Bunch.caselessDict()
        # TODO: this ought to be customizable by channel
        self.columns = self.settings.get('columns', columns)
        self.treeview = None
        # paths of highlighted entries, by channel
        self._hl_path = {}
        self.highlight_tracks_keyboard_focus = self.settings.get(
            'highlight_tracks_keyboard_focus', False)

        self.gui_up = False
        fv.add_callback('add-image', self.add_image)
        fv.add_callback('remove-image', self.remove_image)
        fv.add_callback('add-channel', self.add_channel)
        fv.add_callback('delete-channel', self.delete_channel)
        if self.highlight_tracks_keyboard_focus:
            fv.add_callback('active-image', self.focus_cb)
            self._hl_path['none'] = None
Example #6
0
 def forget_masks(self):
     """Forget all loaded coordinates."""
     self._seqno = 1
     self._maskobjs = []
     self._treepaths = []
     self.tree_dict = Bunch.caselessDict()
     self.redo()
Example #7
0
    def recreate_imlist(self):
        """Refresh image list for new selection."""
        if not self.gui_up:
            return

        treedict = Bunch.caselessDict()
        for imname in self._imlist:
            treedict[imname] = Bunch.Bunch(IMAGE=imname)
        self.treeview.set_tree(treedict)
Example #8
0
    def __init__(self, fv, fitsimage):
        # superclass defines some variables for us, like logger
        super(TVMark, self).__init__(fv, fitsimage)

        self.layertag = 'tvmark-canvas'
        self.marktag = None
        self.markhltag = None

        self._mark_options = ['box', 'circle', 'cross', 'plus', 'point']
        self._color_options = self._short_color_list()
        self._dwidth = 2  # Additional width to highlight selection

        # User preferences. Some are just default values and can also be
        # changed by GUI.
        prefs = self.fv.get_preferences()
        self.settings = prefs.createCategory('plugin_TVMark')
        self.settings.load(onError='silent')
        self.marktype = self.settings.get('marktype', 'circle')
        self.markcolor = self.settings.get('markcolor', 'green')
        self.marksize = self.settings.get('marksize', 5)
        self.markwidth = self.settings.get('markwidth', 1)
        self.pixelstart = self.settings.get('pixelstart', 1)
        self.use_radec = self.settings.get('use_radec', True)
        self.extra_columns = self.settings.get('extra_columns', [])

        # Display coords info table
        self.treeview = None
        self.treeviewsel = None
        self.treeviewbad = None
        self.tree_dict = Bunch.caselessDict()
        self.columns = [('No.', 'MARKID'), ('RA', 'RA'), ('DEC', 'DEC'),
                        ('X', 'X'), ('Y', 'Y')]

        # Append extra columns to table header
        self.columns += [(colname, colname) for colname in self.extra_columns]

        # Store results
        self.coords_dict = defaultdict(list)
        self._xarr = []
        self._yarr = []
        self._treepaths = []

        self.dc = self.fv.getDrawClasses()

        canvas = self.dc.DrawingCanvas()
        canvas.enable_draw(True)
        canvas.enable_edit(False)
        canvas.set_callback('draw-event', self.hl_canvas2table_box)
        canvas.set_callback('cursor-down', self.hl_canvas2table)
        canvas.setSurface(self.fitsimage)
        canvas.set_drawtype('rectangle', color='green', linestyle='dash')
        self.canvas = canvas

        fv.add_callback('remove-image', lambda *args: self.redo())

        self.gui_up = False
Example #9
0
    def recreate_pxdq(self, dqparser, dqs, pixval):
        """Refresh single pixel results table with given data."""
        if not self.gui_up:
            return

        dqstr = self.settings.get('dqstr', 'long')
        treedict = Bunch.caselessDict()

        for row in dqs:
            flag = row[dqparser._dqcol]
            val = row[dqstr]
            treedict[str(flag)] = Bunch.Bunch(FLAG=flag, DESCRIP=val)

        self.pxdqlist.set_tree(treedict)
        self.w.dq.set_text(str(pixval))
Example #10
0
    def __init__(self, logger, fitsview, ds, mm):
        super(PluginManagerBase, self).__init__()

        self.logger = logger
        self.fv = fitsview
        self.ds = ds
        self.mm = mm

        self.lock = threading.RLock()
        self.plugin = Bunch.caselessDict()
        self.active = {}
        self.focus  = set([])
        self.exclusive = set([])
        self.focuscolor = "lightgreen"

        self.hbox = None
Example #11
0
    def stop(self):
        # remove canvas from image
        p_canvas = self.fitsimage.get_canvas()
        try:
            p_canvas.delete_object_by_tag(self.layertag)
        except Exception:
            pass

        # Free some memory, maybe
        self.tree_dict = Bunch.caselessDict()
        self._xarr = []
        self._yarr = []
        self._treepaths = []

        self.gui_up = False
        self.fv.show_status('')
Example #12
0
    def __init__(self, fv, fitsimage):
        # superclass defines some variables for us, like logger
        super(TVMask, self).__init__(fv, fitsimage)

        self.layertag = 'tvmask-canvas'
        self.masktag = None
        self.maskhltag = None

        self._color_options = self._short_color_list()

        # User preferences. Some are just default values and can also be
        # changed by GUI.
        prefs = self.fv.get_preferences()
        self.settings = prefs.create_category('plugin_TVMask')
        self.settings.add_defaults(maskcolor='green', maskalpha=0.5,
                                   hlcolor='white', hlalpha=1.0)
        self.settings.load(onError='silent')
        self.maskcolor = self.settings.get('maskcolor', 'green')
        self.maskalpha = self.settings.get('maskalpha', 0.5)
        self.hlcolor = self.settings.get('hlcolor', 'white')
        self.hlalpha = self.settings.get('hlalpha', 1.0)

        # Display coords info table
        self.treeview = None
        self.tree_dict = Bunch.caselessDict()
        self.columns = [('No.', 'ID'), ('Filename', 'MASKFILE')]

        # Store results
        self._seqno = 1
        self._maskobjs = []
        self._treepaths = []

        self.dc = self.fv.get_draw_classes()

        canvas = self.dc.DrawingCanvas()
        canvas.enable_draw(True)
        canvas.enable_edit(False)
        canvas.set_callback('draw-event', self.hl_canvas2table_box)
        #canvas.set_callback('cursor-down', self.hl_canvas2table)
        canvas.register_for_cursor_drawing(self.fitsimage)
        canvas.set_surface(self.fitsimage)
        canvas.set_drawtype('rectangle', color='green', linestyle='dash')
        self.canvas = canvas

        fv.add_callback('remove-image', lambda *args: self.redo())

        self.gui_up = False
Example #13
0
    def __init__(self, logger, fitsview, ds, mm):
        super(PluginManager, self).__init__()

        self.logger = logger
        self.fv = fitsview
        self.ds = ds
        self.mm = mm

        self.lock = threading.RLock()
        self.plugin = Bunch.caselessDict()
        self.active = {}
        self.focus  = set([])
        self.exclusive = set([])

        for name in ('activate-plugin', 'deactivate-plugin',
                     'focus-plugin', 'unfocus-plugin'):
            self.enable_callback(name)
Example #14
0
    def get_keystroke(self):
        self.logger.info("get_keystroke() called")
        chinfo = self.fv.get_channelInfo()
        fitsimage = chinfo.fitsimage
        # Find out which frame we are looking at
        #frame = self.current_frame
        frame = self.channel_to_frame(chinfo.name)
        image = fitsimage.get_image()

        self.start_imexamine(fitsimage, chinfo.name)

        self.keyevent.wait()
        evt = self.keyqueue.get()

        self.stop_imexamine(fitsimage, chinfo.name)

        res = Bunch.Bunch(x=evt.x, y=evt.y, key=evt.key, frame=frame)
        return res
Example #15
0
    def get_scaled_cutout(self,
                          x1,
                          y1,
                          x2,
                          y2,
                          scale_x,
                          scale_y,
                          method='basic'):
        if method == 'basic':
            return self.get_scaled_cutout_basic(x1, y1, x2, y2, scale_x,
                                                scale_y)

        data = self._get_data()
        newdata, (scale_x, scale_y) = trcalc.get_scaled_cutout_basic(
            data, x1, y1, x2, y2, scale_x, scale_y, interpolation=method)

        res = Bunch.Bunch(data=newdata, scale_x=scale_x, scale_y=scale_y)
        return res
Example #16
0
def register_wcs(name, wrapper_class, coord_types):
    """Register a custom WCS wrapper.

    Parameters
    ----------
    name : str
        The name of the custom WCS wrapper

    wrapper_class : subclass of `~ginga.util.wcsmod.BaseWCS`
        The class implementing the WCS wrapper

    coord_types : list of str
        List of names of coordinate types supported by the WCS
    """
    global custom_wcs
    custom_wcs[wcs_name] = Bunch.Bunch(name=name,
                                       wrapper_class=wrapper_class,
                                       coord_types=coord_types)
Example #17
0
    def __init__(self, logger, full_name, short_name, survey, description):
        self.logger = logger
        self.full_name = full_name
        self.short_name = short_name
        self.kind = 'astroquery-image'
        self.querymod = SkyView
        self.survey = survey

        # For compatibility with other Ginga catalog servers
        self.params = {}
        count = 0
        for label, key in (('RA', 'ra'), ('DEC', 'dec'), ('Width', 'width'),
                           ('Height', 'height')):
            self.params[key] = Bunch.Bunch(name=key,
                                           convert=str,
                                           label=label,
                                           order=count)
            count += 1
Example #18
0
    def select_child_cb(self, layout, event, subwin):
        ex, ey = event.x_root, event.y_root

        x, y = self.get_widget_position(subwin.frame)
        subwin.x, subwin.y = x, y

        # make this the selected widget
        idx = self.page_num(subwin.widget)
        if idx >= 0:
            self.set_current_page(idx)

        self.selected_child = Bunch.Bunch(subwin=subwin,
                                          action='move',
                                          x_origin=x,
                                          y_origin=y,
                                          dx=ex,
                                          dy=ey)
        return True
Example #19
0
    def recreate_imdq(self, dqparser):
        """Refresh image DQ results table with given data."""
        if not self.gui_up:
            return

        dqstr = self.settings.get('dqstr', 'long')
        treedict = Bunch.caselessDict()

        for key in self._curpxmask:
            if len(self._curpxmask[key][0]) == 0:
                continue

            row = dqparser.tab[dqparser.tab[dqparser._dqcol] == key]
            flag = row[dqparser._dqcol][0]
            val = row[dqstr][0]
            treedict[str(flag)] = Bunch.Bunch(FLAG=flag, DESCRIP=val)

        self.imdqlist.set_tree(treedict)
Example #20
0
    def __init__(self, logger, full_name, key, url, description):
        self.logger = logger
        self.full_name = full_name
        self.short_name = key
        self.description = description
        self.kind = 'pyvo-image'
        self.url = url

        # For compatibility with other Ginga catalog servers
        self.params = {}
        count = 0
        for label, key in (('RA', 'ra'), ('DEC', 'dec'), ('Width', 'width'),
                           ('Height', 'height')):
            self.params[key] = Bunch.Bunch(name=key,
                                           convert=str,
                                           label=label,
                                           order=count)
            count += 1
Example #21
0
    def add_channel(self, viewer, channel):
        info = Bunch.Bunch(chinfo=channel)
        channel.extdata._wcsmatch_info = info

        # Add callbacks to the viewer for all the scale, pan, rotation and
        # transform settings changes
        chviewer = channel.fitsimage
        fitssettings = chviewer.get_settings()
        fitssettings.get_setting('scale').add_callback('set', self.zoomset_cb,
                                                       chviewer, info)
        fitssettings.get_setting('rot_deg').add_callback(
            'set', self.rotset_cb, chviewer, info)
        for name in ('flip_x', 'flip_y', 'swap_xy'):
            fitssettings.get_setting(name).add_callback(
                'set', self.xfmset_cb, chviewer, info)
        fitssettings.get_setting('pan').add_callback('set', self.panset_cb,
                                                     chviewer, info)
        self.fv.gui_do(self._reset_channels_gui)
Example #22
0
def get_relative_orientation(image, ref_image):
    """Computes the relative orientation and scale of an image to a reference
    image.

    Parameters
    ----------
    image
        AstroImage based object

    ref_image
        AstroImage based object

    Returns
    -------
    result
        Bunch object containing the relative scale in x and y
        and the relative rotation in degrees.

    """
    # Get reference image rotation and scale
    header = ref_image.get_header()
    ((xrot_ref, yrot_ref),
     (cdelt1_ref, cdelt2_ref)) = get_xy_rotation_and_scale(header)

    scale_x, scale_y = math.fabs(cdelt1_ref), math.fabs(cdelt2_ref)

    # Get rotation and scale of image
    header = image.get_header()
    ((xrot, yrot),
     (cdelt1, cdelt2)) = get_xy_rotation_and_scale(header)

    # Determine relative scale of this image to the reference
    rscale_x = math.fabs(cdelt1) / scale_x
    rscale_y = math.fabs(cdelt2) / scale_y

    # Figure out rotation relative to our orientation
    rrot_dx, rrot_dy = xrot - xrot_ref, yrot - yrot_ref

    # Choose Y rotation as default
    rrot_deg = rrot_dy

    res = Bunch.Bunch(rscale_x=rscale_x, rscale_y=rscale_y,
                      rrot_deg=rrot_deg)
    return res
Example #23
0
    def __init__(self, logger, container):
        super(CatalogListing, self).__init__()

        self.logger = logger
        self.tag = None
        self.cmap_names = cmap.get_names()
        self.imap_names = imap.get_names()
        self.magcmap = 'stairs8'
        self.magimap = 'ramp'

        self.mag_field = 'mag'
        self.mag_max = 25.0
        self.mag_min = 0.0
        self.color_default = 'skyblue'

        # keys: are name, ra, dec, mag, flag, b_r, preference, priority, dst
        # TODO: automate this generation
        self.columns = [
            ('Name', 'name'),
            ('RA', 'ra'),
            ('DEC', 'dec'),
            ('Mag', 'mag'),
            ('Preference', 'preference'),
            ('Priority', 'priority'),
            ('Description', 'description'),
            ('Index', 'index'),
        ]

        self.catalog = None
        self.cursor = 0
        self.color_selected = 'skyblue'
        self.selection_mode = 'single'
        self.selected = []
        self.moving_cursor = False

        self.btn = Bunch.Bunch()

        self.cmap = cmap.get_cmap(self.magcmap)
        self.imap = imap.get_imap('ramp')

        self.operation_table = []
        self._select_flag = False

        self._build_gui(container)
Example #24
0
    def open_file(self, filespec, memmap=None, **kwargs):

        info = iohelper.get_fileinfo(filespec)
        if not info.ondisk:
            raise FITSError("File does not appear to be on disk: %s" %
                            (info.url))

        self.fileinfo = info
        filepath = info.filepath

        self.logger.debug("Loading file '%s' ..." % (filepath))
        fits_f = fitsio.FITS(filepath, memmap=memmap)
        self.fits_f = fits_f

        extver_db = {}
        self.extver_db = extver_db
        self.hdu_info = []
        self.hdu_db = {}

        for idx in range(len(fits_f)):
            hdu = fits_f[idx]
            hduinfo = hdu.get_info()
            name = hduinfo['extname']
            # figure out the EXTVER for this HDU
            #extver = hduinfo['extver']
            extver = extver_db.setdefault(name, 0)
            extver += 1
            extver_db[name] = extver

            # prepare a record of pertinent info about the HDU for
            # lookups by numerical index or (NAME, EXTVER)
            d = Bunch.Bunch(index=idx, name=name, extver=extver)
            hdutype = self.hdutypes.get(hduinfo['hdutype'], 'UNKNOWN')
            d.setvals(htype=hdutype, dtype=str(hduinfo.get('img_type', None)))
            self.hdu_info.append(d)
            # different ways of accessing this HDU:
            # by numerical index
            self.hdu_db[idx] = d
            # by (hduname, extver)
            key = (name, extver)
            if len(name) > 0 and extver >= 0 and key not in self.hdu_db:
                self.hdu_db[key] = d

        return self
Example #25
0
    def add_channel(self, viewer, chinfo):
        panimage = self._create_pan_image()
        chname = chinfo.name
        
        iw = panimage.get_widget()
        iw.show()
        self.nb.append_page(iw, gtk.Label(chname))
        index = self.nb.page_num(iw)
        paninfo = Bunch.Bunch(panimage=panimage, widget=iw,
                              pancompass=None, panrect=None,
                              nbindex=index)
        self.channel[chname] = paninfo

        # Extract RGBMap object from main image and attach it to this
        # pan image
        fitsimage = chinfo.fitsimage
        rgbmap = fitsimage.get_rgbmap()
        panimage.set_rgbmap(rgbmap, redraw=False)
        rgbmap.add_callback('changed', self.rgbmap_cb, panimage)

        fitsimage.copy_attributes(panimage, ['cutlevels'])
        
        fitsimage.add_callback('image-set', self.new_image_cb, chinfo, paninfo)
        fitsimage.add_callback('pan-set', self.panset, chinfo, paninfo)

        fitssettings = fitsimage.get_settings()
        pansettings = panimage.get_settings()
        
        zoomsettings = ['zoom_algorithm', 'zoom_rate', 'scale_x_base', 'scale_y_base']
        fitssettings.shareSettings(pansettings, zoomsettings)
        for key in zoomsettings:
            pansettings.getSetting(key).add_callback('set', self.zoom_cb,
                                                     fitsimage, chinfo, paninfo)

        xfrmsettings = ['flip_x', 'flip_y', 'swap_xy', 'locut', 'hicut']
        fitssettings.shareSettings(pansettings, xfrmsettings)
        for key in xfrmsettings:
            pansettings.getSetting(key).add_callback('set', self.redraw_cb,
                                                     fitsimage, chinfo, paninfo, 0.5)
            
        fitssettings.shareSettings(pansettings, ['rot_deg'])
        pansettings.getSetting('rot_deg').add_callback('set', self.redraw_cb,
                                                       fitsimage, chinfo, paninfo, 0)
        self.logger.debug("channel %s added." % (chinfo.name))
Example #26
0
    def __init__(self, fv, fitsimage):
        # superclass defines some variables for us, like logger
        super(TVMask, self).__init__(fv, fitsimage)

        self.layertag = 'tvmask-canvas'
        self.masktag = None
        self.maskhltag = None

        self._color_options = self._short_color_list()

        # User preferences. Some are just default values and can also be
        # changed by GUI.
        prefs = self.fv.get_preferences()
        self.settings = prefs.create_category('plugin_TVMask')
        self.settings.load(onError='silent')
        self.maskcolor = self.settings.get('maskcolor', 'green')
        self.maskalpha = self.settings.get('maskalpha', 0.5)
        self.hlcolor = self.settings.get('hlcolor', 'white')
        self.hlalpha = self.settings.get('hlalpha', 1.0)

        # Display coords info table
        self.treeview = None
        self.tree_dict = Bunch.caselessDict()
        self.columns = [('No.', 'ID'), ('Filename', 'MASKFILE')]

        # Store results
        self._seqno = 1
        self._maskobjs = []
        self._treepaths = []

        self.dc = self.fv.get_draw_classes()

        canvas = self.dc.DrawingCanvas()
        canvas.enable_draw(True)
        canvas.enable_edit(False)
        canvas.set_callback('draw-event', self.hl_canvas2table_box)
        canvas.set_callback('cursor-down', self.hl_canvas2table)
        canvas.set_surface(self.fitsimage)
        canvas.set_drawtype('rectangle', color='green', linestyle='dash')
        self.canvas = canvas

        fv.add_callback('remove-image', lambda *args: self.redo())

        self.gui_up = False
Example #27
0
    def activate(self, pInfo, exclusive=True):
        name = pInfo.tabname
        lname = pInfo.name.lower()
        if lname not in self.active:
            bnch = Bunch.Bunch(pInfo=pInfo, lblname=None, widget=None,
                               exclusive=exclusive)

            if pInfo.chinfo is not None:
                # local plugin
                tup = name.split(':')
                bnch.lblname = ' ' + tup[0] + ':\n' + tup[1] + ' '
                self.make_callback('activate-plugin', bnch)
            else:
                # global plugin
                bnch.exclusive = False

            self.active[lname] = bnch
            if bnch.exclusive:
                self.exclusive.add(lname)
Example #28
0
    def info_xy(self, data_x, data_y, settings):
        # Get the value under the data coordinates
        try:
            # We report the value across the pixel, even though the coords
            # change halfway across the pixel
            _d_x, _d_y = int(np.floor(data_x + 0.5)), int(
                np.floor(data_y + 0.5))
            value = self.get_data_xy(_d_x, _d_y)

        except Exception as e:
            value = None

        info = Bunch.Bunch(itype='base',
                           data_x=data_x,
                           data_y=data_y,
                           x=data_x,
                           y=data_y,
                           value=value)
        return info
Example #29
0
    def get_info(self, path):
        dirname, filename = os.path.split(path)
        name, ext = os.path.splitext(filename)
        ftype = 'file'
        if os.path.isdir(path):
            ftype = 'dir'
        elif os.path.islink(path):
            ftype = 'link'
        elif ext.lower() == '.fits':
            ftype = 'fits'

        filestat = os.stat(path)
        bnch = Bunch.Bunch(path=path,
                           name=filename,
                           type=ftype,
                           st_mode=filestat.st_mode,
                           st_size=filestat.st_size,
                           st_mtime=filestat.st_mtime)
        return bnch
Example #30
0
        def process_common_params(widget, inparams):
            params = Bunch.Bunch(name=None, height=-1, width=-1, xpos=-1, ypos=-1)
            params.update(inparams)
            
            if params.name:
                widgetDict[params.name] = widget

            if (params.width >= 0) or (params.height >= 0):
                widget.set_size_request(params.width, params.height)
                #pass

            # User wants to place window somewhere
            if params.xpos >= 0:
                #widget.show()
                win = widget.get_window()
                if win != None:
                    win.move(params.xpos, params.ypos)

            return params
Example #31
0
def get_ruler_distances(image, p1, p2):
    """Get the distance calculated between two points.  A Bunch of
    results is returned, containing pixel values and distance values
    if the image contains a valid WCS.
    """
    x1, y1 = p1[:2]
    x2, y2 = p2[:2]

    dx, dy = x2 - x1, y2 - y1
    res = Bunch.Bunch(x1=x1, y1=y1, x2=x2, y2=y2,
                      theta=np.arctan2(y2 - y1, x2 - x1),
                      dx_pix=dx, dy_pix=dy,
                      dh_pix=np.sqrt(dx**2 + dy**2),
                      ra_org=None, dec_org=None,
                      ra_dst=None, dec_dst=None,
                      ra_heel=None, dec_heel=None,
                      dx_deg=None, dy_deg=None, dh_deg=None)

    if image is not None and hasattr(image, 'wcs') and image.wcs is not None:
        # Calculate RA and DEC for the three points
        try:
            # origination point
            ra_org, dec_org = image.pixtoradec(x1, y1)
            res.ra_org, res.dec_org = ra_org, dec_org

            # destination point
            ra_dst, dec_dst = image.pixtoradec(x2, y2)
            res.ra_dst, res.dec_dst = ra_dst, dec_dst

            # "heel" point making a right triangle
            ra_heel, dec_heel = image.pixtoradec(x2, y1)
            res.ra_heel, res.dec_heel = ra_heel, dec_heel

            res.dh_deg = deltaStarsRaDecDeg(ra_org, dec_org,
                                            ra_dst, dec_dst)
            res.dx_deg = deltaStarsRaDecDeg(ra_org, dec_org,
                                            ra_heel, dec_heel)
            res.dy_deg = deltaStarsRaDecDeg(ra_heel, dec_heel,
                                            ra_dst, dec_dst)
        except Exception as e:
            pass

    return res
Example #32
0
    def make_thumbs(self):
        path = self.curpath
        self.logger.info("Generating thumbnails for '%s'..." % (path))
        filelist = glob.glob(path)
        filelist.sort(key=lambda s: s.lower())

        if self.fitsimage is not None:
            # we were invoked as a local plugin
            channel = self.channel
        else:
            chviewer = self.fv.getfocus_viewer()
            # find out our channel
            chname = self.fv.get_channel_name(chviewer)
            channel = self.fv.get_channel(chname)

        for path in filelist:
            name = self.fv.name_image_from_path(path)
            info = Bunch.Bunch(name=name, path=path)
            self.fv.nongui_do(channel.add_image_info, info)
Example #33
0
    def add_image_cb(self, viewer, chname, image, info):

        # Get any previously stored thumb information in the image info
        thumb_extra = info.setdefault('thumb_extras', Bunch.Bunch())

        # Get metadata for mouse-over tooltip
        metadata = self._get_tooltip_metadata(info, image)

        # Update the tooltip, in case of new or changed metadata
        text = self._mk_tooltip_text(metadata)
        thumb_extra.tooltip = text

        if not self.gui_up:
            return False

        channel = self.fv.get_channel(chname)

        if thumb_extra.get('time_update', None) is None:
            self.fv.gui_do(self.redo_thumbnail_image, channel, image, info)
Example #34
0
    def window_key_press(self, canvas, keyname):
        if not self.imexam_active:
            return
        self.logger.info("key pressed: %s" % (keyname))
        if len(keyname) > 1:
            if keyname in ('shift_l', 'shift_r'):
                # ignore these keystrokes
                return
            elif keyname in ('control_l', 'control_r'):
                # control key combination
                self.ctrldown = True
                return
            elif keyname == 'space':
                self.toggleMode()
                return
            keyname = self.keymap.get(keyname, '?')

        if self.mode != 'iraf':
            return

        if self.ctrldown:
            if keyname == 'd':
                # User typed ^D
                keyname = chr(4)

        # Get cursor position
        fitsimage = canvas.getSurface()
        last_x, last_y = fitsimage.get_last_data_xy()

        # Correct for surrounding framebuffer
        image = fitsimage.get_image()
        if isinstance(image, IRAF_AstroImage):
            last_x, last_y = image.get_corrected_xy(last_x, last_y)

        # Get frame info
        #frame = self.current_frame
        chname = self.fv.get_channelName(fitsimage)
        chinfo = self.fv.get_channelInfo(chname)
        frame = self.channel_to_frame(chinfo.name)

        self.keyqueue.put(
            Bunch.Bunch(x=last_x, y=last_y, key=keyname, frame=frame))
        self.keyevent.set()
Example #35
0
    def set_table_cb(self, viewer, table):
        """Display the given table object."""
        self.clear()
        tree_dict = OrderedDict()

        # Extract data as astropy table
        a_tab = table.get_data()

        # Fill masked values, if applicable
        try:
            a_tab = a_tab.filled()
        except Exception:  # Just use original table
            pass

        # This is to get around table widget not sorting numbers properly
        i_fmt = '{{0:0{0}d}}'.format(len(str(len(a_tab))))

        # Table header with units
        columns = [('Row', '_DISPLAY_ROW')]
        for c in itervalues(a_tab.columns):
            col_str = '{0:^s}\n{1:^s}'.format(c.name, str(c.unit))
            columns.append((col_str, c.name))

        self.widget.setup_table(columns, 1, '_DISPLAY_ROW')

        # Table contents
        for i, row in enumerate(a_tab, 1):
            bnch = Bunch.Bunch(zip(row.colnames, row.as_void()))
            i_str = i_fmt.format(i)
            bnch['_DISPLAY_ROW'] = i_str
            tree_dict[i_str] = bnch

        self.widget.set_tree(tree_dict)

        # Resize column widths
        n_rows = len(tree_dict)
        if n_rows < self.settings.get('max_rows_for_col_resize', 5000):
            self.widget.set_optimal_column_widths()
            self.logger.debug('Resized columns for {0} row(s)'.format(n_rows))

        tablename = table.get('name', 'NoName')
        self.logger.debug('Displayed {0}'.format(tablename))
Example #36
0
    def redo_thumbnail_image(self, channel, image, info, save_thumb=None):
        # image is flagged not to make a thumbnail?
        nothumb = (image.get('nothumb', False)
                   or not channel.settings.get('genthumb', True))
        if nothumb:
            return

        self.logger.debug("redoing thumbnail ...")
        if save_thumb is None:
            save_thumb = self.settings.get('cache_thumbs', False)

        # Get any previously stored thumb information in the image info
        thumb_extra = info.setdefault('thumb_extras', Bunch.Bunch())

        # Get metadata for mouse-over tooltip
        metadata = self._get_tooltip_metadata(info, image)

        chname = channel.name
        thumbkey = self.get_thumb_key(chname, info.name, info.path)
        with self.thmblock:
            if thumbkey not in self.thumb_dict:
                # No memory of this thumbnail, so regenerate it
                self.logger.debug("No memory of %s, adding..." %
                                  (str(thumbkey)))
                self._add_image(self.fv, chname, image)
                return

            # Generate new thumbnail
            self.logger.debug("generating new thumbnail")
            thmb_image = self._regen_thumb_image(image, channel.fitsimage)
            thumb_extra.time_update = time.time()

            # Save a thumbnail for future browsing
            if save_thumb and info.path is not None:
                thumbpath = self.get_thumbpath(info.path)
                if thumbpath is not None:
                    if os.path.exists(thumbpath):
                        os.remove(thumbpath)
                    thmb_image.save_as_file(thumbpath)

            self.update_thumbnail(thumbkey, thmb_image, metadata)
        self.fv.update_pending()
Example #37
0
def build_info(captions):
    vbox = gtk.VBox(spacing=2)

    numrows = len(captions)
    numcols = reduce(lambda acc, tup: max(acc, len(tup)), captions, 0)
    table = gtk.Table(rows=numrows, columns=numcols)
    table.set_row_spacings(2)
    table.set_col_spacings(4)
    vbox.pack_start(table, expand=False)

    wb = Bunch.Bunch()
    row = 0
    for tup in captions:
        col = 0
        while col < numcols:
            if col < len(tup):
                tup1 = tup[col:col + 2]
                w1, w2 = _make_widget(tup1, wb)
                table.attach(w1,
                             col,
                             col + 1,
                             row,
                             row + 1,
                             xoptions=gtk.FILL,
                             yoptions=gtk.FILL,
                             xpadding=1,
                             ypadding=1)
                table.attach(w2,
                             col + 1,
                             col + 2,
                             row,
                             row + 1,
                             xoptions=gtk.FILL,
                             yoptions=gtk.FILL,
                             xpadding=1,
                             ypadding=1)
            col += 2
        row += 1

    vbox.show_all()

    return vbox, wb
Example #38
0
    def add_channel(self, viewer, channel):
        chname = channel.name
        info = Bunch.Bunch(chinfo=channel)
        self.channel[chname] = info

        # Add callbacks to the viewer for all the scale, pan, rotation and
        # transform settings changes
        fitsimage = channel.fitsimage
        fitssettings = fitsimage.get_settings()
        fitsimage.add_callback('image-set', self.new_image_cb, info)
        fitssettings.getSetting('scale').add_callback('set', self.zoomset_cb,
                                                      fitsimage, info)
        fitssettings.getSetting('rot_deg').add_callback(
            'set', self.rotset_cb, fitsimage, info)
        for name in ('flip_x', 'flip_y', 'swap_xy'):
            fitssettings.getSetting(name).add_callback('set', self.xfmset_cb,
                                                       fitsimage, info)
        fitssettings.getSetting('pan').add_callback('set', self.panset_cb,
                                                    fitsimage, info)
        self.fv.gui_do(self._reset_channels_gui)
Example #39
0
    def add_schedule(self, schedule):
        target_list = []
        i, j = 0, 0

        for slot in schedule.slots:
            ob = slot.ob
            if ob != None:
                if not ob.derived:
                    # not an OB generated to serve another OB
                    i += 1
                    #txt = "%d [%s]" % (i, ob.target.name)
                    txt = "%d [%s]" % (i, ob.name)
                    #txt = "%d" % (i)
                    color = self.colors[j]
                    j = (j + 1) % len(self.colors)
                    target_list.append(
                        (ob.target, slot.start_time, txt, color))

        self.schedules[schedule] = Bunch.Bunch(targets=target_list)
        return True
Example #40
0
    def get_scaled_cutout_wdht(self,
                               x1,
                               y1,
                               x2,
                               y2,
                               new_wd,
                               new_ht,
                               method='bicubic'):
        newdata, (scale_x, scale_y) = trcalc.get_scaled_cutout_wdht(
            self._get_data(),
            x1,
            y1,
            x2,
            y2,
            new_wd,
            new_ht,
            interpolation=method)

        res = Bunch.Bunch(data=newdata, scale_x=scale_x, scale_y=scale_y)
        return res
Example #41
0
    def add_channel(self, viewer, channel):
        if not self.gui_up:
            return
        fitsimage = channel.fitsimage
        panimage = self._create_pan_viewer(fitsimage)

        iw = Viewers.GingaViewerWidget(panimage)
        iw.resize(self._wd, self._ht)
        self.nb.add_widget(iw)
        #index = self.nb.index_of(iw)
        paninfo = Bunch.Bunch(panimage=panimage, widget=iw,
                              compass_wcs=None, compass_xy=None,
                              panrect=None)
        channel.extdata._pan_info = paninfo

        fitsimage.copy_attributes(panimage, self.copy_attrs)

        fitsimage.add_callback('redraw', self.redraw_cb, channel)

        self.logger.debug("channel '%s' added." % (channel.name))
Example #42
0
    def __init__(self, logger, full_name, key, url, description):
        if not have_pyvo:
            raise ImportError('pyvo not found, please install pyvo')

        self.logger = logger
        self.full_name = full_name
        self.short_name = key
        self.description = description
        self.kind = 'pyvo-catalog'
        self.url = url

        # For compatibility with URL catalog servers
        self.params = {}
        count = 0
        for label, key in (('RA', 'ra'), ('DEC', 'dec'), ('Radius', 'r')):
            self.params[key] = Bunch.Bunch(name=key,
                                           convert=str,
                                           label=label,
                                           order=count)
            count += 1
Example #43
0
    def __init__(self, fv):
        # superclass defines some variables for us, like logger
        super(Toolbar, self).__init__(fv)

        # active view
        self.active = None
        # holds our gui widgets
        self.w = Bunch.Bunch()
        self.gui_up = False

        # get local plugin preferences
        prefs = self.fv.get_preferences()
        self.settings = prefs.createCategory('plugin_Toolbar')
        self.settings.load(onError='silent')

        self.modetype = self.settings.get('mode_type', 'oneshot')

        fv.set_callback('add-channel', self.add_channel_cb)
        fv.set_callback('delete-channel', self.delete_channel_cb)
        fv.set_callback('channel-change', self.focus_cb)
Example #44
0
    def __init__(self, fv):
        # superclass defines some variables for us, like logger
        super(Contents, self).__init__(fv)

        columns = [('Name', 'NAME'), ('Object', 'OBJECT'),
                   ('Date', 'DATE-OBS'), ('Time UT', 'UT'),
                   ('Modified', 'MODIFIED')]

        spec = self.fv.get_plugin_spec(str(self))

        prefs = self.fv.get_preferences()
        self.settings = prefs.create_category('plugin_Contents')
        self.settings.add_defaults(columns=columns,
                                   always_expand=True,
                                   highlight_tracks_keyboard_focus=True,
                                   color_alternate_rows=True,
                                   row_font_color='green',
                                   closeable=not spec.get('hidden', False),
                                   max_rows_for_col_resize=100)
        self.settings.load(onError='silent')

        # For table-of-contents pane
        self.name_dict = Bunch.caselessDict()
        # TODO: this ought to be customizable by channel
        self.columns = self.settings.get('columns', columns)
        self.treeview = None
        # paths of highlighted entries, by channel
        self.highlight_tracks_keyboard_focus = self.settings.get(
            'highlight_tracks_keyboard_focus', True)
        self._hl_path = set([])
        self.chnames = []

        fv.add_callback('add-image', self.add_image_cb)
        fv.add_callback('remove-image', self.remove_image_cb)
        fv.add_callback('add-image-info', self.add_image_info_cb)
        fv.add_callback('remove-image-info', self.remove_image_info_cb)
        fv.add_callback('add-channel', self.add_channel_cb)
        fv.add_callback('delete-channel', self.delete_channel_cb)
        fv.add_callback('channel-change', self.focus_cb)

        self.gui_up = False
Example #45
0
    def __init__(self, fv):
        # superclass defines some variables for us, like logger
        super(ChangeHistory, self).__init__(fv)

        self.columns = [('Timestamp (UTC)', 'MODIFIED'),
                        ('Description', 'DESCRIP'),
                        ]
        # For table-of-contents pane
        self.name_dict = Bunch.caselessDict()
        self.treeview = None

        prefs = self.fv.get_preferences()
        self.settings = prefs.createCategory('plugin_ChangeHistory')
        self.settings.addDefaults(always_expand=True,
                                  color_alternate_rows=True,
                                  ts_colwidth=250)
        self.settings.load(onError='silent')

        fv.add_callback('remove-image', self.remove_image_cb)
        fv.add_callback('delete-channel', self.delete_channel_cb)

        self.gui_up = False
Example #46
0
 def clear(self):
     self.name_dict = Bunch.caselessDict()
     self._hl_path = set([])
     self.recreate_toc()
Example #47
0
#
# common.py -- common global functions for WCS calculations.
#
# This is open-source software licensed under a BSD license.
# Please see the file LICENSE.txt for details.
#
import re

import numpy as np

from ginga.misc import Bunch

# Holds custom WCSes that are registered
custom_wcs = Bunch.caselessDict()


class WCSError(Exception):
    pass


class BaseWCS(object):
    """Base class for WCS."""

    def __init__(self, logger):
        self.logger = logger
        # The header (or WCS parts thereof) that is in a format readable
        # by the WCS package used by the wrapper.
        self.header = None
        # Internal object holding the wrapped WCS object.  This should
        # be None if no valid WCS could be created by the WCS package.
        self.wcs = None
Example #48
0
 def clear(self):
     self.name_dict = Bunch.caselessDict()
     self.recreate_toc()
Example #49
0
 def clear(self):
     self.name_dict = Bunch.caselessDict()
     self.clear_selected_history()
     self.recreate_toc()
Example #50
0
    def redo(self, *args):
        """Generate listing of images that user can save."""
        if not self.gui_up:
            return

        mod_only = self.w.modified_only.get_state()
        treedict = Bunch.caselessDict()
        self.treeview.clear()
        self.w.status.set_text('')

        channel = self.fv.get_channelInfo(self.chname)
        if channel is None:
            return

        # Only list modified images for saving. Scanning Datasrc is enough.
        if mod_only:
            all_keys = channel.datasrc.keys(sort='alpha')

        # List all images in the channel.
        else:
            all_keys = channel.get_image_names()

        # Extract info for listing and saving
        for key in all_keys:
            iminfo = channel.get_image_info(key)
            path = iminfo.get('path')
            idx = iminfo.get('idx')
            t = iminfo.get('time_modified')

            if path is None:  # Special handling for generated buffer, eg mosaic
                infile = key
                is_fits = True
            else:
                infile = os.path.basename(path)
                infile_ext = os.path.splitext(path)[1]
                infile_ext = infile_ext.lower()
                is_fits = False

                if 'fit' in infile_ext:
                    is_fits = True

            # Only list FITS files unless it is Ginga generated buffer
            if not is_fits:
                continue

            # Only list modified buffers
            if mod_only and t is None:
                continue

            # More than one ext modified, append to existing entry
            if infile in treedict:
                if t is not None:
                    treedict[infile].extlist.add(idx)
                    elist = sorted(treedict[infile].extlist)
                    treedict[infile].MODEXT = ';'.join(
                        map(self._format_extname, elist))

            # Add new entry
            else:
                if t is None:
                    s = ''
                    extlist = set()
                else:
                    s = self._format_extname(idx)
                    extlist = set([idx])
                treedict[infile] = Bunch.Bunch(
                    IMAGE=infile, MODEXT=s, extlist=extlist, path=path)

        self.treeview.set_tree(treedict)

        # Resize column widths
        n_rows = len(treedict)
        if n_rows == 0:
            self.w.status.set_text('Nothing available for saving')
        elif n_rows < self.settings.get('max_rows_for_col_resize', 5000):
            self.treeview.set_optimal_column_widths()
            self.logger.debug('Resized columns for {0} row(s)'.format(n_rows))
Example #51
0
    def redo(self):
        """Image or coordinates have changed. Clear and redraw."""
        if not self.gui_up:
            return

        self.clear_marking()
        self.tree_dict = Bunch.caselessDict()
        self.treeviewbad.clear()
        bad_tree_dict = Bunch.caselessDict()
        nbad = 0
        self._xarr = []
        self._yarr = []
        self._treepaths = []

        image = self.fitsimage.get_image()
        if image is None:
            return

        if not hasattr(image, 'radectopix'):
            self.logger.error(
                'Image as no radectopix() method for coordinates conversion')
            return

        objlist = []
        seqno = 1
        max_x = image.width - 1
        max_y = image.height - 1

        for key, coords in self.coords_dict.items():
            if len(coords) == 0:
                continue

            marktype, marksize, markcolor = key
            kstr = ','.join(map(str, key))
            sub_dict = {}
            bad_sub_dict = {}
            self.tree_dict[kstr] = sub_dict
            bad_tree_dict[kstr] = bad_sub_dict

            for args in coords:
                ra, dec, x, y = args[:4]

                # Use X and Y positions directly. Convert to RA and DEC (deg).
                if ra is None or dec is None:
                    ra, dec = image.pixtoradec(x, y)

                # RA and DEC already in degrees. Convert to pixel X and Y.
                else:
                    x, y = image.radectopix(ra, dec)

                # Display original X/Y (can be 0- or 1-indexed) using
                # our internal 0-indexed values.
                xdisp = x + self.pixelstart
                ydisp = y + self.pixelstart

                seqstr = '{0:04d}'.format(seqno)  # Prepend 0s for proper sort
                bnch = Bunch.Bunch(zip(self.extra_columns, args[4:]))  # Extra
                bnch.update(Bunch.Bunch(MARKID=seqstr, RA=ra, DEC=dec,
                                        X=xdisp, Y=ydisp))

                # Do not draw out of bounds
                if (not np.isfinite(x) or x < 0 or x > max_x or
                        not np.isfinite(y) or y < 0 or y > max_y):
                    self.logger.debug('Ignoring RA={0}, DEC={1} '
                                      '(x={2}, y={3})'.format(ra, dec, x, y))
                    bad_sub_dict[seqstr] = bnch
                    nbad += 1

                # Display point
                else:
                    obj = self._get_markobj(
                        x, y, marktype, marksize, markcolor, self.markwidth)
                    objlist.append(obj)

                    sub_dict[seqstr] = bnch
                    self._xarr.append(x)
                    self._yarr.append(y)
                    self._treepaths.append((kstr, seqstr))

                seqno += 1

        n_obj = len(objlist)
        self.logger.debug('Displaying {0} markings'.format(n_obj))

        if nbad > 0:
            self.treeviewbad.set_tree(bad_tree_dict)

        if n_obj == 0:
            return

        # Convert to Numpy arrays to avoid looping later
        self._xarr = np.array(self._xarr)
        self._yarr = np.array(self._yarr)
        self._treepaths = np.array(self._treepaths)

        # Display info table
        self.recreate_toc()

        # Draw on canvas
        self.marktag = self.canvas.add(self.dc.CompoundObject(*objlist))
        self.fitsimage.redraw()  # Force immediate redraw