def get_move_scale_rotate_pts(self, viewer): """Returns 3 edit control points for editing this object: a move point, a scale point and a rotate point. These points are all in data coordinates. """ scale = viewer.get_scale_min() ref_x, ref_y = self.get_center_pt() xl, yl, xu, yu = self.get_llur() offset = 8.0 / scale scl_x, scl_y = xl - offset, yl - offset rot_x, rot_y = xu + offset, yu + offset if hasattr(self, 'rot_deg'): # if this is an object with a rotation attribute, pre rotate # the control points in the opposite direction, because they # will be rotated back theta = -self.rot_deg scl_x, scl_y = trcalc.rotate_pt(scl_x, scl_y, theta, xoff=ref_x, yoff=ref_y) rot_x, rot_y = trcalc.rotate_pt(rot_x, rot_y, theta, xoff=ref_x, yoff=ref_y) move_pt = MovePoint(ref_x, ref_y) scale_pt = ScalePoint(scl_x, scl_y) rotate_pt = RotatePoint(rot_x, rot_y) return (move_pt, scale_pt, rotate_pt)
def _rot_xlate(self, obj, data_x, data_y): # translate point back into non-rotated form rot_deg = - obj.rot_deg xoff, yoff = obj.get_center_pt() data_x, data_y = trcalc.rotate_pt(data_x, data_y, rot_deg, xoff=xoff, yoff=yoff) return data_x, data_y
def rotate_pt(self, x, y, theta, xoff=0, yoff=0): # TODO: rotate in WCS space? # rotate in data space xoff, yoff = self.to_data(xoff, yoff) data_x, data_y = self.to_data(x, y) rot_x, rot_y = trcalc.rotate_pt(data_x, data_y, theta, xoff=xoff, yoff=yoff) x, y = self.data_to(rot_x, rot_y) return x, y
def rotate_pt(self, pts, theta, offset): # TODO: rotate in WCS space? # rotate in data space data_off = self.to_data(offset) data_pts = self.to_data(pts) xoff, yoff = np.transpose(data_off) data_x, data_y = data_pts.T data_rot = trcalc.rotate_pt(data_x, data_y, theta, xoff=xoff, yoff=yoff) return self.data_to(data_rot.T)
def to_(self, off_x, off_y): t_ = self.viewer.t_ if t_['flip_x']: off_x = - off_x if t_['flip_y']: off_y = - off_y if t_['swap_xy']: off_x, off_y = off_y, off_x if t_['rot_deg'] != 0: off_x, off_y = trcalc.rotate_pt(off_x, off_y, t_['rot_deg']) return (off_x, off_y)
def to_(self, off_x, off_y): t_ = self.viewer.t_ if t_['flip_x']: off_x = -off_x if t_['flip_y']: off_y = -off_y if t_['swap_xy']: off_x, off_y = off_y, off_x if t_['rot_deg'] != 0: off_x, off_y = trcalc.rotate_pt(off_x, off_y, t_['rot_deg']) return (off_x, off_y)
def from_(self, off_x, off_y): """Reverse of :meth:`to_`.""" t_ = self.viewer.t_ if t_['rot_deg'] != 0: off_x, off_y = trcalc.rotate_pt(off_x, off_y, -t_['rot_deg']) if t_['swap_xy']: off_x, off_y = off_y, off_x if t_['flip_y']: off_y = -off_y if t_['flip_x']: off_x = -off_x return (off_x, off_y)
def from_(self, off_x, off_y): """Reverse of :meth:`to_`.""" t_ = self.viewer.t_ if t_['rot_deg'] != 0: off_x, off_y = trcalc.rotate_pt(off_x, off_y, -t_['rot_deg']) if t_['swap_xy']: off_x, off_y = off_y, off_x if t_['flip_y']: off_y = - off_y if t_['flip_x']: off_x = - off_x return (off_x, off_y)
def get_pt(self, viewer, points, x, y, canvas_radius=None): if canvas_radius is None: canvas_radius = self.cap_radius if hasattr(self, 'rot_deg'): # rotate point back to cartesian alignment for test ctr_x, ctr_y = self.get_center_pt() xp, yp = trcalc.rotate_pt(x, y, -self.rot_deg, xoff=ctr_x, yoff=ctr_y) else: xp, yp = x, y # TODO: do this using numpy array() for i in range(len(points)): a, b = points[i] if self.within_radius(viewer, xp, yp, a, b, canvas_radius): return i return None
def rotate_pt(self, x, y, theta, xoff=0, yoff=0): return trcalc.rotate_pt(x, y, theta, xoff=xoff, yoff=yoff)
def ob_to_ope(self, ob, out_f): out = self._mk_out(out_f) # special cases: filter change, long slew, calibrations, etc. if ob.derived != None: if ob.comment.startswith('Filter change'): #self.out_filterchange(ob, out_f) return elif ob.comment.startswith('Long slew'): out("\n# %s" % (ob.comment)) d = {} self._setup_target(d, ob) cmd_str = 'SetupField $DEF_IMAG %(tgtstr)s $MASK_NONE Shift_Sec=%(offset_sec)d Delta_Ra=%(offset_ra)d Delta_Dec=%(offset_dec)d' % d cmd_str = cmd_str + (' AUTOGUIDE=%(autoguide)s' % d) out(cmd_str) return elif ob.comment.startswith('Delay for'): out("\n# %s" % (ob.comment)) d = dict(sleep_time=int(ob.total_time)) cmd_str = 'EXEC OBS TIMER SLEEP_TIME=%(sleep_time)d' % d out(cmd_str) return tgtname = ob.target.name.lower() if tgtname == 'domeflat': out("\n# %s" % (ob.comment)) d = {} self._setup_target(d, ob) cmd_str = 'GetDomeflat $DEF_IMAG $DEF_DOMEFLAT $MASK_NONE $FILTER_%(filter)s $CCD_%(binning)s ExpTime=7 VOLT=20' % d for i in xrange(ob.inscfg.num_exp): out(cmd_str) return elif tgtname == 'bias': out("\n# %s" % (ob.comment)) d = {} self._setup_target(d, ob) cmd_str = 'GetBias $DEF_IMAG $CCD_%(binning)s OBJECT=BIAS' % d for i in xrange(ob.inscfg.num_exp): out(cmd_str) return # <-- normal OBs out = self._mk_out(out_f) out("\n# %s (%s %s) %s: %s" % (ob, ob.program.proposal, ob.program.pi, ob.name, ob.target.name)) d = {} self._setup_target(d, ob) cmd_str = 'SetupField $DEF_IMAG %(tgtstr)s $MASK_NONE Shift_Sec=%(offset_sec)d Delta_Ra=%(offset_ra)d Delta_Dec=%(offset_dec)d' % d if ob.inscfg.guiding: dith_cmd = "MoveGuide0" cmd_str = cmd_str + (' AUTOGUIDE=%(autoguide)s' % d) else: dith_cmd = "MoveTelescope" cmd_str = cmd_str + (' AUTOGUIDE=%(autoguide)s' % d) # output setupfield command to position telescope out(cmd_str) d_ra, d_dec = d['dither_ra'], d['dither_dec'] d_theta = d['dither_theta'] abs_off = ((0, 0), (d_ra, d_dec), (-d_dec, d_ra), (-d_ra, -d_dec), (d_dec, -d_ra), (0, 0)) # rotate box points according to dither theta abs_off = map(lambda p: trcalc.rotate_pt(p[0], p[1], d_theta), abs_off) # 5 dither sequence d['mask'] = 'NONE' if ob.inscfg.num_exp == 1: cmd_str = 'GetObject $DEF_IMAG $MASK_%(mask)s %(tgtstr)s $CCD_%(binning)s EXPTIME=%(exptime)d' % d out(cmd_str) else: for i in xrange(5): out("# Dither point %d" % (i+1)) cmd_str = 'GetObject $DEF_IMAG $MASK_%(mask)s %(tgtstr)s $CCD_%(binning)s EXPTIME=%(exptime)d' % d out(cmd_str) # calculate deltas for positioning at next dither pos cur_off_ra, cur_off_dec = abs_off[i] #print("current off ra, dec=%.3f,%.3f" % (cur_off_ra, cur_off_dec)) next_off_ra, next_off_dec = abs_off[i+1] #print("next off ra, dec=%.3f,%.3f" % (next_off_ra, next_off_dec)) delta_ra = next_off_ra - cur_off_ra delta_dec = next_off_dec - cur_off_dec # issue command for offsetting to next dither pos cmd_str = '%s $DEF_TOOL Delta_RA=%.3f Delta_DEC=%.3f' % ( dith_cmd, delta_ra, delta_dec) out(cmd_str) d['mask'] = 'NOP'
def rotate_pt(self, pts, theta, offset): x, y = np.asarray(pts).T xoff, yoff = np.transpose(offset) rot_x, rot_y = trcalc.rotate_pt(x, y, theta, xoff=xoff, yoff=yoff) return np.asarray((rot_x, rot_y)).T
def ob_to_ope(self, ob, out_f): out = self._mk_out(out_f) # special cases: filter change, long slew, calibrations, etc. if ob.derived != None: if ob.comment.startswith('Filter change'): #self.out_filterchange(ob, out_f) return elif ob.comment.startswith('Long slew'): out("\n# %s" % (ob.comment)) d = {} self._setup_target(d, ob) cmd_str = 'SetupField $DEF_IMAG %(tgtstr)s $MASK_NONE Shift_Sec=%(offset_sec)d Delta_Ra=%(offset_ra)d Delta_Dec=%(offset_dec)d' % d cmd_str = cmd_str + (' AUTOGUIDE=%(autoguide)s' % d) out(cmd_str) return elif ob.comment.startswith('Delay for'): out("\n# %s" % (ob.comment)) d = dict(sleep_time=int(ob.total_time)) cmd_str = 'EXEC OBS TIMER SLEEP_TIME=%(sleep_time)d' % d out(cmd_str) return tgtname = ob.target.name.lower() if tgtname == 'domeflat': out("\n# %s" % (ob.comment)) d = {} self._setup_target(d, ob) cmd_str = 'GetDomeflat $DEF_IMAG $DEF_DOMEFLAT $MASK_NONE $FILTER_%(filter)s $CCD_%(binning)s ExpTime=7 VOLT=20' % d for i in range(ob.inscfg.num_exp): out(cmd_str) return elif tgtname == 'bias': out("\n# %s" % (ob.comment)) d = {} self._setup_target(d, ob) cmd_str = 'GetBias $DEF_IMAG $CCD_%(binning)s OBJECT=BIAS' % d for i in range(ob.inscfg.num_exp): out(cmd_str) return # <-- normal OBs out = self._mk_out(out_f) out("\n# %s (%s %s) %s: %s" % (ob, ob.program.proposal, ob.program.pi, ob.name, ob.target.name)) d = {} self._setup_target(d, ob) cmd_str = 'SetupField $DEF_IMAG %(tgtstr)s $MASK_NONE Shift_Sec=%(offset_sec)d Delta_Ra=%(offset_ra)d Delta_Dec=%(offset_dec)d' % d if ob.inscfg.guiding: dith_cmd = "MoveGuide0" cmd_str = cmd_str + (' AUTOGUIDE=%(autoguide)s' % d) else: dith_cmd = "MoveTelescope" cmd_str = cmd_str + (' AUTOGUIDE=%(autoguide)s' % d) # output setupfield command to position telescope out(cmd_str) d_ra, d_dec = d['dither_ra'], d['dither_dec'] d_theta = d['dither_theta'] abs_off = ((0, 0), (d_ra, d_dec), (-d_dec, d_ra), (-d_ra, -d_dec), (d_dec, -d_ra), (0, 0)) # rotate box points according to dither theta abs_off = map(lambda p: trcalc.rotate_pt(p[0], p[1], d_theta), abs_off) # 5 dither sequence d['mask'] = 'NONE' if ob.inscfg.num_exp == 1: cmd_str = 'GetObject $DEF_IMAG $MASK_%(mask)s %(tgtstr)s $CCD_%(binning)s EXPTIME=%(exptime)d' % d out(cmd_str) else: for i in range(5): out("# Dither point %d" % (i+1)) cmd_str = 'GetObject $DEF_IMAG $MASK_%(mask)s %(tgtstr)s $CCD_%(binning)s EXPTIME=%(exptime)d' % d out(cmd_str) # calculate deltas for positioning at next dither pos cur_off_ra, cur_off_dec = abs_off[i] #print("current off ra, dec=%.3f,%.3f" % (cur_off_ra, cur_off_dec)) next_off_ra, next_off_dec = abs_off[i+1] #print("next off ra, dec=%.3f,%.3f" % (next_off_ra, next_off_dec)) delta_ra = next_off_ra - cur_off_ra delta_dec = next_off_dec - cur_off_dec # issue command for offsetting to next dither pos cmd_str = '%s $DEF_TOOL Delta_RA=%.3f Delta_DEC=%.3f' % ( dith_cmd, delta_ra, delta_dec) out(cmd_str) d['mask'] = 'NOP'