def get_moon(times): t = Table() earth = get_body(times, 'earth') moon = get_body(times, 'moon') em_x = moon['x']-earth['x'] em_y = moon['y']-earth['y'] em_z = moon['z']-earth['z'] em_d = np.sqrt(em_x**2 + em_y**2 + em_z**2) em_vx = moon['vx']-earth['vx'] em_vy = moon['vy']-earth['vy'] em_vz = moon['vz']-earth['vz'] em_v = np.sqrt(em_vx**2 + em_vy**2 + em_vz**2) t.add_column(moon['utc']) t.add_column(moon['jd']) t.add_column(em_x) t.add_column(em_y) t.add_column(em_z) t.add_column(em_d, name='d') t.add_column(em_vx) t.add_column(em_vy) t.add_column(em_vz) t.add_column(em_v, name='v') t.add_column(np.arcsin(em_z/em_d), name='dec') t.add_column(np.arctan2(em_y, em_x), name='RA') return t
def termtime(daytime,daytime2,code,unit='hour'): if unit=='hour': times=daytime+np.linspace(0.,1.,25)*(daytime2-daytime) elif unit=='minute': times=daytime+np.linspace(0.,1.,61)*(daytime2-daytime) else: times=daytime+np.linspace(0.,1.,61)*(daytime2-daytime) gmttimes=times-eighthours if type=='jieqi': diflongitudes=get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg else: sunlongitudes=get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg moonlongitudes=get_body('moon', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg diflongitudes=(moonlongitudes-sunlongitudes)%360 difcode=diflongitudes // sec difcode=[int(difcode[i]) for i in range(len(difcode))] for i in range(len(difcode)-1): if difcode[i+1]!=code: if unit=='hour': return termtime(times[i],times[i+1],code,"minute") else: if unit=='minute': return termtime(times[i],times[i+1],code,"second") else: return ((code+1) % (360//sec),(times[i]+0.5*(times[i+1]-times[i])).value) return (-1,"")
def gcrs_to_geosolarecliptic(gcrs_coo, to_frame): if not to_frame.obstime.isscalar: raise ValueError( "To perform this transformation the obstime Attribute must be a scalar." ) _earth_orbit_perpen_point_gcrs = UnitSphericalRepresentation( lon=0 * u.deg, lat=(90 * u.deg - _obliquity_rotation_value(to_frame.obstime))) _earth_detilt_matrix = _make_rotation_matrix_from_reprs( _earth_orbit_perpen_point_gcrs, CartesianRepresentation(0, 0, 1)) sun_pos_gcrs = get_body("sun", to_frame.obstime).cartesian earth_pos_gcrs = get_body("earth", to_frame.obstime).cartesian sun_earth = sun_pos_gcrs - earth_pos_gcrs sun_earth_detilt = sun_earth.transform(_earth_detilt_matrix) # Earth-Sun Line in Geocentric Solar Ecliptic Frame x_axis = CartesianRepresentation(1, 0, 0) rot_matrix = _make_rotation_matrix_from_reprs(sun_earth_detilt, x_axis) return matrix_product(rot_matrix, _earth_detilt_matrix)
def __init__(self, observer, body_name, t): """Calculate properties of the geometry of the observer, the body and the Sun.""" self.observer = observer self.body_name = body_name self.t = t # Position of the Sun self.sun = get_body('sun', self.t) # Position of the body self.body = get_body(body_name, self.t) # The location of the observer in HPC co-ordinates. self.observer_hpc = coordinates.Helioprojective( observer=observer, obstime=observer.obstime) # The location of the body as seen by the observer, following the # SunPy example self.body_hpc = self.body.transform_to( frames.Helioprojective).transform_to(self.observer_hpc) # The body and the observer in HCC for ease of distance calculation. self.body_hcc = self.body.transform_to(frames.Heliocentric) self.observer_hcc = self.observer.transform_to(frames.Heliocentric)
def gcrs_to_geosolarecliptic(gcrs_coo, to_frame): if not to_frame.obstime.isscalar: raise ValueError( "To perform this transformation the obstime Attribute must be a scalar." ) _earth_orbit_perpen_point_gcrs = UnitSphericalRepresentation( lon=0 * u.deg, lat=(90 * u.deg - _obliquity_rotation_value(to_frame.obstime)) ) _earth_detilt_matrix = _make_rotation_matrix_from_reprs( _earth_orbit_perpen_point_gcrs, CartesianRepresentation(0, 0, 1) ) sun_pos_gcrs = get_body("sun", to_frame.obstime).cartesian earth_pos_gcrs = get_body("earth", to_frame.obstime).cartesian sun_earth = sun_pos_gcrs - earth_pos_gcrs sun_earth_detilt = sun_earth.transform(_earth_detilt_matrix) # Earth-Sun Line in Geocentric Solar Ecliptic Frame x_axis = CartesianRepresentation(1, 0, 0) rot_matrix = _make_rotation_matrix_from_reprs(sun_earth_detilt, x_axis) return matrix_product(rot_matrix, _earth_detilt_matrix)
def galactic(tstart=None, tend=None, tstep=None, time=None): if time is not None and (tstart is not None or tend is not None or tstep is not None): raise AssertionError( 'Must enter one time, or a start time, end time, and time step') elif time is not None: with solar_system_ephemeris.set('jpl'): jup_ephem = get_body('sun', time).galactic elif time is None and (tstart is None or tend is None or tstep is None): raise AssertionError('Must enter start time, end time, and time step') elif time is None and (tstart is not None and tend is not None and tstep is not None): # tstart = tstart.mjd + (tstep/2) #use this line if you want times in the center of timeranges, dont use if you want coordinates at the time intervals themselves tstart = tstart.mjd # use if you want coordinates at time intervals not at center of intervals tend = tend.mjd times = np.arange(tstart, tend, tstep, dtype=float) times_list = Time(times, format='mjd').fits times_list = Time(times_list, format='fits') jup_ephem = list() for date in times_list: with solar_system_ephemeris.set('jpl'): jup = get_body('sun', date).galactic jup_ephem.append(jup) return jup_ephem
def CCTerm(start,end,type): eighthours=TimeDelta(8*3600,format='sec') def termtime(daytime,daytime2,code,unit='hour'): if unit=='hour': times=daytime+np.linspace(0.,1.,25)*(daytime2-daytime) elif unit=='minute': times=daytime+np.linspace(0.,1.,61)*(daytime2-daytime) else: times=daytime+np.linspace(0.,1.,61)*(daytime2-daytime) gmttimes=times-eighthours if type=='jieqi': diflongitudes=get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg else: sunlongitudes=get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg moonlongitudes=get_body('moon', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg diflongitudes=(moonlongitudes-sunlongitudes)%360 difcode=diflongitudes // sec difcode=[int(difcode[i]) for i in range(len(difcode))] for i in range(len(difcode)-1): if difcode[i+1]!=code: if unit=='hour': return termtime(times[i],times[i+1],code,"minute") else: if unit=='minute': return termtime(times[i],times[i+1],code,"second") else: return ((code+1) % (360//sec),(times[i]+0.5*(times[i+1]-times[i])).value) return (-1,"") start=Time(Time(start,out_subfmt='date').iso) end=Time(Time(end,out_subfmt='date').iso) daycount=int(round((Time(end)-Time(start)).value)) # print(start,end,daycount) # print(daycount) times=Time(start)+np.linspace(0.,1.,daycount+1)*(end-start+TimeDelta(3,format='sec')) # 考量潤秒,故加上3秒 times=Time(Time(times,out_subfmt='date').iso) gmttimes=times-TimeDelta(8*3600,format='sec') if type=='jieqi': diflongitudes= get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg sec=15 else: sunlongitudes=get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg moonlongitudes=get_body('moon', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg diflongitudes=(moonlongitudes-sunlongitudes)%360 sec=90 res=[] difcode=diflongitudes // sec difcode=[int(difcode[i]) for i in range(len(difcode))] for i in range(len(difcode)-1): if difcode[i]!=difcode[i+1]: res.append(termtime(times[i],times[i+1],difcode[i],'hour')) return res
def get_position(body_name, time, observer=None): """ Get the position of one of the supported bodies. If an observer is given then light travel time from the body to the observer is taken in to account. Parameters ---------- body_name : `str` The body whose position will be calculated time : `~astropy.time.Time` The time at which the body position is calculated. If the observer is not None, then the time is the time at the observer. observer : None, `~astropy.coordinate.SkyCoord` If None, the position of the body is returned. If not none, the position of the body as seen from the observer takes into account the light travel time from the body to the observer. Returns ------- `~astropy.coordinate.SkyCoord` The position of the body. If the observer is not none, the position of the body as seen from the observer takes into account the light travel time from the body to the observer. """ _body_name = body_name.lower() if observer is None: if _body_name in spice_spacecraft: spice_target = get_spice_target(_body_name) if _body_name == 'soho': # Use the SPICE kernels if available, otherwise estimate the position of SOHO. try: coordinate = spice_target.coordinate(time) except: # SpiceyError: earth = get_body('earth', time).transform_to(frames.HeliographicStonyhurst) coordinate = SkyCoord(lat=earth.lat, lon=earth.lon, radius=0.99 * earth.radius, obstime=time, frame=frames.HeliographicStonyhurst) else: coordinate = spice_target.coordinate(time) elif _body_name in solar_system_objects: coordinate = get_body(_body_name, time) else: raise ValueError('The body name is not recognized.') else: if _body_name in spice_spacecraft: #log.warning('Light travel time corrected locations of spacecraft are not yet supported ({:s} seen from observer).'.format(body_name)) spice_target = get_spice_target(_body_name) coordinate = spice_target.coordinate(time) elif _body_name in solar_system_objects: body_frame = get_body_heliographic_stonyhurst(_body_name, observer=observer, time=time) # Explicitly convert the returned body frame in to a SkyCoord. coordinate = SkyCoord(lat=body_frame.lat, lon=body_frame.lon, radius=body_frame.radius, obstime=time, frame=frames.HeliographicStonyhurst) else: raise ValueError('The body name is not recognized.') return coordinate.transform_to(frames.HeliographicStonyhurst)
def get_observer(observer_name, t): """ Get the location of the observer given the name of the observer.""" # TODO understand LASCO and helioviewer image processing steps if observer_name.lower() == 'soho': earth = get_body('earth', t).transform_to(frames.Heliocentric) return SkyCoord(earth.x, earth.y, 0.99 * earth.z, frame=frames.Heliocentric, obstime=t) else: return get_body(observer_name, t)
def find_parallax(self, date): '''Find the maximum parallax of self.planet on the given date from self.observer's location -- in other words, the difference in Mars' position between the observer's position and an observer at the same latitude but opposite longitude: this tells you you how much difference you would see from your position if Mars didn't move between your sunrise and sunset. ''' # To calculate from a point on the equator, set lat to 0. observer_loc = EarthLocation.from_geodetic(self.location.lon, self.location.lat, self.location.height) # Specify the anti-point. # This isn't really an antipode unless lat == 0. antipode_loc = EarthLocation.from_geodetic(-observer.lon, observer.lat, observer.height) # XXX Oops, astropy doesn't offer next_rising etc. # so we'll need a function to find that before this # function can be implemented since it only works # when the planet is on the horizon so both the observer # and the anti-observer can see it. risetime = find_next_rising(planetname, date) obs_planet = get_body(planetname, risetime, observer_loc) ant_planet = get_body(planetname, risetime, antipode_loc) # First, calculate it the straightforward way using the arctan: print() mars_dist_miles = mars.distance.km / 1.609344 print("Miles to Mars:", mars_dist_miles) earth_mean_radius = 3958.8 # in miles half_dist = earth_mean_radius * math.cos(observer_loc.lat) print("Distance between observers:", 2. * half_dist) par = 2. * math.atan(half_dist / mars_dist_miles) \ * 180. / math.pi * 3600. print("Calculated parallax (arcsec):", par) # See what astropy calculates as the difference between observations: print() print("parallax on %s: RA %f, dec %f" % (antipode.date, obs_planet.ra - ant_planet.ra, obs_planet.dec - ant_planet.dec)) total_par = (math.sqrt((obs_planet.ra.radians - ant_planet.ra.radians)**2 + (obs_planet.dec.radians - ant_planet.dec.radians)**2) * 180. * 3600. / math.pi) print("Total parallax (sum of squares): %f arcseconds" % total_par) print()
def test_regression_10291(): """ According to https://eclipse.gsfc.nasa.gov/OH/transit12.html, the minimum separation between Venus and the Sun during the 2012 transit is 554 arcseconds for an observer at the Geocenter. If light deflection from the Sun is incorrectly applied, this increases to 557 arcseconds. """ t = Time('2012-06-06 01:29:36') sun = get_body('sun', t) venus = get_body('venus', t) assert_quantity_allclose(venus.separation(sun), 554.427*u.arcsecond, atol=0.001*u.arcsecond)
def find_parallax(self, date): '''Find the maximum parallax of self.planet on the given date from self.observer's location -- in other words, the difference in Mars' position between the observer's position and an observer at the same latitude but opposite longitude: this tells you you how much difference you would see from your position if Mars didn't move between your sunrise and sunset. ''' # To calculate from a point on the equator, set lat to 0. observer_loc = EarthLocation.from_geodetic(self.location.lon, self.location.lat, self.location.height) # Specify the anti-point. # This isn't really an antipode unless lat == 0. antipode_loc = EarthLocation.from_geodetic(-observer.lon, observer.lat, observer.height) # XXX Oops, astropy doesn't offer next_rising etc. # so we'll need a function to find that before this # function can be implemented since it only works # when the planet is on the horizon so both the observer # and the anti-observer can see it. risetime = find_next_rising(planetname, date) obs_planet = get_body(planetname, risetime, observer_loc) ant_planet = get_body(planetname, risetime, antipode_loc) # First, calculate it the straightforward way using the arctan: print() mars_dist_miles = mars.distance.km / 1.609344 print("Miles to Mars:", mars_dist_miles) earth_mean_radius = 3958.8 # in miles half_dist = earth_mean_radius * math.cos(observer_loc.lat) print("Distance between observers:", 2. * half_dist) par = 2. * math.atan(half_dist / mars_dist_miles) \ * 180. / math.pi * 3600. print("Calculated parallax (arcsec):", par) # See what astropy calculates as the difference between observations: print() print("parallax on %s: RA %f, dec %f" % (antipode.date, obs_planet.ra - ant_planet.ra, obs_planet.dec - ant_planet.dec)) total_par = ( math.sqrt((obs_planet.ra.radians - ant_planet.ra.radians)**2 + (obs_planet.dec.radians - ant_planet.dec.radians)**2) * 180. * 3600. / math.pi) print("Total parallax (sum of squares): %f arcseconds" % total_par) print()
def main(): # MeerKAT obs_lat = -30.71323598930457 obs_lon = 21.443001467965008 loc = EarthLocation.from_geodetic(obs_lat, obs_lon) #,obs_height,ellipsoid) myms = sys.argv[1].rstrip('/') maintab = table(myms, ack=False) scans = list(numpy.unique(maintab.getcol('SCAN_NUMBER'))) ids, names, dirs = get_fields(myms) print(myms + ' | ' + str(len(ids)) + ' fields | ' + str(len(scans)) + ' scans') #header = 'Scan Field ID t[iso] t[s] t0[s] t1[s] int0 int1 Duration[m] N_int' header = 't[iso] Scan Field Name SunRA[deg] SunDec[deg] SunRA[hms] SunDec[dms] SunSep[deg] MoonRA[deg] MoonDec[deg] MoonRA[hms] MoonDec[dms] MoonSep[deg]' print('-' * len(header)) print(header) print('-' * len(header)) for scan in scans: subtab = maintab.query(query='SCAN_NUMBER==' + str(scan)) field = numpy.unique(subtab.getcol('FIELD_ID'))[0] name, field_ra, field_dec = match_field(ids, names, dirs, field) field_hms, field_dms = format_coords(field_ra, field_dec) t_scan = numpy.mean(subtab.getcol('TIME')) t = Time(t_scan / 86400.0, format='mjd') with solar_system_ephemeris.set('builtin'): sun = get_body('Sun', t, loc) moon = get_body('Moon', t, loc) sun_ra = sun.ra.value sun_dec = sun.dec.value moon_ra = moon.ra.value moon_dec = moon.dec.value sun_hms, sun_dms = format_coords(sun_ra, sun_dec) moon_hms, moon_dms = format_coords(moon_ra, moon_dec) delta_ra_sun = field_ra - sun_ra delta_dec_sun = field_dec - sun_dec delta_ra_moon = field_ra - moon_ra delta_dec_moon = field_dec - moon_dec sun_sep = calcsep(field_ra, field_dec, sun_ra, sun_dec) moon_sep = calcsep(field_ra, field_dec, moon_ra, moon_dec) # print field,name,sun_sep print( '%-28s %-5i %-5i %-12s %-12f %-12f %-16s %-16s %-12f %-12f %-12f %-16s %-16s %-12f' % (t.iso, scan, field, name, sun_ra, sun_dec, sun_hms, sun_dms, sun_sep, moon_ra, moon_dec, moon_hms, moon_dms, moon_sep)) print('-' * len(header))
def EarthRegion(times): gmttimes=times-eighthours sun=get_body('sun', gmttimes, ephemeris='jpl') moon=get_body('moon', gmttimes, ephemeris='jpl') earth=get_body('earth', gmttimes, ephemeris='jpl') rs=const.R_sun.to('km').value re=const.R_earth.to('km').value ro=1737.1 sunpos=np.transpose(np.array([sun.cartesian.x.value, sun.cartesian.y.value,sun.cartesian.z.value])) moonpos=np.transpose(np.array([moon.cartesian.x.value, moon.cartesian.y.value,moon.cartesian.z.value])) earthpos=np.zeros((len(sunpos),3)) Ucenter,Pcenter,uarc,parc,SOdir=ShadowCone(sunpos,rs,moonpos,ro) return(Region(sunpos,moonpos,earthpos,re,Ucenter,Pcenter,uarc,parc,SOdir))
def _select_solar_system(self, body: str) -> None: """Set RA/Dec for selected solar system body.""" from astropy.coordinates import solar_system_ephemeris, get_body # nothing? if body == "": return # clear simbad and JPL self.textSimbadName.clear() self.textJplHorizonsName.clear() QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) with solar_system_ephemeris.set("builtin"): # get coordinates body = get_body(body, Time.now(), self.observer.location) QtWidgets.QApplication.restoreOverrideCursor() # set them self.textMoveRA.setText( body.ra.to_string(unit=u.hour, sep=" ", precision=2)) self.textMoveDec.setText(body.dec.to_string(sep=" ", precision=2)) # update destination self._calc_dest_equatorial(clear=False)
def solarbody_to_radec( body, location, timestamp, # default output in degrees as_radians=False, as_string=False): """Calculate equatorial (ra, dec) for solar body ephemerides Parameters ---------- body: Name of solar body, Astropy convention location: Telescope geocentric position, `Astropy.EarthLocaton` timestamp: Unix timestamp Returns ------- tuple: (ra, dec) equatorial coordinates in degrees """ obs_time = timestamp2datetime(timestamp) obs_time = obs_time.strftime("%Y-%m-%d %H:%M:%S") obs_time = Time(obs_time) with solar_system_ephemeris.set('builtin'): solar_gcrs = get_body(body, obs_time, location) return radec_from_pointing_object(solar_gcrs, as_radians=as_radians, as_string=as_string)
def planet(body, obs_loc, t=None): if t is None: t = datetime.utcnow() body = body.lower() if not body in solar_system_ephemeris.bodies: raise Exception("Body not available!") if type(obs_loc) == str and obs_loc in cities.keys(): lon, lat = cities[obs_loc][:-1] elif isinstance(obs_loc, tuple): if len(obs_loc) == 2: lon, lat = obs_loc else: raise Exception("obs_loc should be in the format: (lon, lat)") else: raise Exception( "obs_loc should be a city name or geographic coordiantes.") loc = EarthLocation(lon=lon, lat=lat) with solar_system_ephemeris.set('jpl'): crd = get_body(body, Time(t), loc) ra = crd.ra.value dec = crd.dec.value r = crd.distance.value x, y, z = radec_to_cartesian(ra, dec, r) alt, az = radec_to_altaz(lon=lon, lat=lat, ra=ra, dec=dec, t=t) return (x, y, z), (ra, dec, r), (az, alt)
def get_planet_info(): planet_info = [] with solar_system_ephemeris.set('de432s'): for planet_name in planets: planet = get_body(planet_name, current_time, location) planet_info.append({ "name": planet_name, "lightMinutes": to_light_minutes(planet.distance), "xyz": get_xyz(planet) }) sun = get_sun(current_time) planet_info.append({ "name": "The Sun", "lightMinutes": to_light_minutes(sun.distance), "xyz": get_xyz(sun) }) moon = get_moon(current_time) planet_info.append({ "name": "The Moon", "lightMinutes": to_light_minutes(moon.distance), "xyz": get_xyz(moon) }) return json.dumps(planet_info)
def plot_solarsystem(self, obs_time): """ Put planets of Solar System on a given Axes instance. Designation of the each planet is its roman symbol """ # for Uranus must be another symbol, but at Unicode U+2645, which renders as ♅ (Wiki) planets = OrderedDict([('Mercury', '☿'), ('Venus', '♀'), ('Mars', '♂'), ('Jupiter', '♃'), ('Saturn', '♄'), ('Uranus', '♅'), ('Neptune', '♆')]) planets_coords = [ get_body(planet, obs_time, location=self.obs_loc) for planet in planets.keys() ] for coords, (name, symbol) in zip(planets_coords, planets.items()): planet = SkyCoord(coords.ra, coords.dec, frame='gcrs').transform_to('icrs') self.ax.plot([planet.ra.radian], [-planet.dec.value + 45], label=name, linestyle='', color='violet', marker='$' + symbol + '$', markersize=markers['planet']) print("planets are plotted")
def sun_position(obs_time): location = EarthLocation(lon=115.2505 * u.deg, lat=42.211833333 * u.deg, height=1365.0 * u.m) solar_system_ephemeris.set('de432s') # GCRS phasecentre = get_body('sun', obs_time, location, ephemeris='jpl') print('SUN: RA:{} Dec:{}'.format(phasecentre.ra.value, phasecentre.dec.value)) # convert phasecentre into ITRS coordinate # ITRF - Alta cAltAz = phasecentre.transform_to( AltAz(obstime=obs_time, location=location)) newAltAzcoordiantes = SkyCoord(alt=cAltAz.alt, az=cAltAz.az, obstime=obs_time, frame='altaz') new_ra_dec = newAltAzcoordiantes.transform_to('icrs') print(new_ra_dec) c_ITRS = phasecentre.transform_to(ITRS(obstime=obs_time, location=location)) local_ha = location.lon - c_ITRS.spherical.lon local_ha.wrap_at(24 * u.hourangle, inplace=True) print("UTC: {} Local Hour Angle: {}".format(obs_time, local_ha.to('deg').value)) obs_time1 = Time(obs_time, scale='utc', location=location) lst = obs_time1.sidereal_time('mean') local_ha1 = lst.to('deg').value - phasecentre.ra.value print("UTC: {} Local Hour Angle: {}".format(obs_time, local_ha1 * u.deg))
def moon_coordinates(time, cam): """This function searches for the moon position at a given time. Parameters ----------- time: 'astropy.time.core.Time' Time the image was taken. cam: 'str' Camera Returns ------- moon_altitude: 'float' Altitude of the moon at the time the image was taken [radians] """ observer = cam.location object = 'moon' with solar_system_ephemeris.set('builtin'): coordinates = get_body(object, time, observer) ra = coordinates.ra dec = coordinates.dec moon_position = SkyCoord(ra=ra, dec=dec, frame='icrs', unit='deg') moon_position_altaz = moon_position.transform_to( AltAz(obstime=time, location=observer)) moon_altitude = moon_position_altaz.alt.radian print('time', type(time)) return moon_altitude
def Get_Sun_Coordinates(self, cg, ctime): # # Get_Sun_Coordinates # # This method obtains the Sun Coordinates both in (Ra,Dec) and (Alt, Az) # While astropy may use very accurate calculations and corrections from # IERS, for some reason it cannot download the data. So, I decided to # work off-line with a lesser precision, although enoug for us. # # # @guiguesp - 2020-04-05 # - 2020-05-30 : Now using sunpy 1.1 #_____________________________________________________________________________ t = Time(ctime) with solar_system_ephemeris.set('builtin'): sun_radec = get_body('sun', t, cg) aa = AltAz(location=cg, obstime=t) sun_altaz = sun_radec.transform_to(aa) L0 = Sun_Coordinates.sun.L0(ctime) B0 = Sun_Coordinates.sun.B0(ctime) P = Sun_Coordinates.sun.P(ctime) R_Sun = Sun_Coordinates.sun.angular_radius(ctime) Carrington = Sun_Coordinates.sun.carrington_rotation_number(ctime) return sun_radec, sun_altaz, L0, B0, P, R_Sun, Carrington
def rm_celestial_bodies( self, radius=10.0, bodies=['moon', 'venus', 'mars', 'mercury', 'jupiter', 'saturn']): """Removes stars in the vicinity of bright celestial bodies from the image. Parameters ---------- radius : float Radius in pixels bodies : list(str) List of names of celestial bodies. For allowed values see astropy.coordinates.get_body. """ altaz_cs = AltAz(obstime=self.time, location=self.camera.location) objects = [ get_body(p, self.time, self.camera.location).transform_to(altaz_cs) for p in bodies ] px_pos = np.array([ np.array(self.camera.__project_stars__(p.az, p.alt)) for p in objects ]) D = distance_matrix(self.star_pos, px_pos) choice = np.all(D > radius, axis=1) self.star_pos = self.star_pos[choice, :] self.star_mag = self.star_mag[choice]
def stentime(plot=False): gravity = EarthLocation(lat=31.78135 * u.deg, lon=76.99313 * u.deg, height=1000 * u.m) time = Time(datetime(2020, 6, 8, 20, 18, 37, 274634)) deluni = np.linspace(0, 12, 1440) delta = deluni * u.hour utcoffset = 5.5 * u.hour time = time - utcoffset saturn = get_body('Saturn', time=time, location=gravity) frame = AltAz(obstime=time + delta, location=gravity) range1 = saturn.transform_to(frame) alts = range1.alt.value list20 = [] for i in range(1440): if (alts[i] >= 20): list20.append(i) first20delta = deluni[list20[0]] last20delta = deluni[list20[len(list20) - 1]] st = first20delta * u.hour ls = last20delta * u.hour if plot: plt.plot(delta, range1.alt.value) plt.xlim(0, 12) plt.xlabel('Hours from 8 PM IST') plt.ylabel('Saturn Alt at Gravity') plt.show() rise = time + st + utcoffset set = time + ls + utcoffset rised = rise.to_datetime() setd = set.to_datetime() print(rise.to_datetime()) print(set.to_datetime()) return rised, setd
def check_sun_position(self): now = dt.utcnow() sun = get_body("sun", Time(now)) sun.location = self.nanten2 azel = sun.altaz sun_az = azel.az.deg if sun_az > 240.: sun_az -= 360. sun_el = azel.alt.deg stop_flag = False az_list = self.az_list el_list = self.el_list for i in range(len(az_list)): if sun_az + 15 > +240.: if (sun_az - 360. + 15 >= az_list[i] / 3600. >= -120.) or (sun_az - 15 <= az_list[i] / 3600. <= +240.): stop_flag = True else: pass elif sun_az - 15 < -240.: if (sun_az + 360. - 15 <= az_list[i] / 3600. <= +120.) or (sun_az + 15 >= az_list[i] / 3600. >= -240.): stop_flag = True else: pass elif sun_az - 15 <= az_list[i] / 3600. <= sun_az + 15: stop_flag = True else: pass if sun_el - 15 <= el_list[i] / 3600. <= sun_el + 15: stop_flag = True return stop_flag
def get_object(objectName: str, earthPos: (float, float), time: str) -> dict: """Get the altitude and azimuth of an object at a given time and location :param objectName: Name of the target object :param earthPos: Latitude and Longitude of the observation location :param time: Time of observation :type objectName: string :type earthPos: (float, float) :type time: string :return: A dict containing the altitude and azimuth of the object :rtype: { 'alt': float, 'az': float } """ (lat, long) = earthPos astroTime = Time(time) objectCoord = get_body(objectName, astroTime) earthCoord = EarthLocation(lat=lat * u.deg, lon=long * u.deg) observation_frame = AltAz(obstime=astroTime, location=earthCoord) object_alt_az = objectCoord.transform_to(observation_frame) return { 'alt': round(object_alt_az.alt.deg, 2), 'az': round(object_alt_az.az.deg, 2) }
def run(self): if self.target == "Home": self.telescope.goto_home() elif self.target == "Stop": self.telescope.tracking = False else: body = get_body(self.target.lower(), Time.now()) self.telescope.goto(body.ra.hour, body.dec.degree)
def get_mars_ephemeris(timedate): """ Get the ephemeris of Mars given a particular julian date """ t = Time(timedate) with solar_system_ephemeris.set('builtin'): mars = get_body('mars', t) return mars
def _get_bodies(self, time): """Get position of the solar system bodies from Astropy. """ return [ get_body(body, time, ephemeris=self.ephemeris).transform_to(ITRS) for body in self.bodies ]
def set_beam_target(self, target_or_ra, dec=None, load_time=None, verbose=True): """ Given the name of an astronomical target, 'sun', or 'zenith', compute the current topocentric position of the body and point the beam at it. If the 'dec' keyword is not None, the target is intepreted to be a RA. """ # Force to string target_or_ra = str(target_or_ra) if dec is not None: dec = str(dec) # Figure out what to do with the name if target_or_ra.lower() in ('z', 'zen', 'zenith'): ## Zenith is easy az, alt = 0.0, 90.0 else: ## Load in where we are obs = EarthLocation.from_geocentric(*self.station.ecef, unit=u.m) ## Resolve the name into coordinates if dec is not None: ra = Angle(target_or_ra, unit='hourangle') dec = Angle(dec, unit='deg') sc = SkyCoord(ra, dec, frame='fk5') if verbose: print( f"Resolved '{target_or_ra}, {dec}' to RA {sc.ra}, Dec. {sc.dec}" ) elif target_or_ra.lower() in solar_system_ephemeris.bodies: if target_or_ra.lower().startswith('earth'): raise ValueError(f"Invalid target: '{target_or_ra}'") sc = get_body(target_or_ra.lower(), Time.now(), location=obs) if verbose: print( f"Resolved '{target_or_ra}' to {target_or_ra.lower()}") else: sc = SkyCoord.from_name(target_or_ra) if verbose: print( f"Resolved '{target_or_ra}' to RA {sc.ra}, Dec. {sc.dec}" ) ## Figure out where it is right now aa = sc.transform_to(AltAz(obstime=Time.now(), location=obs)) az = aa.az.deg alt = aa.alt.deg if verbose: print(f"Currently at azimuth {aa.az}, altitude {aa.alt}") # Point the beam self.set_beam_pointing(az, alt, degrees=True, load_time=load_time)
def check_sky_tonight(self, obj): if obj in self.planet_list: midnight = Time(self.date + ' 00:00:00') sky_obj = get_body(obj, midnight) else: sky_obj = SkyCoord.from_name(obj) sky_objaltazs_viewing_date = sky_obj.transform_to(self.viewing_frame) last_hour = 999 for altaz in sky_objaltazs_viewing_date: # need to parallelize this at some point altitude = altaz.alt (sign, d, m, s) = altitude.signed_dms (zsign, zd, zm, zs) = altaz.az.signed_dms zstr = zsign + zd ohour = str(altaz.obstime)[11:13] omin = str(altaz.obstime)[14:16] odate = str(altaz.obstime)[0:10] oday = str(altaz.obstime)[8:10] omon = str(altaz.obstime)[5:7] object_type = 'Planet' suggested_filters = '' finder_link = '' if obj not in self.planet_list: my_messier = Messier.MessierData() object_type = my_messier.object_type[obj] finder_link = "<a href=\"https://freestarcharts.com/images/Articles/Messier" \ "/Single/{0}_Finder_Chart.pdf\" target=\"_blank\">Finder Chart</a>".format(obj.upper()) if obj in my_messier.messier_filters.keys(): suggested_filters = my_messier.messier_filters[obj] skip_print = True if 0 <= int(omin) < 5: if ohour == last_hour: skip_print = True else: skip_print = False else: skip_print = True last_hour = ohour if altitude.is_within_bounds(20 * u.deg, 90 * u.deg) and not skip_print: obs_date, obs_hour = un_utc(odate, ohour) if int(ohour) % 2 == 0: tr_bgclr = "#d5f5e3" else: tr_bgclr = "#d6eaf8" compass = return_sector(zstr) direction = str(zstr) + " - {0}".format(compass) table_row = "<tr bgcolor={6}><td>{0}</td><td>{5}</td><td>{1}</td><td>{2}</td><td>{3}˚</td>" \ "<td>{4}˚</td><td>{8}</td><td>{7}</td></tr>\n" \ .format(obj.upper(), obs_date, obs_hour, d, direction, object_type, tr_bgclr, suggested_filters, finder_link) key = int(omon) * 10000 + int(oday) * 100 + int(ohour) self.viewing_index[self.v_i_ctr] = key self.viewing_dictionary[self.v_i_ctr] = table_row self.v_i_ctr += 1
def jupLoc(tt, dd, loc): ds = str(dd[0]) + '-' + str(dd[1]) + '-' + str(dd[2]) ts = str(tt[0]) + ':' + str(tt[1]) + ':' + str(tt[2]) t = Time(ds + ' ' + ts) # loc = EarthLocation.of_site('Kitt Peak') with solar_system_ephemeris.set('builtin'): jup_loc = get_body('jupiter', t, loc) return jup_loc.ra, jup_loc.dec
def compute_constraint(self, times, observer, targets): # use get_body rather than get sun here, since # it returns the Sun's coordinates in an observer # centred frame, so the separation is as-seen # by the observer. # 'get_sun' returns ICRS coords. sun = get_body('sun', times, location=observer.location) solar_separation = sun.separation(targets) if self.min is None and self.max is not None: mask = self.max >= solar_separation elif self.max is None and self.min is not None: mask = self.min <= solar_separation elif self.min is not None and self.max is not None: mask = ((self.min <= solar_separation) & (solar_separation <= self.max)) else: raise ValueError("No max and/or min specified in " "SunSeparationConstraint.") return mask
def __init__(self, parent = None, arg = None, name = "mount", port="", connect = True, var = {}): self.arg = arg self.Autoconnect = connect self.port = port self.parent = parent self.name = name self.sname = self.name self.variables = var self.rate = 1 self.mount = drive(profile = 'HEQ5', mode = "eq", connectMethod = 'pymlab', obs_lat = 48.986976, obs_lon = 14.467532, obs_alt = 300, port = '/dev/ttyUSB0') self.mount.run() self.mount.UnPark() #self.mount.Slew(SkyCoord(alt = 45, az = 10, obstime = Time.now(), frame = 'altaz', unit="deg", location = self.mount.getObs()).icrs) rospy.Subscriber("/mount/controll", String, callback_btn) rospy.Subscriber("/arom/UI/buttons", String, callback_btn) self.pub_status = rospy.Publisher('/mount/status', String, queue_size=10) self.pub_radec = rospy.Publisher('/mount/status/coordinates/RaDec', Float32MultiArray, queue_size=10) #rospy.init_node('AROM_mount') AromNode.__init__(self) print "zinicializovano" rate = rospy.Rate(self.rate) ra = 0 dec = 90 while not rospy.is_shutdown(): try: if len(btn_data) > 0: print btn_data[0], len(btn_data) lastBtn = btn_data[0] btn_data.pop(0) if "name" in lastBtn: split = lastBtn.split(" ") self.mount.Slew(SkyCoord.from_name(split[1])) #self.mount.Slew(SkyCoord(alt = float(split[1]), az = float(split[2]), obstime = Time.now(), frame = 'altaz', unit="deg", location = self.mount.getObs()).icrs) elif "solar" in lastBtn: split = lastBtn.split(" ") self.mount.Slew(get_body(split[1], obstime = Time.now(), location = self.mount.getObs()).icrs) elif "sun" in lastBtn: self.mount.Slew(get_sun(Time.now()).icrs) elif "altaz" in lastBtn: split = lastBtn.split(" ") self.mount.Slew(SkyCoord(alt = float(split[1]), az = float(split[2]), obstime = Time.now(), frame = 'altaz', unit="deg", location = self.mount.getObs()).icrs) elif "radec" in lastBtn: split = lastBtn.split(" ") self.mount.Slew(SkyCoord(alt = float(split[1]), az = float(split[2]), obstime = Time.now(), frame = 'altaz', unit="deg", location = self.mount.getObs()).icrs) elif lastBtn == 'KEY_OK': self.mount.Slew(SkyCoord(ra = float(split[1]), dec = float(split[2]), frame = 'icrs', unit="deg")) #now = Time.now() #altazframe = AltAz(obstime=now, location=self.mount.getObs()) #sunaltaz = get_sun(now).transform_to(altazframe) #print sunaltaz, altazframe, now #self.mount.Slew(SkyCoord(get_sun(Time.now()), location = self.mount.getObs()).icrs) if lastBtn == 'KEY_UP': dec += 10 self.mount.Slew(SkyCoord(ra = ra, dec=dec, unit="deg")) #self.mount.Slew(SkyCoord(alt = 45, az = 181+90, obstime = Time.now(), frame = 'altaz', unit="deg", location = self.mount.getObs()).icrs) # mode: -90 - 0 if lastBtn == 'KEY_DOWN': dec -= 10 self.mount.Slew(SkyCoord(ra = ra, dec=dec, unit="deg")) #self.mount.Slew(SkyCoord(alt = 45, az = 181+45, obstime = Time.now(), frame = 'altaz', unit="deg", location = self.mount.getObs()).icrs) # mode: -180 - -90 if lastBtn == 'KEY_LEFT': ra += 10 self.mount.Slew(SkyCoord(ra = ra, dec=dec, unit="deg")) #self.mount.Slew(SkyCoord(alt = 45, az = 181, obstime = Time.now(), frame = 'altaz', unit="deg", location = self.mount.getObs()).icrs) #mode: -90 - 0 if lastBtn == 'KEY_RIGHT': ra -= 10 self.mount.Slew(SkyCoord(ra = ra, dec=dec, unit="deg")) #self.mount.Slew(SkyCoord(alt = 1, az = 181+90, obstime = Time.now(), frame = 'altaz', unit="deg", location = self.mount.getObs()).icrs) #mode: -180 - -90 if lastBtn == 'KEY_MENU': self.mount.Slew(SkyCoord(alt = 1, az = 181+45, obstime = Time.now(), frame = 'altaz', unit="deg", location = self.mount.getObs()).icrs) if lastBtn == 'KEY_TAB': self.mount.Slew(SkyCoord(alt = 1, az = 181, obstime = Time.now(), frame = 'altaz', unit="deg", location = self.mount.getObs()).icrs) elif lastBtn == 'KEY_STOP' or lastBtn == 'home': self.mount.GoPark() elif lastBtn == 'KEY_PLAY': self.mount.UnPark() else: #(ra, dec) = self.mount.getCoordinates('RaDec') #print ra, dec #try: # mat = Float32MultiArray(data=[ra, dec]) # self.pub_radec.publish(mat) #except Exception, e: # print e #mat = Float32MultiArray(data=[ra, dec]) #mat.layout.dim.append(MultiArrayDimension()) #mat.layout.dim[0].label = "RaDec" #mat.layout.dim[0].size = 2 #mat.data. #print mat #self.pub_radec.publish(mat) pass except Exception, e: rospy.logerr(e) rate.sleep()
def find_opp_and_retro(self, start_time): cur_time = Time(start_time) last_RA = 0. last_dist = Distance(999, unit=units.au) pre_closest = True self.retrograding = False retro_start = None retro_end = None opptime = None # Earth location to use for calculating Mars' position. # Setting it to None will (I think? docs aren't clear) calculate # from the center of the Earth; this is much faster, skips # calculations like parallax due to earth's rotation, # and avoids seeing a lot of spurious retrograde/direct # transitions due solely to the observer's position changing # as the earth rotates. location = None # A place to store the data points self.planettrack = [] # When a planet is approaching opposition, its elongation is negative. # When it flips to positive (-180 to 180), it just passed opposition. # Can't check for exactly 180 if we're only checking time coarsely. last_elong = -1 # We'll look for the end of retrograde then go a few days # past it; but first, put a limit on how far we can go. end_time = cur_time + TimeDelta(300, format='jd') # Initially, go one day at a time: coarsemode = TimeDelta(1, format='jd') # but in fine mode, we'll go one hour at a time: finemode = TimeDelta(60*60, format='sec') # and near opposition we'll go even finer for a few days: superfinemode = TimeDelta(60 * 5, format='sec') timeslice = coarsemode while cur_time < end_time: cur_time += timeslice mars = get_body(planetname, cur_time) flags = '' # Are we starting or stopping retrograde? if ( (mars.ra == last_RA) or (mars.ra < last_RA and not self.retrograding) or (mars.ra > last_RA and self.retrograding) ): # Are we still in coarse mode? If so, jump back # in time a few days and go to fine mode. if timeslice == coarsemode: print("Switching to fine mode on", cur_time) print(" RA", mars.ra.hour, ", dec", mars.dec.degree) timeslice = finemode cur_time -= TimeDelta(EXTRA_DAYS, format='jd') continue # We're in fine mode. Record dates when the planet # starts or ends retrograde, hits opposition or makes # its closest approach. if self.retrograding: flags += END_RETROGRADE # Don't consider this the actual end of retrograde # unless we're already past opposition. # There are potentially a lot of false retrogrades. # We can get them from parallax if we calculate # Mars' position from a specific earth location; # but even if we don't, pyastro gives us a lot # of false little retrogrades and I don't know why. if opptime: retro_end = cur_time else: flags += START_RETROGRADE retro_start = cur_time if mars.ra == last_RA: flags += STATIONARY self.retrograding = not self.retrograding # Calculate elongation to find the opposition time: sun = get_body('sun', cur_time) elongation = (mars.ra - sun.ra).degree # print(cur_time, "\n RA", # mars.ra.hour, "dec", mars.dec.degree, # "elongation", elongation) if last_elong > 180. and elongation <= 180.: if timeslice == superfinemode: flags += OPPOSITION opptime = cur_time timeslice = finemode print("Opposition on", cur_time, ", switching back to fine") # XXX it would be nice not to go back to finemode # until after we've found closest approach. # But astropy randomly finds a closest approach # date weeks before the actual closest approach, # at the start of retrograde. else: # Looks like opposition. But let's go back a day and # get a finer view of the time. print("Switching to superfine mode on", cur_time) timeslice = superfinemode cur_time -= TimeDelta(1, format='jd') if mars.distance >= last_dist and pre_closest: flags += CLOSEST_APPROACH # self.find_parallax(cur_time) pre_closest = False elif mars.distance < last_dist: # receding pre_closest = True if flags or self.save_all_points: self.planettrack.append([cur_time.datetime, mars.ra.radian, mars.dec.radian, mars.distance.km, flags]) last_RA = mars.ra last_dist = mars.distance last_elong = elongation # If we've seen the opposition as well as retro_start and retro_end # then we're done. Switch back to coarse mode and record a # few more days. if timeslice == finemode and retro_start and retro_end and opptime: timeslice = coarsemode end_time = cur_time + TimeDelta(EXTRA_DAYS, format='jd') # We're done calculating all the points. # Now calculate the retrograde midpoint, if we have both start and end. if retro_start and retro_end: mid_retro_date = retro_start + (retro_end - retro_start) / 2 mars = get_body(planetname, mid_retro_date) # Insert that into our planettrack list: for i, point in enumerate(self.planettrack): if point[IDATE] == mid_retro_date: point[IFLAGS] += MIDPOINT_RETRO break elif point[IDATE] > mid_retro_date: self.planettrack.insert(i, [mid_retro_date.datetime, mars.ra.radian, mars.dec.radian, mars.distance.km, MIDPOINT_RETRO]) # We've just changed a list in the middle of looping # over that list, but it's okay because we're breaking out. break else: print("don't have both retro start and end") # Now print what we found. print("%20s %-19s %-11s %-10s %s" % ('', 'Date', 'RA', 'Dec', 'Dist (mi)')) for point in self.planettrack: if point[IFLAGS]: # print("%20s %-19s %-11s %-10s %d" % \ # (self.flags_to_string(point[4]), str(point[0]), # point[1], point[2], # point[3] * 9.2956e7)) print("%20s %-19s %-11.7f %-10.7f %d" % \ (self.flags_to_string(point[IFLAGS]), str(point[IDATE]), self.rads_to_hours(point[IRA]), self.rads_to_degrees(point[IDEC]), point[IDIST] / 1.609344))