def worldAt(self, *pixel): if not self._findWCS(): return Position.fromRaDec(0, 0) world = self._valueAt(self._wcs.wcs_pix2world, *pixel) return Position.fromRaDec(Coord.fromD(world[0]), Coord.fromD(world[1]))
def syncWithTel(self): self.syncBegin() self.log.debug('[sync] Check if dome is in sync with telescope') if self.getMode() == Mode.Track: self.log.warning('Dome is in track mode... Slew is completely controled by AsTelOS...' 'Waiting for dome to reach expected position') start_time = time.time() tpl = self.getTPL() ref_altitude = Coord.fromD(0.) target_az = Coord.fromD(tpl.getobject('POSITION.INSTRUMENTAL.DOME[0].TARGETPOS')) target_position = Position.fromAltAz(ref_altitude, target_az) while True: current_az = self.getAz() current_position = Position.fromAltAz(ref_altitude, current_az) self.log.debug('Current az: %s | Target az: %s' % (current_az.toDMS(), target_az.toDMS())) if time.time() > (start_time + self._maxSlewTime): if abs(target_position.angsep(current_position).D) < tpl.getobject( 'POINTING.SETUP.DOME.MAX_DEVIATION') * 4.0: self.log.warning("[sync] Dome too far from target position!") break else: self.syncComplete() raise AstelcoDomeException("Dome synchronization timed-out") elif abs(target_position.angsep(current_position).D) < tpl.getobject( 'POINTING.SETUP.DOME.MAX_DEVIATION') * 2.0: break self.syncComplete() self.log.debug('[sync] Dome in sync')
def _moveScope(self, tracking=False, pierSide=None): """ Moves the scope, usually to zenith """ tel = self._getTel() site = self._getSite() self.log.debug('Moving scope to alt %s az %s.' % (self["flat_alt"], self["flat_az"])) if tel.getPositionAltAz().angsep( Position.fromAltAz(Coord.fromD(self["flat_alt"]), Coord.fromD(self["flat_az"]))).D < self[ "flat_position_max"]: self.log.debug( 'Telescope is less than {} degrees from flat position. Not moving!'.format(self["flat_position_max"])) if tracking and not tel.isTracking(): tel.startTracking() elif not tracking and tel.isTracking(): tel.stopTracking() if pierSide is not None and tel.features(TelescopePier): self.log.debug("Setting telescope pier side to %s." % tel.getPierSide().__str__().lower()) tel.setSideOfPier(self['pier_side']) return try: self.log.debug("Skyflat Slewing scope to alt {} az {}".format(self["flat_alt"], self["flat_az"])) tel.slewToRaDec(Position.altAzToRaDec(Position.fromAltAz(Coord.fromD(self["flat_alt"]), Coord.fromD(self["flat_az"])), site['latitude'], site.LST())) if tracking: self._startTracking() else: self._stopTracking() except: self.log.debug("Error moving the telescope")
def test_distances(self): p1 = Position.fromRaDec("10:00:00", "0:0:0") p2 = Position.fromRaDec("12:00:00", "0:0:0") d = p1.angsep(p2) assert p1.within(p2, Coord.fromD(29.99)) == False assert p1.within(p2, Coord.fromD(30.01)) == True
def extinctionCoefficient(self,dbase,ra1,dec1,error,startTime1,endTime1,latitude1,outfile): outname = outfile self.ra = Coord.fromD(ra1) self.dec = Coord.fromD(dec1) self.error = error self.starttime = startTime1 self.endtime = endTime1 self.latitude = Coord.fromHMS(latitude1) self.outname = outfile self.doDatabaseModeEC(dbase)
def __init__(self): self.db = 0 self.ra = Coord.fromD(0) self.dec = Coord.fromD(0) self.error = 0 self.starttime = '' self.endtime = '' self.latitude = Coord.fromD(0) self.outname = "" self.path = "" self.seeing = Seeing()
def chimera_handler(self, payload, root): t0 = time.time() # Check if it is a real GRB ra, dec = float( root.find( "./WhereWhen/ObsDataLocation/ObservationLocation/AstroCoords/Position2D/Value2/C1" ).text ), float( root.find( "./WhereWhen/ObsDataLocation/ObservationLocation/AstroCoords/Position2D/Value2/C2" ).text) packet_type = int( root.find("./What/Param[@name='Packet_Type']").attrib['value']) site = self.getSite() ephem_site = site.getEphemSite(site.ut()) grb = ephem.FixedBody() grb._ra, grb._dec = ra, dec grb.compute(ephem_site) # Conditions to pull the observation trigger # TODO: implement min_moon_distance -> Position(coord.fromD(grb.alt), coord.fromD(grb.az)) - site.moonpos() # In[8]: a = Position.fromAltAz(Coord.fromD(10), Coord.fromD(10)) # # In[9]: b = Position.fromAltAz(Coord.fromD(10), Coord.fromD(20)) # # In[11]: a.angsep(b).D # Out[11]: 10.0 moondist = Position.fromAltAz(Coord.fromD(float(grb.alt)), Coord.fromD(float(grb.az))).angsep( site.moonpos()) if moondist > self['obs-min_moondist']: self.log.debug("Moon is OK! Moon distance = %.2f deg" % moondist) else: self.log.debug("Moon is NOT OK! Moon distance = %.2f deg" % moondist) # TODO: check if Test_Notice != True (for INTEGRAL) if grb.alt >= self['obs-min_alt'] and packet_type in range( 1000): # self['obs-packets']: gal_coord = ephem.Galactic(grb) ebv = get_SFD_dust([gal_coord.long], [gal_coord.lat], dustmap=self.dust_file, interpolate=False) if ebv < self['obs-ebv_max']: self.log.debug('Total analysis time: %6.3f secs' % (time.time() - t0)) self.trigger_observation(ra, dec) else: self.log.debug( "Reject alert type %i. ALT = %.2f, RA = %.2f DEC = %.2f. Config: %d, %s" % (packet_type, grb.alt, ra, dec, self['obs-min_alt'], str(self['obs-packets'])))
def test_parsing_conversion_hipparcos(self): """Parsing and comparing a subset of the Hipparcos and Tycho Catalog""" hipp = ascii.read(os.path.abspath( os.path.join(os.path.dirname(__file__), 'hipparcos-tycho.dat')), format="tab") expected_ra = [] expected_ra_str = [] expected_dec = [] expected_dec_str = [] ra = [] ra_hms = [] dec = [] dec_dms = [] for row in hipp: expected_ra_str.append(row[0].strip()) expected_dec_str.append(row[1].strip()) expected_ra.append(float(row[2])) expected_dec.append(float(row[3])) ra.append(Coord.fromD(str(row[2]))) dec.append(Coord.fromD(str(row[3]))) ra_hms.append(Coord.fromHMS(str(row[0]))) dec_dms.append(Coord.fromDMS(str(row[1]))) for i in range(len(hipp)): assert expected_ra_str[i] == ra_hms[i].strfcoord("%(h)02d %(m)02d %(s)05.2f"), \ "ra: %s != coord ra: %s" % (expected_ra_str[i], ra_hms[i].strfcoord("%(h)02d %(m)02d %(s)05.2f")) assert expected_dec_str[i] == dec_dms[i].strfcoord("%(d)02d %(m)02d %(s)04.1f"), \ "dec: %s != coord dec: %s" % (expected_dec_str[i], dec_dms[i].strfcoord("%(d)02d %(m)02d %(s)04.1f")) # test conversion from D to D assert TestCoord.equal(ra[i].D, expected_ra[i], e=1e-8), \ "ra: %.6f != coord ra: %.6f (%.6f)" % (expected_ra[i], ra[i].D, expected_ra[i]-ra[i].D) assert TestCoord.equal(dec[i].D, expected_dec[i], e=1e-8), \ "dec: %.6f != coord dec: %.64f (%.6f)" % (expected_dec[i], dec[i].D, expected_dec[i]-dec[i].D) # test conversion from DMS HMS to D assert TestCoord.equal(ra_hms[i].D, expected_ra[i], e=1e-4), \ "ra: %.6f != coord ra: %.6f (%.6f)" % (expected_ra[i], ra_hms[i].D, expected_ra[i]-ra_hms[i].D) assert TestCoord.equal(dec_dms[i].D, expected_dec[i], e=1e-4), \ "dec: %.6f != coord dec: %.64f (%.6f)" % (expected_dec[i], dec_dms[i].D, expected_dec[i]-dec_dms[i].D)
def test_parsing_conversion_hipparcos (self): """Parsing and comparing a subset of the Hipparcos and Tycho Catalog""" hipp = ascii.read(os.path.abspath(os.path.join(os.path.dirname(__file__), 'hipparcos-tycho.dat')), format="tab") expected_ra = [] expected_ra_str = [] expected_dec = [] expected_dec_str = [] ra = [] ra_hms = [] dec = [] dec_dms = [] for row in hipp: expected_ra_str.append(row[0].strip()) expected_dec_str.append(row[1].strip()) expected_ra.append(float(row[2])) expected_dec.append(float(row[3])) ra.append(Coord.fromD(str(row[2]))) dec.append(Coord.fromD(str(row[3]))) ra_hms.append(Coord.fromHMS(str(row[0]))) dec_dms.append(Coord.fromDMS(str(row[1]))) for i in range(len(hipp)): assert expected_ra_str[i] == ra_hms[i].strfcoord("%(h)02d %(m)02d %(s)05.2f"), \ "ra: %s != coord ra: %s" % (expected_ra_str[i], ra_hms[i].strfcoord("%(h)02d %(m)02d %(s)05.2f")) assert expected_dec_str[i] == dec_dms[i].strfcoord("%(d)02d %(m)02d %(s)04.1f"), \ "dec: %s != coord dec: %s" % (expected_dec_str[i], dec_dms[i].strfcoord("%(d)02d %(m)02d %(s)04.1f")) # test conversion from D to D assert TestCoord.equal(ra[i].D, expected_ra[i], e=1e-8), \ "ra: %.6f != coord ra: %.6f (%.6f)" % (expected_ra[i], ra[i].D, expected_ra[i]-ra[i].D) assert TestCoord.equal(dec[i].D, expected_dec[i], e=1e-8), \ "dec: %.6f != coord dec: %.64f (%.6f)" % (expected_dec[i], dec[i].D, expected_dec[i]-dec[i].D) # test conversion from DMS HMS to D assert TestCoord.equal(ra_hms[i].D, expected_ra[i], e=1e-4), \ "ra: %.6f != coord ra: %.6f (%.6f)" % (expected_ra[i], ra_hms[i].D, expected_ra[i]-ra_hms[i].D) assert TestCoord.equal(dec_dms[i].D, expected_dec[i], e=1e-4), \ "dec: %.6f != coord dec: %.64f (%.6f)" % (expected_dec[i], dec_dms[i].D, expected_dec[i]-dec_dms[i].D)
def getAz(self): self._write(":GZ#") ret = self._readline() ret = ret.replace('\xdf', ':') c = Coord.fromDMS(ret[:-1]) if self['azimuth180Correct']: if c.toD() >= 180: c = c - Coord.fromD(180) else: c = c + Coord.fromD(180) return c
def getAz(self): # converted to Astelco ret = self._tpl.getobject('POSITION.HORIZONTAL.AZ') if ret: self._az = Coord.fromD(ret) self.log.debug('Az: %9.5f'%float(ret)) c = self._az #Coord.fromD(ret) if self['azimuth180Correct']: if c.toD() >= 180: c = c - Coord.fromD(180) else: c = c + Coord.fromD(180) return c
def getAlt(self): # converted to Astelco ret = self._tpl.getobject('POSITION.HORIZONTAL.ALT') if ret: self._alt = Coord.fromD(ret) self.log.debug('Alt: %9.5f'%float(ret)) return self._alt
def _valueAt(self, fn, *coords): """ Accepts a function callback and variable coords. If len(coords) == 1 convert (from tuple or Position) to decimal degress. If len(coords) == 2, convert (from number or Coord) to decimal degress """ assert len(coords) >= 1 assert self._wcs is not None if len(coords) == 2: c1 = Coord.fromH(coords[0]).D c2 = Coord.fromD(coords[1]).D else: if isinstance(coords[0], Position): c1, c2 = coords[0].dd() else: # assumes as tuple c1, c2 = coords[0] value = fn(N.array([[c1, c2]]), 1) if len(value) >= 1: return tuple(value[0]) else: raise WCSNotFoundException("Couldn't convert coordinates.")
class Dome(Interface): """ A Roll-off or classic dome. """ __config__ = { "device": None, "telescope": "/Telescope/0", "mode": Mode.Stand, "model": "Fake Domes Inc.", "style": Style.Classic, 'park_position': Coord.fromD(155), 'park_on_shutdown': False, 'close_on_shutdown': False, "az_resolution": 2, # dome position resolution in degrees "slew_timeout": 120, "abort_timeout": 60, "init_timeout": 5, "open_timeout": 20, "close_timeout": 20, "fans": [], # list of fans of the dome, i.e.: fans: ['/FakeFan/fake1', '/FakeFan/fake2'] "lamps": [], # list of lamps of the dome, i.e.: lamps: ['/FakeLamp/fake1'] }
def _watchTrackingStopped(self, position, status): self.setFlag("telescope",InstrumentOperationFlag.READY) self.broadCast('Telescope tracking stopped with status %s.' % status) if status == TelescopeStatus.OBJECT_TOO_LOW: # Todo: Make this an action on the checklist database, so user can configure what to do robobs = self.getRobObs() sched = self.getSched() robobs.stop() sched.stop() tel = self.getTel() from chimera.util.position import Position from chimera.util.coord import Coord park_position = Position.fromAltAz(Coord.fromD(80),Coord.fromD(89)) tel.slewToAltAz(park_position) robobs.reset_scheduler() robobs.start() robobs.wake()
def getAz(self): self._write(":GZ#") ret = self._readline() ret = ret.replace('\xdf', ':') c = Coord.fromDMS(ret[:-1]) if self['azimuth180Correct']: self.log.debug('Initial azimuth: %s' % str(c.toDMS())) if c.toD() > 180: c = c - Coord.fromD(180) else: c = c + Coord.fromD(180) self.log.debug('Final azimuth: %s' % str(c.toDMS())) return c
def getAz(self): tpl = self.getTPL() ret = tpl.getobject('POSITION.INSTRUMENTAL.DOME[0].CURRPOS') if ret: self._position = ret elif not self._position: self._position = 0. return Coord.fromD(self._position)
def _moveDome(self): dome = self._getDome() # from chimera.util.coord import Coord target = Coord.fromD(self["dome_az"]) dome.stand() dome.slewToAz(target)
def test_altAzRaDec(self): altAz = Position.fromAltAz('20:30:40', '222:11:00') lat = Coord.fromD(0) o = ephem.Observer() o.lat = '0:0:0' o.long = '0:0:0' o.date = dt.now(tz.tzutc()) lst = float(o.sidereal_time()) raDec = Position.altAzToRaDec(altAz, lat, lst) altAz2 = Position.raDecToAltAz(raDec, lat, lst) assert equal(altAz.alt.toR(),altAz2.alt.toR()) & equal(altAz.az.toR(),altAz2.az.toR())
def setTargetAz(self, az): # converted to Astelco if not isinstance(az, Coord): az = Coord.fromDMS(az) if self['azimuth180Correct']: if az.toD() >= 180: az = az - Coord.fromD(180) else: az = az + Coord.fromD(180) cmdid = self._tpl.set('OBJECT.HORIZONTAL.AZ', az.D, wait=True) ret = self._tpl.succeeded(cmdid) if not ret: raise AstelcoException( "Invalid Azimuth '%s'" % az.strfcoord("%(d)03d\xdf%(m)02d")) self._target_az = az return True
def _moveScope(self, pierSide=None): """ Moves the scope, usually to zenith """ tel = self._getTel() if pierSide is not None and tel.features(TelescopePier): self.log.debug("Setting telescope pier side to %s." % tel.getPierSide().__str__().lower()) tel.setSideOfPier(self['pier_side']) else: self.log.warning("Telescope does not support pier side.") try: self.log.debug("Slewing scope to alt {} az {}".format(self["flat_alt"], self["flat_az"])) tel.slewToAltAz(Position.fromAltAz(Coord.fromD(self["flat_alt"]), Coord.fromD(self["flat_az"]))) if tel.isTracking(): tel.stopTracking() except: self.log.debug("Error moving the telescope")
def getAz(self, tag=None): if tag is not None: ack = tag else: ack = self._getTag() if ack < 846: # 270 to 360 deg az = 270 + (ack - 801) * 2 else: # 0 to 270 deg az = (ack - 846) * 2 return Coord.fromD(az)
def setTargetAz(self, az): if not isinstance (az, Coord): az = Coord.fromDMS (az) if self['azimuth180Correct']: if az.toD() >= 180: az = az - Coord.fromD(180) else: az = az + Coord.fromD(180) self._write (":Sz%s#" % az.strfcoord("%(d)03d\xdf%(m)02d:%(s)02d", signed=False)) ret = self._readbool() if not ret: raise MeadeException("Invalid Azimuth '%s'" % az.strfcoord("%(d)03d\xdf%(m)02d")) self._target_az = az return True
def telegram_set_target(self, bot, update, args, job_queue, chat_data): if len(args) != 2: update.message.reply_text( "Usage: /set HH:MM:SS.S DD:MM:SS.S or /set ra dec (J2000)") else: self.last_update = datetime.datetime.now() ra = Coord.fromHMS(args[0]) if ":" in args[0] else Coord.fromD( float(args[0])) dec = Coord.fromDMS(args[1]) if ":" in args[1] else Coord.fromD( float(args[1])) self.target = Position.fromRaDec(ra, dec) site = self.getSite() lst = site.LST_inRads() alt = float(site.raDecToAltAz(self.target, lst).alt) # TODO: reject if alt< telescope_min_alt! moonPos = site.moonpos() moonRaDec = site.altAzToRaDec(moonPos, lst) moonDist = self.target.angsep(moonRaDec) update.message.reply_text( 'Hello {} arg is {} {}. Object alt = {}, Moon dist = {}'. format(update.message.from_user.first_name, args[0], args[1], alt, moonDist))
def setTargetAlt(self, alt): # converted to Astelco if not isinstance(alt, Coord): alt = Coord.fromD(alt) cmdid = self._tpl.set('OBJECT.HORIZONTAL.ALT', alt.D, wait=True) ret = self._tpl.succeeded(cmdid) if not ret: raise AstelcoException("Invalid Altitude '%s'" % alt) self._target_alt = alt return True
def pointVerify(self): """ Checks telescope pointing Checks the pointing. If abs ( telescope coordinates - image coordinates ) > tolerance move the scope take a new image test again do this while ntrials < max_trials Returns True if centering was succesful False if not """ # take an image and read its coordinates off the header image = None try: image = self._takeImage() print "image name %s", image.filename() except: self.log.error("Can't take image") raise ra_img_center = image["CRVAL1"] # expects to see this in image dec_img_center = image["CRVAL2"] currentImageCenter = Position.fromRaDec(Coord.fromD(ra_img_center), Coord.fromD(dec_img_center)) tel = self.getTel() # analyze the previous image using # AstrometryNet defined in util try: wcs_name = AstrometryNet.solveField(image.filename(), findstarmethod="sex") except NoSolutionAstrometryNetException, e: raise e
def trigger_observation(self, ra, dec, trigger_time=datetime.datetime.utcnow()): """ Acquire observatory control, point and start exposing :return: """ # Clear previous abort state self.abort.clear() # Acquire telescope via supervisor action self.acquire_telescope() telescope = self.getTelescope() # Point self.log.debug("Slewing to ra, dec %.2f %.2f" % (ra, dec)) telescope.slewToRaDec( Position.fromRaDec(Coord.fromD(ra), Coord.fromD(dec))) # Start expose sequence # TODO: register a method change_filter to the camera readout camera = self.getCamera() filterwheel = self.getFilterWheel() with open(os.path.expanduser("~/.chimera/grb_sequence.json")) as fp: sequence = json.load(fp) for request in sequence: self.log.debug("Exposing: %s" % str(request)) filterwheel.setFilter(request.pop('filter')) camera.expose(request) if self.abort.is_set(): self.release_telescope() return False self.release_telescope() return True
def pointVerify (self): """ Checks telescope pointing Checks the pointing. If abs ( telescope coordinates - image coordinates ) > tolerance move the scope take a new image test again do this while ntrials < max_trials Returns True if centering was succesful False if not """ # take an image and read its coordinates off the header image = None try: image = self._takeImage() print "image name %s", image.filename() except: self.log.error( "Can't take image" ) raise ra_img_center = image["CRVAL1"] # expects to see this in image dec_img_center= image["CRVAL2"] currentImageCenter = Position.fromRaDec(Coord.fromD(ra_img_center), Coord.fromD(dec_img_center)) tel = self.getTel() # analyze the previous image using # AstrometryNet defined in util try: wcs_name = AstrometryNet.solveField(image.filename(),findstarmethod="sex") except NoSolutionAstrometryNetException, e: raise e
def fromRaDec(ra, dec, epoch=Epoch.J2000): try: if type(ra) is str: ra = Coord.fromHMS(ra) elif isinstance(ra, Coord): ra = ra.toHMS() else: try: ra = Coord.fromH(float(ra)) ra = ra.toHMS() except ValueError: raise ValueError( "Invalid RA coordinate type %s. Expected numbers, strings or Coords." % str(type(ra))) Position._checkRange(float(ra), 0, 360) except ValueError as e: raise ValueError("Invalid RA coordinate %s" % str(ra)) except PositionOutsideLimitsError: raise ValueError( "Invalid RA range %s. Must be between 0-24 hours or 0-360 deg." % str(ra)) try: if type(dec) is str: dec = Coord.fromDMS(dec) elif isinstance(dec, Coord): dec = dec.toDMS() else: try: dec = Coord.fromD(float(dec)) dec = dec.toDMS() except ValueError: raise ValueError( "Invalid DEC coordinate type %s. Expected numbers, strings or Coords." % str(type(dec))) Position._checkRange(float(dec), -90, 360) except ValueError as e: raise ValueError("Invalid DEC coordinate %s" % str(dec)) except PositionOutsideLimitsError: raise ValueError( "Invalid DEC range %s. Must be between 0-360 deg or -90 - +90 deg." % str(dec)) return Position((ra, dec), system=System.CELESTIAL, epoch=epoch)
def setTargetAlt(self, alt): if not isinstance(alt, Coord): alt = Coord.fromD(alt) self._write(":Sa%s#" % alt.strfcoord("%(d)02d\xdf%(m)02d\'%(s)02d")) ret = self._readbool() if not ret: raise MeadeException("Invalid Altitude '%s'" % alt) self._target_alt = alt return True
def setTargetAz(self, az): if not isinstance(az, Coord): az = Coord.fromDMS(az) if self['azimuth180Correct']: if az.toD() >= 180: az = az - Coord.fromD(180) else: az = az + Coord.fromD(180) self._write(":Sz%s#" % az.strfcoord("%(d)03d\xdf%(m)02d:%(s)02d", signed=False)) ret = self._readbool() if not ret: raise MeadeException("Invalid Azimuth '%s'" % az.strfcoord("%(d)03d\xdf%(m)02d")) self._target_az = az return True
def setTargetAlt(self, alt): if not isinstance (alt, Coord): alt = Coord.fromD (alt) self._write(":Sa%s#" % alt.strfcoord("%(d)02d\xdf%(m)02d\'%(s)02d")) ret = self._readbool() if not ret: raise MeadeException("Invalid Altitude '%s'" % alt) self._target_alt = alt return True
def test_park(self): # FIXME: make a real test. raise SkipTest() def printPosition(): print self.tel.getPositionRaDec(), self.tel.getPositionAltAz() sys.stdout.flush() print ra = self.tel.getRa() dec = self.tel.getDec() print "current position:", self.tel.getPositionRaDec() print "moving to:", (ra - "01 00 00"), (dec - "01 00 00") self.tel.slewToRaDec( Position.fromRaDec(ra - Coord.fromH(1), dec - Coord.fromD(1))) for i in range(10): printPosition() time.sleep(0.5) print "parking..." sys.stdout.flush() self.tel.park() t0 = time.time() wait = 30 for i in range(10): printPosition() time.sleep(0.5) while time.time() < t0 + wait: print "\rwaiting ... ", sys.stdout.flush() time.sleep(1) print "unparking..." sys.stdout.flush() self.tel.unpark() for i in range(10): printPosition() time.sleep(0.5)
def test_slew_abort(self): site = self.manager.getProxy("/Site/0") # go to know position self.tel.slewToRaDec(Position.fromRaDec(site.LST(), site["latitude"])) last = self.tel.getPositionRaDec() # clear event checkings FiredEvents = {} # drift it dest = Position.fromRaDec(last.ra + Coord.fromH(1), last.dec + Coord.fromD(10)) real_dest = None @callback(self.manager) def slewBeginClbk(target): global real_dest real_dest = target @callback(self.manager) def slewCompleteClbk(position, status): assert last.ra < position.ra < real_dest.ra assert last.dec < position.dec < real_dest.dec self.tel.slewBegin += slewBeginClbk self.tel.slewComplete += slewCompleteClbk # async slew def slew(): tel = self.manager.getProxy(self.TELESCOPE) tel.slewToRaDec(dest) pool = ThreadPool() pool.queueTask(slew) # wait thread to be scheduled time.sleep(2) # abort and test self.tel.abortSlew() pool.joinAll() # event checkings self.assertEvents(TelescopeStatus.ABORTED)
def test_park (self): # FIXME: make a real test. raise SkipTest() def printPosition(): print self.tel.getPositionRaDec(), self.tel.getPositionAltAz() sys.stdout.flush() print ra = self.tel.getRa() dec = self.tel.getDec() print "current position:", self.tel.getPositionRaDec() print "moving to:", (ra-"01 00 00"), (dec-"01 00 00") self.tel.slewToRaDec(Position.fromRaDec(ra-Coord.fromH(1), dec-Coord.fromD(1))) for i in range(10): printPosition() time.sleep(0.5) print "parking..." sys.stdout.flush() self.tel.park() t0 = time.time() wait = 30 for i in range(10): printPosition() time.sleep(0.5) while time.time() < t0+wait: print "\rwaiting ... ", sys.stdout.flush() time.sleep(1) print "unparking..." sys.stdout.flush() self.tel.unpark() for i in range(10): printPosition() time.sleep(0.5)
def test_slew_abort (self): site = self.manager.getProxy("/Site/0") # go to know position self.tel.slewToRaDec(Position.fromRaDec(site.LST(), site["latitude"])) last = self.tel.getPositionRaDec() # clear event checkings FiredEvents = {} # drift it dest = Position.fromRaDec(last.ra+Coord.fromH(1), last.dec+Coord.fromD(10)) real_dest = None @callback(self.manager) def slewBeginClbk(target): global real_dest real_dest = target @callback(self.manager) def slewCompleteClbk(position, status): assert last.ra < position.ra < real_dest.ra assert last.dec < position.dec < real_dest.dec self.tel.slewBegin += slewBeginClbk self.tel.slewComplete += slewCompleteClbk # async slew def slew(): tel = self.manager.getProxy(self.TELESCOPE) tel.slewToRaDec(dest) pool = ThreadPool() pool.queueTask(slew) # wait thread to be scheduled time.sleep(2) # abort and test self.tel.abortSlew() pool.joinAll() # event checkings self.assertEvents(TelescopeStatus.ABORTED)
def test_sync (self): # get current position, drift the scope, and sync on the first # position (like done when aligning the telescope). real = self.tel.getPositionRaDec() @callback(self.manager) def syncCompleteClbk(position): assert position.ra == real.ra assert position.dec == real.dec self.tel.syncComplete += syncCompleteClbk # drift to "real" object coordinate drift = Position.fromRaDec(real.ra+Coord.fromH(1), real.dec+Coord.fromD(1)) self.tel.slewToRaDec(drift) self.tel.syncRaDec(real) time.sleep(2)
def test_stress_dome_slew (self): # just for visual testing raise SkipTest() dome = self.manager.getProxy(self.DOME) quit = threading.Event() def get_az_stress (): while not quit.isSet(): dome.getAz() time.sleep(0.5) az_thread = threading.Thread(target=get_az_stress) az_thread.start() for i in range(10): az = random.randint(0,359) dome.slewToAz(Coord.fromD(az)) time.sleep(5) quit.set() az_thread.join()
def getAzOffset(self): tpl = self.getTPL() ret = tpl.getobject('POSITION.INSTRUMENTAL.DOME[0].OFFSET') return Coord.fromD(ret)
def _watchStateChanged(self, newState, oldState): self._debuglog.debug("State changed %s -> %s..." % (oldState, newState)) if oldState == SchedState.IDLE and newState == SchedState.OFF: if self.rob_state == RobState.ON: self._debuglog.debug( "Scheduler went from BUSY to OFF. Needs resheduling...") # if self._current_program is not None: # self._debuglog.warning("Wait for last program to be updated") # self._current_program_condition.acquire() # self._current_program_condition.wait(30) # wait 10s most! # self._current_program_condition.release() session = RSession() csession = model.Session() # cprog = model.Program( name = "CALIB", # pi = "Tiago Ribeiro", # priority = 1 ) # cprog.actions.append(model.Expose(frames = 3, # exptime = 10, # imageType = "DARK", # shutter = "CLOSE", # filename = "dark-$DATE-$TIME")) # cprog.actions.append(model.Expose(frames = 1, # exptime = 0, # imageType = "DARK", # shutter = "CLOSE", # filename = "bias-$DATE-$TIME")) # # csession.add(cprog) # self._current_program = cprog # self._debuglog.debug("Added: %s" % cprog) program_info = self.reshedule() # if program_info is not None: program = session.merge(program_info[0]) obs_block = session.merge(program_info[2]) self._debuglog.debug( "Adding program %s to scheduler and starting." % program) cprogram = program.chimeraProgram() for act in obs_block.actions: cact = getattr(sys.modules[__name__], act.action_type).chimeraAction(act) cprogram.actions.append(cact) cprogram = csession.merge(cprogram) csession.add(cprogram) csession.commit() program.finished = True session.commit() # sched = self.getSched() self._current_program = program_info self._no_program_on_queue = False # sched.start() # self._current_program_condition.release() self._debuglog.debug("Done") elif self._no_program_on_queue: self._debuglog.warning( "No program on robobs queue, waiting for 5 min.") time.sleep(300) else: self._debuglog.warning( "No program on robobs queue. Sending telescope to park position." ) # ToDo: Run an action from the database to send telescope to park position. cprog = model.Program(name="SAFETY", pi="ROBOBS", priority=1) to_park_position = model.Point() to_park_position.targetAltAz = Position.fromAltAz( Coord.fromD(88.), Coord.fromD(89.)) cprog.actions.append(to_park_position) csession.add(cprog) self._no_program_on_queue = True # self.stop() csession.commit() session.commit() # for i in range(10): # self.log.debug('Waiting %i/10' % i) # time.sleep(1.0) # sched = self.getSched() # sched.start() self.wake() self._debuglog.debug("Done") else: self._debuglog.debug("Current state is off. Won't respond.")
def getPositionRaDec(self): self._telescope.GetRaDec() return Position.fromRaDec(Coord.fromH(self._telescope.dRa), Coord.fromD(self._telescope.dDec))
def slewToAz(self, az): # Astelco Dome will only enable slew if it is not tracking # If told to slew I will check if the dome is syncronized with # with the telescope. If it is not it¡ will wait until it gets # in sync or timeout... if self.getMode() == Mode.Track: raise AstelcoDomeException('Dome is in track mode... Slew is completely controled by AsTelOS...') # self.log.warning('Dome is in track mode... Slew is completely controled by AsTelOS...') # self.slewBegin(az) # # start_time = time.time() # self._abort.clear() # self._slewing = True # caz = self.getAz() # # while self.isSlewing(): # # time.sleep(1.0) # if time.time() > (start_time + self._maxSlewTime): # self.log.warning('Dome syncronization timed-out...') # self.slewComplete(self.getAz(), DomeStatus.TIMEOUT) # return 0 # elif self._abort.isSet(): # self._slewing = False # self.slewComplete(self.getAz(), DomeStatus.ABORTED) # return 0 # elif abs(caz - self.getAz()) < 1e-6: # self._slewing = False # self.slewComplete(self.getAz(), DomeStatus.OK) # return 0 # else: # caz = self.getAz() # # self.slewComplete(self.getAz(), DomeStatus.OK) else: self.log.info('Slewing to %f...' % az) start_time = time.time() self._abort.clear() self._slewing = True current_az = self.getAz() tpl = self.getTPL() self.slewBegin(az) cmdid = tpl.set('POSITION.INSTRUMENTAL.DOME[0].TARGETPOS', '%f' % az) reference_alt = Coord.fromD(0.) desired_position = Position.fromAltAz(reference_alt, az) # Wait for command to be completed cmd = tpl.getCmd(cmdid) while not cmd.complete: if time.time() > (start_time + self._maxSlewTime): self.log.warning('Dome syncronization timed-out...') self.slewComplete(self.getAz(), DomeStatus.ABORTED) return 0 cmd = tpl.getCmd(cmdid) # time.sleep(self['stabilization_time']) # Wait dome arrive on desired position while True: current_position = Position.fromAltAz(reference_alt, current_az) if time.time() > (start_time + self._maxSlewTime): self.slewComplete(self.getAz(), DomeStatus.ABORTED) raise AstelcoDomeException('Dome syncronization timed-out...') elif self._abort.isSet(): self._slewing = False tpl.set('POSITION.INSTRUMENTAL.DOME[0].TARGETPOS', current_az) self.slewComplete(self.getAz(), DomeStatus.ABORTED) return 0 elif abs(current_position.angsep(desired_position)) < tpl.getobject( 'POINTING.SETUP.DOME.MAX_DEVIATION') * 2.0: self._slewing = False self.slewComplete(self.getAz(), DomeStatus.OK) return 0 else: current_az = self.getAz() self.slewComplete(self.getAz(), DomeStatus.OK)
except ValueError, e: raise ValueError("Invalid RA coordinate %s" % str(ra)) except PositionOutsideLimitsError: raise ValueError( "Invalid RA range %s. Must be between 0-24 hours or 0-360 deg." % str(ra)) try: if type(dec) == StringType: dec = Coord.fromDMS(dec) elif isinstance(dec, Coord): dec = dec.toDMS() else: try: dec = Coord.fromD(float(dec)) dec = dec.toDMS() except ValueError: raise ValueError( "Invalid DEC coordinate type %s. Expected numbers, strings or Coords." % str(type(dec))) Position._checkRange(float(dec), -90, 360) except ValueError, e: raise ValueError("Invalid DEC coordinate %s" % str(dec)) except PositionOutsideLimitsError: raise ValueError( "Invalid DEC range %s. Must be between 0-360 deg or -90 - +90 deg." % str(dec))
def getPositionRaDec(self): self._telescope.GetRaDec() return Position.fromRaDec(Coord.fromH(self._telescope.dRa), Coord.fromD(self._telescope.dDec), epoch=Epoch.NOW).toEpoch(Epoch.J2000)
if (zeta > -2. * pi) and (zeta < 2. * pi): if self.site_latitude.R <= 0.: zeta += pi else: zeta = telaz if zeta < 0: zeta = zeta + 2 * pi elif zeta > 2 * pi: zeta - 2 * pi return zeta * 180 / pi if __name__ == '__main__': import numpy as np dome_radius, mount_dec_height, mount_dec_length, mount_dec_offset = 147, 0, 49.2, 0 site = Site() Model = AzimuthModel(site['latitude'], dome_radius, mount_dec_height, mount_dec_length, mount_dec_offset) # for dra in np.arange(10, 200, 36): # for ddec in np.arange(1, 360, 10): for az, alt in [(ii, jj) for ii in np.arange(5, 360, 10) for jj in np.arange(25, 90, 20)]: tel_pos = Position.altAzToRaDec( Position.fromAltAz(Coord.fromD(alt), Coord.fromD(az)), site['latitude'], site.LST()) model = Model.solve_dome_azimuth(tel_pos, site.LST_inRads()) print 'here', alt, az, model, model - az
def getAlt(self): self._telescope.GetAzAlt() return Coord.fromD(self._telescope.dAlt)
def getDec(self): self._telescope.GetRaDec() return Coord.fromD(self._telescope.dDec)
Position._checkRange(float(ra), 0, 360) except ValueError, e: raise ValueError("Invalid RA coordinate %s" % str(ra)) except PositionOutsideLimitsError: raise ValueError( "Invalid RA range %s. Must be between 0-24 hours or 0-360 deg." % str(ra)) try: if type(dec) == StringType: dec = Coord.fromDMS(dec) elif isinstance(dec, Coord): dec = dec.toDMS() else: try: dec = Coord.fromD(float(dec)) dec = dec.toDMS() except ValueError: raise ValueError( "Invalid DEC coordinate type %s. Expected numbers, strings or Coords." % str(type(dec))) Position._checkRange(float(dec), -90, 360) except ValueError, e: raise ValueError("Invalid DEC coordinate %s" % str(dec)) except PositionOutsideLimitsError: raise ValueError( "Invalid DEC range %s. Must be between 0-360 deg or -90 - +90 deg." % str(dec)) return Position((ra, dec), system=System.CELESTIAL, epoch=epoch)
def getPositionAltAz(self): self._telescope.GetAzAlt() return Position.fromAltAz(Coord.fromD(self._telescope.dAlt), Coord.fromD(self._telescope.dAz))
class PointVerify(ChimeraObject, IPointVerify): """ Verifies telescope pointing. There are two ways of doing this: - verify the field the scope has been pointed to - choose a field (from a list of certified fields) and try verification """ # normal constructor # initialize the relevant variables def __init__(self): ChimeraObject.__init__(self) self.ntrials = 0 # number times we try to center on a field self.nfields = 0 # number of fields we try to center on self.checkedpointing = False # True = Standard field is verified self.currentField = 0 # counts fields tried to verify #def __start__ (self): #self.pointVerify() #self.checkPointing() #return True def getTel(self): return self.getManager().getProxy(self["telescope"]) def getCam(self): return self.getManager().getProxy(self["camera"]) def getFilter(self): return self.getManager().getProxy(self["filterwheel"]) def _takeImage(self): cam = self.getCam() frames = cam.expose(exptime=self["exptime"], frames=1, shutter=Shutter.OPEN, filename="pointverify-$DATE") if frames: return frames[0] else: raise Exception("Could not take an image") def pointVerify(self): """ Checks telescope pointing Checks the pointing. If abs ( telescope coordinates - image coordinates ) > tolerance move the scope take a new image test again do this while ntrials < max_trials Returns True if centering was succesful False if not """ # take an image and read its coordinates off the header image = None try: image = self._takeImage() print "image name %s", image.filename() except: self.log.error("Can't take image") raise ra_img_center = image["CRVAL1"] # expects to see this in image dec_img_center = image["CRVAL2"] currentImageCenter = Position.fromRaDec(Coord.fromD(ra_img_center), Coord.fromD(dec_img_center)) tel = self.getTel() # analyze the previous image using # AstrometryNet defined in util try: wcs_name = AstrometryNet.solveField(image.filename(), findstarmethod="sex") except NoSolutionAstrometryNetException, e: raise e # why can't I select this exception? # # there was no solution to this field. # send the telescope back to checkPointing # if that fails, clouds or telescope problem # an exception will be raised there #self.log.error("No WCS solution") #if not self.checkedpointing: # self.nfields += 1 # self.currentField += 1 # if self.nfields <= self["max_fields"] and self.checkPointing() == True: # self.checkedpointing = True # tel.slewToRaDec(currentImageCenter) # try: # self.pointVerify() # return True # except CanSetScopeButNotThisField: # raise # # else: # self.checkedpointing = False # self.currentField = 0 # raise Exception("max fields") # #else: # self.checkedpointing = False # raise CanSetScopeButNotThisField("Able to set scope, but unable to verify this field %s" %(currentImageCenter)) wcs = Image.fromFile(wcs_name) ra_wcs_center = wcs["CRVAL1"] + (wcs["NAXIS1"] / 2.0 - wcs["CRPIX1"]) * wcs["CD1_1"] dec_wcs_center = wcs["CRVAL2"] + (wcs["NAXIS2"] / 2.0 - wcs["CRPIX2"]) * wcs["CD2_2"] currentWCS = Position.fromRaDec(Coord.fromD(ra_wcs_center), Coord.fromD(dec_wcs_center)) # save the position of first trial: if (self.ntrials == 0): initialPosition = Position.fromRaDec(Coord.fromD(ra_img_center), Coord.fromD(dec_img_center)) initialWCS = Position.fromRaDec(currentWCS.ra, currentWCS.dec) # write down the two positions for later use in mount models if (self.ntrials == 0): site = self.getManager().getProxy("/Site/0") logstr = "Pointing Info for Mount Model: %s %s %s %s %s" % ( site.LST(), site.MJD(), image["DATE-OBS"], initialPosition, currentWCS) self.log.info(logstr) delta_ra = ra_img_center - ra_wcs_center delta_dec = dec_img_center - dec_wcs_center self.log.debug("delta_ra: %s delta_dec: %s" % (delta_ra, delta_dec)) self.log.debug("ra_img_center: %s ra_wcs_center: %s" % (ra_img_center, ra_wcs_center)) self.log.debug("dec_img_center: %s dec_wcs_center: %s" % (dec_img_center, dec_wcs_center)) # *** need to do real logging here logstr = "%s %f %f %f %f %f %f" % (image["DATE-OBS"], ra_img_center, dec_img_center, ra_wcs_center, dec_wcs_center, delta_ra, delta_dec) self.log.debug(logstr) if (fabs(delta_ra) > self["tolra"]) or (fabs(delta_dec) > self["toldec"]): print "Telescope not there yet." print "Trying again" self.ntrials += 1 if (self.ntrials > self["max_trials"]): self.ntrials = 0 raise CantPointScopeException( "Scope does not point with a precision of %f (RA) or %f (DEC) after %d trials\n" % (self["tolra"], self["toldec"], self["max_trials"])) time.sleep(5) tel.moveOffset(Coord.fromD(delta_ra).AS, Coord.fromD(delta_dec).AS, rate=SlewRate.CENTER) self.pointVerify() else: # if we got here, we were succesfull, reset trials counter self.ntrials = 0 self.currentField = 0 # and save final position # write down the two positions for later use in mount models logstr = "Pointing: final solution %s %s %s" % ( image["DATE-OBS"], currentImageCenter, currentWCS) #self.log.debug("Synchronizing telescope on %s" % currentWCS) #tel.syncRaDec(currentWCS) # *** should we sync the scope ??? # maybe there should be an option of syncing or not # the first pointing in the night should sync I believe # subsequent pointings should not. # another idea is to sync if the delta_coords at first trial were larger than some value self.log.info(logstr) return (True)