def setpickregion(self, canvas, tag): obj = canvas.getObjectByTag(tag) if obj.kind != 'rectangle': return True canvas.deleteObjectByTag(tag, redraw=False) if self.picktag: try: canvas.deleteObjectByTag(self.picktag, redraw=False) except: pass # determine center of rectangle x = obj.x1 + (obj.x2 - obj.x1) // 2 y = obj.y1 + (obj.y2 - obj.y1) // 2 tag = canvas.add(CanvasTypes.CompoundObject( CanvasTypes.Rectangle(obj.x1, obj.y1, obj.x2, obj.y2, color=self.pickcolor), CanvasTypes.Point(x, y, 10, color='red'), CanvasTypes.Text(obj.x1, obj.y2 + 4, "Pick: calc", color=self.pickcolor)), redraw=False) self.picktag = tag #self.fv.raise_tab("detail") return self.redo()
def plot_star(self, obj, image=None): if not image: image = self.fitsimage.get_image() x, y = image.radectopix(obj['ra_deg'], obj['dec_deg']) #print "STAR at %d,%d" % (x, y) # TODO: auto-pick a decent radius radius = 10 color = self.table.get_color(obj) #print "color is %s" % str(color) circle = CanvasTypes.Circle(x, y, radius, color=color) point = CanvasTypes.Point(x, y, radius, color=color) ## What is this from? if obj.has_key('pick'): # Some objects returned from the Gen2 star catalog are marked # with the attribute 'pick'. If present then we show the # star with or without the cross, otherwise we always show the # cross if not obj['pick']: star = CanvasTypes.Canvas(circle, point) else: star = CanvasTypes.Canvas(circle) else: star = CanvasTypes.Canvas(circle, point) star.set_data(star=obj) obj.canvobj = star self.canvas.add(star, tagpfx='star', redraw=False)
def panset(self, fitsimage, chinfo, paninfo): x, y = fitsimage.get_pan() points = fitsimage.get_pan_rect() # calculate pan position point radius image = paninfo.panimage.get_image() width, height = image.get_size() edgew = math.sqrt(width**2 + height**2) radius = int(0.015 * edgew) # Mark pan rectangle and pan position try: obj = paninfo.panimage.getObjectByTag(paninfo.panrect) if obj.kind != 'compound': return True point, bbox = obj.objects self.logger.debug("starting panset") point.x, point.y = x, y point.radius = radius bbox.points = points paninfo.panimage.redraw(whence=3) except KeyError: paninfo.panrect = paninfo.panimage.add(CanvasTypes.CompoundObject( CanvasTypes.Point(x, y, radius=radius), CanvasTypes.Polygon(points)))
def add_mark(self, data_x, data_y, radius=None, color=None, style=None): if not radius: radius = self.mark_radius if not color: color = self.mark_color if not style: style = self.mark_style self.logger.debug("Setting mark at %d,%d" % (data_x, data_y)) self.mark_index += 1 tag = 'mark%d' % (self.mark_index) tag = self.canvas.add(CanvasTypes.CompoundObject( CanvasTypes.Point(data_x, data_y, self.mark_radius, style=style, color=color, linestyle='solid'), CanvasTypes.Text(data_x + 10, data_y, "%d" % (self.mark_index), color=color)), tag=tag) self.marks.append(tag) self.w.marks.append_text(tag) self.select_mark(tag, pan=False)
def setfromimage(self): x1, y1 = 0, 0 x2, y2 = self.fitsimage.get_data_size() tag = self.canvas.add( CanvasTypes.Rectangle(x1, y1, x2, y2, color=self.mycolor)) self.getarea(self.canvas, tag)
def __init__(self, fv, fitsimage): # superclass defines some variables for us, like logger super(PixTable, self).__init__(fv, fitsimage) #fitsimage.set_callback('motion', self.motion) self.layertag = 'pixtable-canvas' self.pan2mark = False canvas = CanvasTypes.DrawingCanvas() ## canvas.enable_draw(True) ## canvas.set_drawtype('point', color='pink') ## canvas.set_callback('draw-event', self.draw_cb) canvas.set_callback('button-press', self.btndown) canvas.set_callback('motion', self.motion) canvas.setSurface(self.fitsimage) self.canvas = canvas self.w.tooltips = self.fv.w.tooltips # For pixel table self.pixtbl_radius = 2 self.sizes = [1, 2, 3, 4] self.lastx = 0 self.lasty = 0 # For "marks" feature self.mark_radius = 10 self.mark_style = 'cross' self.mark_color = 'purple' self.select_color = 'cyan' self.marks = ['None'] self.mark_index = 0 self.mark_selected = None
def highlight_object(self, obj, tag, color, redraw=True): x = obj.objects[0].x y = obj.objects[0].y delta = 10 radius = obj.objects[0].radius + delta hilite = CanvasTypes.Circle(x, y, radius, linewidth=4, color=color) obj.add(hilite, tag=tag, redraw=redraw)
def __init__(self, fv, fitsimage): # superclass defines some variables for us, like logger super(Pick, self).__init__(fv, fitsimage) self.layertag = 'pick-canvas' self.pickimage = None self.pickcenter = None self.pick_qs = None self.picktag = None self.pickcolor = 'green' self.candidate_color = 'purple' self.pick_x1 = 0 self.pick_y1 = 0 self.pick_data = None self.dx = region_default_width self.dy = region_default_height # For offloading intensive calculation from graphics thread self.serialnum = 0 self.lock = threading.RLock() self.lock2 = threading.RLock() self.ev_intr = threading.Event() # Peak finding parameters and selection criteria # this is the maximum size a side can be self.max_side = 1024 self.radius = 10 self.threshold = None self.min_fwhm = 2.0 self.max_fwhm = 50.0 self.min_ellipse = 0.5 self.edgew = 0.01 self.show_candidates = False self.plot_panx = 0.5 self.plot_pany = 0.5 self.plot_zoomlevel = 1.0 self.num_contours = 8 self.contour_size_limit = 70 self.contour_data = None self.delta_sky = 0.0 self.delta_bright = 0.0 self.iqcalc = iqcalc.IQCalc(self.logger) canvas = CanvasTypes.DrawingCanvas() canvas.enable_draw(True) canvas.set_callback('button-press', self.btndown) canvas.set_callback('motion', self.drag) canvas.set_callback('button-release', self.update) canvas.set_drawtype('rectangle', color='cyan', linestyle='dash', drawdims=True) canvas.set_callback('draw-event', self.setpickregion) canvas.setSurface(self.fitsimage) self.canvas = canvas self.w.tooltips = self.fv.w.tooltips
def draw_cb(self, canvas, tag): obj = canvas.getObjectByTag(tag) if obj.kind != 'rectangle': return True canvas.deleteObjectByTag(tag, redraw=False) if self.histtag: try: canvas.deleteObjectByTag(self.histtag, redraw=False) except: pass tag = canvas.add(CanvasTypes.CompoundObject( CanvasTypes.Rectangle(obj.x1, obj.y1, obj.x2, obj.y2, color=self.histcolor), CanvasTypes.Text(obj.x1, obj.y2+4, "Histogram", color=self.histcolor))) self.histtag = tag return self.redo()
def draw_cb(self, canvas, tag): obj = canvas.getObjectByTag(tag) if obj.kind != 'line': return True canvas.deleteObjectByTag(tag, redraw=False) # calculate center of line wd = obj.x2 - obj.x1 dw = wd // 2 ht = obj.y2 - obj.y1 dh = ht // 2 x, y = obj.x1 + dw + 4, obj.y1 + dh + 4 if self.cutstag: # Replacing a cut print "replacing cut position" cutobj = canvas.getObjectByTag(self.cutstag) line = cutobj.objects[0] line.x1, line.y1, line.x2, line.y2 = obj.x1, obj.y1, obj.x2, obj.y2 text = cutobj.objects[1] text.x, text.y = x, y else: # Adding new cut print "adding cut position" self.count += 1 tag = "cuts%d" % (self.count) canvas.add(CanvasTypes.CompoundObject( CanvasTypes.Line(obj.x1, obj.y1, obj.x2, obj.y2, color='cyan', cap='ball'), CanvasTypes.Text(x, y, "cuts%d" % self.count, color='cyan')), tag=tag) self.addCutsTag(tag, select=True) print "redoing cut plots" return self.redo()
def full_image(self): canvas = self.canvas try: canvas.deleteObjectByTag(self.histtag, redraw=False) except: pass image = self.fitsimage.get_image() width, height = image.get_size() x1, y1, x2, y2 = 0, 0, width-1, height-1 tag = canvas.add(CanvasTypes.Rectangle(x1, y1, x2, y2, color='cyan', linestyle='dash')) self.draw_cb(canvas, tag)
def __init__(self, fv, fitsimage): # superclass defines some variables for us, like logger super(Drawing, self).__init__(fv, fitsimage) self.layertag = 'drawing-canvas' canvas = CanvasTypes.DrawingCanvas() canvas.enable_draw(True) canvas.set_drawtype('point', color='cyan') canvas.set_callback('draw-event', self.draw_cb) canvas.setSurface(self.fitsimage) self.canvas = canvas self.w = None self.drawtypes = canvas.get_drawtypes() self.drawcolors = draw_colors
def build_gui(self, container): canvas = CanvasTypes.DrawingCanvas() canvas.enable_draw(False) #canvas.set_callback('button-press', self.btndown) canvas.set_callback('motion', self.cursormotion) #canvas.set_callback('button-release', self.update) canvas.add_callback('key-press', self.window_key_press) canvas.add_callback('key-release', self.window_key_release) self.canvas = canvas vbox1 = gtk.VBox() fr = gtk.Frame("IRAF") fr.set_shadow_type(gtk.SHADOW_ETCHED_IN) fr.set_label_align(0.5, 0.5) captions = [ ("Control", 'hbox'), ("Channel", 'label'), ] w, b = GtkHelp.build_info(captions) fr.add(w) self.w = b self.w.mode_d = {} btn = GtkHelp.RadioButton(group=None, label="Ginga") btn.sconnect('toggled', lambda w: self.switchMode('ginga')) self.w.mode_d['ginga'] = btn self.w.control.pack_start(btn, padding=4, fill=False, expand=False) btn = GtkHelp.RadioButton(group=btn, label="IRAF") btn.sconnect('toggled', lambda w: self.switchMode('iraf')) self.w.mode_d['iraf'] = btn self.w.control.pack_start(btn, padding=4, fill=False, expand=False) vbox1.pack_start(fr, padding=4, fill=True, expand=False) fr = gtk.Frame("Frame/Channel") fr.set_shadow_type(gtk.SHADOW_ETCHED_IN) fr.set_label_align(0.5, 0.5) lbl = gtk.Label("") self.w.frch = lbl fr.add(lbl) vbox1.pack_start(fr, padding=4, fill=True, expand=False) vbox1.show_all() container.pack_start(vbox1, padding=0, fill=True, expand=False)
def drag(self, canvas, button, data_x, data_y): if not (button == 0x1): return obj = self.canvas.getObjectByTag(self.picktag) if obj.kind == 'compound': bbox = obj.objects[0] elif obj.kind == 'rectangle': bbox = obj else: return True # calculate center of bbox wd = bbox.x2 - bbox.x1 dw = wd // 2 ht = bbox.y2 - bbox.y1 dh = ht // 2 x, y = bbox.x1 + dw, bbox.y1 + dh # calculate offsets of move dx = (data_x - x) dy = (data_y - y) # calculate new coords x1, y1, x2, y2 = bbox.x1 + dx, bbox.y1 + dy, bbox.x2 + dx, bbox.y2 + dy if (not obj) or (obj.kind == 'compound'): # Replace compound image with rectangle try: self.canvas.deleteObjectByTag(self.picktag, redraw=False) except: pass self.picktag = self.canvas.add( CanvasTypes.Rectangle(x1, y1, x2, y2, color='cyan', linestyle='dash')) else: # Update current rectangle with new coords and redraw bbox.x1, bbox.y1, bbox.x2, bbox.y2 = x1, y1, x2, y2 self.canvas.redraw(whence=3)
def __init__(self, fv, fitsimage): # superclass defines some variables for us, like logger super(Ruler, self).__init__(fv, fitsimage) self.rulecolor = 'green' self.layertag = 'ruler-canvas' self.ruletag = None canvas = CanvasTypes.DrawingCanvas() canvas.enable_draw(True) canvas.set_drawtype('ruler', color='cyan') canvas.set_callback('draw-event', self.wcsruler) canvas.set_callback('button-press', self.clear) canvas.setSurface(self.fitsimage) self.canvas = canvas self.w = None self.unittypes = ('arcmin', 'pixels') self.units = 'arcmin'
def set_image(self, chinfo, paninfo, image): paninfo.panimage.set_image(image) # remove old compass try: paninfo.panimage.deleteObjectByTag(paninfo.pancompass, redraw=False) except Exception: pass # create compass try: (x, y, xn, yn, xe, ye) = image.calc_compass_center() self.logger.debug("x=%d y=%d xn=%d yn=%d xe=%d ye=%d" % ( x, y, xn, yn, xe, ye)) paninfo.pancompass = paninfo.panimage.add(CanvasTypes.Compass( x, y, xn, yn, xe, ye, color='skyblue', fontsize=14), redraw=True) except Exception, e: self.logger.warn("Can't calculate compass: %s" % ( str(e)))
def __init__(self, fv, fitsimage): super(Catalogs, self).__init__(fv, fitsimage) self.mycolor = 'skyblue' self.color_cursor = 'red' self.limit_stars_to_area = False self.use_dss_channel = False self.plot_max = 500 self.plot_limit = 100 self.plot_start = 0 # star list self.starlist = [] # catalog listing self.table = None canvas = CanvasTypes.DrawingCanvas() canvas.enable_draw(True) canvas.set_drawtype('rectangle', color='cyan', linestyle='dash', drawdims=True) canvas.set_callback('button-release', self.btnup) canvas.set_callback('draw-event', self.getarea) canvas.setSurface(self.fitsimage) self.canvas = canvas self.layertag = 'catalog-canvas' self.areatag = None self.curstar = None self.image_server_options = [] self.image_server_params = None self.catalog_server_options = [] self.catalog_server_params = None self.tooltips = self.fv.w.tooltips
def __init__(self, fv, fitsimage): # superclass defines some variables for us, like logger super(Histogram, self).__init__(fv, fitsimage) self.layertag = 'histogram-canvas' self.histtag = None self.histcolor = 'aquamarine' canvas = CanvasTypes.DrawingCanvas() canvas.enable_draw(True) canvas.set_drawtype('rectangle', color='cyan', linestyle='dash', drawdims=True) canvas.set_callback('draw-event', self.draw_cb) canvas.set_callback('button-press', self.drag) canvas.set_callback('motion', self.drag) canvas.set_callback('button-release', self.update) canvas.setSurface(self.fitsimage) self.canvas = canvas self.w.tooltips = self.fv.w.tooltips self.gui_up = False fitsimage.set_callback('cut-set', self.cutset_ext_cb)
def __init__(self, fv, fitsimage): # superclass defines some variables for us, like logger super(Cuts, self).__init__(fv, fitsimage) self.cutscolor = 'green' self.layertag = 'cuts-canvas' self.cutstag = None self.tags = ['None'] self.count = 0 self.colors = ['green', 'red', 'blue', 'cyan', 'pink', 'magenta'] #self.move_together = True canvas = CanvasTypes.DrawingCanvas() canvas.enable_draw(True) canvas.set_drawtype('line', color='cyan', linestyle='dash') canvas.set_callback('draw-event', self.draw_cb) canvas.set_callback('button-press', self.buttondown_cb) canvas.set_callback('motion', self.motion_cb) canvas.set_callback('button-release', self.buttonup_cb) canvas.set_callback('key-press', self.keydown) canvas.setSurface(self.fitsimage) self.canvas = canvas self.w.tooltips = self.fv.w.tooltips
def update(self, canvas, button, data_x, data_y): if not (button == 0x1): return obj = self.canvas.getObjectByTag(self.histtag) if obj.kind == 'compound': bbox = obj.objects[0] elif obj.kind == 'rectangle': bbox = obj else: return True # calculate center of bbox wd = bbox.x2 - bbox.x1 dw = wd // 2 ht = bbox.y2 - bbox.y1 dh = ht // 2 x, y = bbox.x1 + dw, bbox.y1 + dh # calculate offsets of move dx = (data_x - x) dy = (data_y - y) # calculate new coords x1, y1, x2, y2 = bbox.x1+dx, bbox.y1+dy, bbox.x2+dx, bbox.y2+dy try: canvas.deleteObjectByTag(self.histtag, redraw=False) except: pass tag = canvas.add(CanvasTypes.Rectangle(x1, y1, x2, y2, color='cyan', linestyle='dash')) self.draw_cb(canvas, tag)
dx = self.dx dy = self.dy # Mark center of object and region on main image try: self.canvas.deleteObjectByTag(self.picktag, redraw=False) except: pass x1, y1 = data_x - dx, data_y - dy x2, y2 = data_x + dx, data_y + dy tag = self.canvas.add( CanvasTypes.Rectangle(x1, y1, x2, y2, color='cyan', linestyle='dash')) self.picktag = tag #self.setpickregion(self.canvas, tag) def update(self, canvas, button, data_x, data_y): if not (button == 0x1): return try: obj = self.canvas.getObjectByTag(self.picktag) if obj.kind == 'rectangle': bbox = obj else:
def redo(self): serialnum = self.bump_serial() self.ev_intr.set() fig = self.canvas.getObjectByTag(self.picktag) if fig.kind != 'compound': return True bbox = fig.objects[0] point = fig.objects[1] text = fig.objects[2] data_x, data_y = point.x, point.y #self.fitsimage.panset_xy(data_x, data_y, redraw=False) # set the pick image to have the same cut levels and transforms self.fitsimage.copy_attributes(self.pickimage, ['transforms', 'cutlevels', 'rgbmap'], redraw=False) try: image = self.fitsimage.get_image() # sanity check on region width = bbox.x2 - bbox.x1 height = bbox.y2 - bbox.y1 if (width > self.max_side) or (height > self.max_side): errmsg = "Image area (%dx%d) too large!" % (width, height) self.fv.show_error(errmsg) raise Exception(errmsg) # Note: FITS coordinates are 1-based, whereas numpy FITS arrays # are 0-based fits_x, fits_y = data_x + 1, data_y + 1 # Cut and show pick image in pick window #self.pick_x, self.pick_y = data_x, data_y self.logger.debug("bbox %f,%f %f,%f" % (bbox.x1, bbox.y1, bbox.x2, bbox.y2)) x1, y1, x2, y2, data = self.cutdetail(self.fitsimage, self.pickimage, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2)) self.logger.debug("cut box %f,%f %f,%f" % (x1, y1, x2, y2)) # calculate center of pick image wd, ht = self.pickimage.get_data_size() xc = wd // 2 yc = ht // 2 if not self.pickcenter: tag = self.pickimage.add( CanvasTypes.Point(xc, yc, 5, linewidth=1, color='red')) self.pickcenter = self.pickimage.getObjectByTag(tag) self.pick_x1, self.pick_y1 = x1, y1 self.pick_data = data self.wdetail.sample_area.set_text('%dx%d' % (x2 - x1, y2 - y1)) point.color = 'red' text.text = 'Pick: calc' self.pickcenter.x = xc self.pickcenter.y = yc self.pickcenter.color = 'red' # clear contour and fwhm plots if have_mpl: self.clear_contours() self.clear_fwhm() # Delete previous peak marks objs = self.fitsimage.getObjectsByTagpfx('peak') self.fitsimage.deleteObjects(objs, redraw=True) # Offload this task to another thread so that GUI remains # responsive self.fv.nongui_do(self.search, serialnum, data, x1, y1, wd, ht, fig) except Exception, e: self.logger.error("Error calculating quality metrics: %s" % (str(e))) return True
def update_pick(self, serialnum, objlist, qs, x1, y1, wd, ht, fig, msg): if serialnum != self.get_serial(): return try: image = self.fitsimage.get_image() point = fig.objects[1] text = fig.objects[2] text.text = "Pick" if msg != None: raise Exception(msg) # Mark new peaks, if desired if self.show_candidates: for obj in objlist: tag = self.fitsimage.add(CanvasTypes.Point( x1 + obj.objx, y1 + obj.objy, 5, linewidth=1, color=self.candidate_color), tagpfx='peak', redraw=False) # Add back in offsets into image to get correct values with respect # to the entire image qs.x += x1 qs.y += y1 qs.objx += x1 qs.objy += y1 # Calculate X/Y of center of star obj_x = qs.objx obj_y = qs.objy self.logger.info("object center is x,y=%f,%f" % (obj_x, obj_y)) fwhm = qs.fwhm fwhm_x, fwhm_y = qs.fwhm_x, qs.fwhm_y point.x, point.y = obj_x, obj_y text.color = 'cyan' self.wdetail.fwhm_x.set_text('%.3f' % fwhm_x) self.wdetail.fwhm_y.set_text('%.3f' % fwhm_y) self.wdetail.fwhm.set_text('%.3f' % fwhm) self.wdetail.object_x.set_text('%.3f' % (obj_x + 1)) self.wdetail.object_y.set_text('%.3f' % (obj_y + 1)) self.wdetail.sky_level.set_text('%.3f' % qs.skylevel) self.wdetail.background.set_text('%.3f' % qs.background) self.wdetail.brightness.set_text('%.3f' % qs.brightness) self.w.btn_sky_cut.set_sensitive(True) self.w.btn_bright_cut.set_sensitive(True) # Mark center of object on pick image i1 = point.x - x1 j1 = point.y - y1 self.pickcenter.x = i1 self.pickcenter.y = j1 self.pickcenter.color = 'cyan' self.pick_qs = qs self.pickimage.panset_xy(i1, j1, redraw=False) # Mark object center on image point.color = 'cyan' self.fitsimage.panset_xy(obj_x, obj_y, redraw=False) # Calc RA, DEC, EQUINOX of X/Y center pixel try: ra_txt, dec_txt = image.pixtoradec(obj_x, obj_y, format='str') except Exception, e: ra_txt = 'WCS ERROR' dec_txt = 'WCS ERROR' self.wdetail.ra.set_text(ra_txt) self.wdetail.dec.set_text(dec_txt) equinox = image.get_keyword('EQUINOX', 'UNKNOWN') self.wdetail.equinox.set_text(str(equinox)) # TODO: Get separate FWHM for X and Y try: cdelt1, cdelt2 = image.get_keywords_list('CDELT1', 'CDELT2') starsize = self.iqcalc.starsize(fwhm_x, cdelt1, fwhm_y, cdelt2) self.wdetail.star_size.set_text('%.3f' % starsize) except Exception, e: self.wdetail.star_size.set_text('ERROR') self.fv.show_error("Couldn't calculate star size: %s" % (str(e)), raisetab=False)