Pyephem - Degree position of planets - pyephem

Done some searching and can't find a direct answer (well, one that i can understand!)
I want to compute the degree (out of 360 degrees) that the planets (Sun through to Pluto) are at a given time and location. I have the below code. I want to compute Zero degrees as the ascendent and progress from there.
pic of chart for date, time, location. AS = 0 Degrees, Jup = circa 43 degrees, Sat = circa 93 degrees, etc...
Astro Chart for Date, Time & Location
Many thanks, Will
>>> from ephem import *
>>> sun = Sun()
>>> moo = Moon()
>>> mer = Mercury()
>>> mar = Mars()
>>> ven = Venus()
>>> jup = Jupiter()
>>> sat = Saturn()
>>> plu = Pluto()
>>> northwich = Observer()
>>> northwich.lat = '53.15'
>>> northwich.lon = '02.31'
>>> northwich.elevation = 36
>>> northwich.date = '2018/7/30 10:56'
>>> sun.compute(northwich)
>>> moo.compute(northwich)
>>> mer.compute(northwich)
>>> mar.compute(northwich)
>>> ven.compute(northwich)
>>> jup.compute(northwich)
>>> sat.compute(northwich)
>>> plu.compute(northwich)
>>> print(sun.alt, sun.az, moo.alt, moo.az... etc

Related

Migrating from basemap to cartopy - coordinates offset?

I was happy with basemap showing some points of interest I have visited, but since basemap is dead, I am moving over to cartopy.
So far so good, I have transferred all the map features (country borders, etc.) without major problems, but I have noticed my points of interest are shifted a bit to North-East in cartopy.
Minimal example from the old basemap (showing two points of interest on the Germany-Czech border):
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
map = Basemap(projection='merc', epsg='3395',
llcrnrlon = 11.5, urcrnrlon = 12.5,
llcrnrlat = 50, urcrnrlat = 50.7,
resolution = 'f')
map.fillcontinents(color='Bisque',lake_color='LightSkyBlue')
map.drawcountries(linewidth=0.2)
lats = [50.3182289, 50.2523744]
lons = [12.1010486, 12.0906336]
x, y = map(lons, lats)
map.plot(x, y, marker = '.', markersize=1, mfc = 'red', mew = 1, mec = 'red', ls = 'None')
plt.savefig('example-basemap.png', dpi=200, bbox_inches='tight', pad_inches=0)
And the same example from cartopy - both points are slightly shifted to North-East as can be verified also e.g. via google maps:
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
ax = plt.axes(projection=ccrs.Mercator())
ax.set_extent([11.5, 12.5, 50, 50.7])
ax.add_feature(cfeature.LAND.with_scale('10m'), color='Bisque')
ax.add_feature(cfeature.LAKES.with_scale('10m'), alpha=0.5)
ax.add_feature(cfeature.BORDERS.with_scale('10m'), linewidth=0.2)
lats = [50.3182289, 50.2523744]
lons = [12.1010486, 12.0906336]
ax.plot(lons, lats, transform=ccrs.Geodetic(),
marker = '.', markersize=1, mfc = 'red', mew = 1, mec = 'red', ls = 'None')
plt.savefig('cartopy.png', dpi=200, bbox_inches='tight', pad_inches=0)
Any idea how to get cartopy plot the points on expected coordinates? Tried cartopy 0.18 and 0.20 with the same result.

Kolmogorov-Smirnov Test Statistic

Can someone explain why, if I calculate manually the KS test statistic, the result is different from when I use scipy.stats.kstest?
>>> sample = np.array([1000,2000,2500,3000,5000])
>>> ecdf = np.array([0.2, 0.4, 0.6, 0.8, 1. ])
>>> cdf = stats.weibull_min(0.3, 100, 4000).cdf(sample)
>>> abs(ecdf - cdf).max()
0.3454961536273503
>>> stats.kstest(rvs=sample, cdf=stats.weibull_min(0.3, 100, 4000).cdf)
KstestResult(statistic=0.4722995454382698, pvalue=0.1534647709785294)
OK, I realized the mistake I made, so I will answer my onwn question. The KS-Statistic can't be calculated as abs(ecdf - cdf).max(), bacause of the right-continuity / left-discontinuity of the ECDF. The correct approach is:
>>> sample = np.array([1000, 2000, 2500, 3000, 5000])
>>> ecdf = np.array([0, 0.2, 0.4, 0.6, 0.8, 1. ])
>>> cdf = stats.weibull_min(0.3, 100, 4000).cdf(sample)
>>> max([(ecdf[1:] - cdf).max(), (cdf - ecdf[:-1]).max()])
0.4722995454382698

in Ipython a function named display gives me an error

# Kepler's Laws.py
# plots the orbit of a planet in an eccentric orbit to illustrate
# the sweeping out of equal areas in equal times, with sun at focus
# The eccentricity of the orbit is random and determined by the initial velocity
# program uses normalised units (G =1)
# program by Peter Borcherds, University of Birmingham, England
from vpython import *
from random import random
from IPython import display
import pandas as pd
def MonthStep(time, offset=20, whole=1): # mark the end of each "month"
global ccolor # have to make it global, since label uses it before it is updated
if whole:
Ltext = str(int(time * 2 + dt)) # end of 'month', printing twice time gives about 12 'months' in 'year'
else:
Ltext = duration + str(time * 2) + ' "months"\n Initial speed: ' + str(round(speed, 3))
ccolor = color.white
label(pos=planet.pos, text=Ltext, color=ccolor,
xoffset=offset * planet.pos.x, yoffset=offset * planet.pos.y)
ccolor = (0.5 * (1 + random()), random(), random()) # randomise colour of radial vector
return ccolor
scene = display(title="Kepler's law of equal areas", width=1000, height=1000, range=3.2)
duration = 'Period: '
sun = sphere(color=color.yellow, radius=0.1) # motion of sun is ignored (or centre of mass coordinates)
scale = 1.0
poss = vector(0, scale, 0)
planet = sphere(pos=poss, color=color.cyan, radius=0.02)
while 1:
velocity = -vector(0.7 + 0.5 * random(), 0, 0) # gives a satisfactory range of eccentricities
##velocity = -vector(0.984,0,0) # gives period of 12.0 "months"
speed = mag(velocity)
steps = 20
dt = 0.5 / float(steps)
step = 0
time = 0
ccolor = color.white
oldpos = vector(planet.pos)
ccolor = MonthStep(time)
curve(pos=[sun.pos, planet.pos], color=ccolor)
while not (oldpos.x > 0 and planet.pos.x < 0):
rate(steps * 2) # keep rate down so that development of orbit can be followed
time += dt
oldpos = vector(planet.pos) # construction vector(planet.pos) makes oldpos a varible in its own right
# oldpos = planet.pos makes "oldposs" point to "planet.pos"
# oldposs = planet.pos[:] does not work, because vector does not permit slicing
denom = mag(planet.pos) ** 3
velocity -= planet.pos * dt / denom # inverse square law; force points toward sun
planet.pos += velocity * dt
# plot orbit
curve(pos=[oldpos, planet.pos], color=color.red)
step += 1
if step == steps:
step = 0
ccolor = MonthStep(time)
curve(pos=[sun.pos, planet.pos], color=color.white)
else:
# plot radius vector
curve(pos=[sun.pos, planet.pos], color=ccolor)
if scene.kb.keys:
print
"key pressed"
duration = 'Duration: '
break
MonthStep(time, 50, 0)
label(pos=(2.5, -2.5, 0), text='Click for another orbit')
scene.mouse.getclick()
for obj in scene.objects:
if obj is sun or obj is planet: continue
obj.visible = 0 # clear the screen to do it again
I copied Kepler's Laws code in google and compiled it on pycharm.
But there is an error that
scene = display(title="Kepler's law of equal areas", width=1000, height=1000, range=3.2)
TypeError: 'module' object is not callable
I found some information on google that "pandas" library can improve this error so I tried it but I can't improve this error.
What should I do?
Replace "display" with "canvas", which is the correct name of this entity.

how can i calculate distances with pyephem?

hi i need a little help if any of you know how to calculate the distance of a coordinates and a satellite projection, i mean, when i predict the path of the satellite i need to know what is the distance between the future path and the coordinates that i put. and with that make a message alert notifiyng me when that satellite will be close to the coordinates.
this is the code that i am using any of you could help me that would be great.
from mpl_toolkits.basemap import Basemap
from geopy.distance import great_circle
from matplotlib import colors
from pyorbital import tlefile
import matplotlib.pyplot as plt
import numpy as np
import math
import ephem
from datetime import datetime
tlefile.TLE_URLS = ( 'http://celestrak.com/NORAD/elements/resource.txt',)
sat_tle = tlefile.read('NUSAT 1 (FRESCO)')
sat = ephem.readtle("NUSAT 1 (FRESCO)", sat_tle.line1, sat_tle.line2)
obs = ephem.Observer()
# location for tge coordinates
print("Latitud ")
sat_lat = input()
print("Longitud suggested point")
sat_lon = input()
obs.lat = str(sat_lat)
obs.long = str(sat_lon)
# programar proyeccion del mapa
map = Basemap(projection='ortho', lat_0=sat_lat, lon_0=sat_lon, resolution='l')
# draw coastlines, country boundaries, fill continents.
map.drawcoastlines(linewidth=0.25)
map.drawcountries(linewidth=0.25)
map.fillcontinents(color='coral',lake_color='aqua')
# draw the edge of the map projection region (the projection limb)
map.drawmapboundary(fill_color='aqua')
# grid in latitud and longitud every 30 sec.
map.drawmeridians(np.arange(0,360,30))
map.drawparallels(np.arange(-90,90,30))
# plot
passes = 4
for p in range(passes):
coords = []
dists = []
tr, azr, tt, altt, ts, azs = obs.next_pass(sat)
print """Date/Time (UTC) Alt/Azim Lat/Long Elev"""
print """====================================================="""
while tr < ts:
obs.date = tr
sat.compute(obs)
print "%s | %4.1f %5.1f | %4.1f %+6.1f | %5.1f" % \
(tr, math.degrees(sat.alt), math.degrees(sat.az), math.degrees(sat.sublat), math.degrees(sat.sublong), sat.elevation/1000.)
sat_lat = math.degrees(sat.sublat)
sat_lon = math.degrees(sat.sublong)
dist = great_circle((sat_lat, sat_lon), (sat_lat, sat_lon)).miles
coords.append([sat_lon, sat_lat])
dists.append(dist)
tr = ephem.Date(tr + 30.0 * ephem.second)
md = min(dists)
imd = 1 - (float(md) / 1400)
hue = float(240) / float(360)
clr = colors.hsv_to_rgb([hue, imd, 1])
map.drawgreatcircle(coords[0][0], coords[0][1], coords[-1][0], coords[-1][1], linewidth=2, color=clr)
obs.date = tr + ephem.minute
# map with UTC
date = datetime.utcnow()
cs=map.nightshade(date)
plt.title('next '+ str(passes)+ ' passes of the satellite')
plt.show()
You might want to look at http://rhodesmill.org/pyephem/quick.html#other-functions where it describes the function ephem.separation(). You are allowed to call it with two longitude, latitude coordinate pairs, and it will tell you how far apart they are:
ephem.separation((lon1, lat1), (lon2, lat2))
So if you pass the satellites's longitude and latitude as one of the coordinate pairs, and the longitude and latitude of the position you are interested in as the other, then you can watch for when the separation grows very small.

Pymunk body's shapes don't rotate when I rotate the body

In Pymunk, when I rotate a body, its shapes are not rotating. When I apply an impulse, the shapes move in sync, as expected. My google searches indicate that the body's shapes should be rotating when the body rotates. Am I fundamentally misunderstanding rotation?
Here is the relevant rotation code:
def selectEntity(self, location):
shapes = self.space.point_query(location)
bodies = set()
for shape in shapes:
bodies.add(shape.body)
for body in bodies:
body.angle += 1.57079633 # + 90 degrees
Here is the initialization code:
def _addShip(self, mass, center, angle = 0.):
radius = 10
groupId = self.getNextBodyId() # shapes in the same group do not generate collisions
body = pymunk.Body(mass, pymunk.moment_for_circle(mass, radius / 10, radius)) # mass, inner radius, outer radius, offset
body.angle = angle
partOne = pymunk.Circle(body, radius, center)
partOne.group = groupId
partOne.color = THECOLORS['blue']
partOne.friction = .8
partTwo = pymunk.Circle(body, radius, (center[0], center[1] + 20))
partTwo.group = groupId
partTwo.color = THECOLORS['blue']
partTwo.friction = .8
ship = (partOne, partTwo, body)
self.space.add(*ship)
The collision tree/hash is not updated immediately, you need to step the space forward first. Another way to update the collision data is to call Space.reindex_shape(shape_that_has_been_moved).
See this Example:
>>> from pymunk import *
>>> s = Space()
>>> b = Body(1,1)
>>> c1 = Circle(b, 10, (-10,0))
>>> c2 = Circle(b, 10, (10,0))
>>> s.add(b,c1,c2)
>>> s.step(.1)
>>> s.point_query((-15,0))
[<pymunk.Circle object at 0x02264690>]
>>> b.angle
0.0
>>> b.angle = 1.57
>>> s.point_query((-15,0))
[<pymunk.Circle object at 0x02264690>]
>>> s.step(.1)
>>> s.point_query((-15,0))
[]
>>> s.point_query((0,-15))
[<pymunk.Circle object at 0x02264690>]
>>> b.angle = 0
>>> s.point_query((-15,0))
[]
>>> s.reindex_shape(c1)
>>> s.reindex_shape(c2)
>>> s.point_query((-15,0))
[<pymunk.Circle object at 0x02264690>]