我得到了一个 UTC 日期列表,所有时间都转换为 00:00。
我想确定某一天(即过去 24 小时)是否发生了(月食)日食
考虑python片段
from sykfield.api import load
eph = load('de421.bsp')
def eclipticangle(t):
moon, earth = eph['moon'], eph['earth']
e = earth.at(t)
x, y, _ = e.observe(moon).apparent().ecliptic_latlon()
return x.degrees
Run Code Online (Sandbox Code Playgroud)
我假设一个人能够确定日食是否在时间t的24 小时内发生
现在,就评论中的答案而言,仅通过测试角度是否接近 0 来解决第二个问题并不是那么简单。
因此,我的问题是
有人可以提供一个函数来确定月食是否发生在给定的第 t 天吗?
编辑。编辑此问题以反映 Brandon Rhodes 在下面评论中留下的反馈。
(lat, lon)
使用Skyfield将地球中心的距离映射到不同的位置,显示了纬度的变化,但与经度(亚毫米)无关.这可能是包中记录的近似值,我的脚本中的错误或完全不同的东西.我在这里做错了吗?(当然,除了使用喷射)
import numpy as np
import matplotlib.pyplot as plt
from skyfield.api import load, now
data = load('de421.bsp')
earth = data['earth']
jd = now()
epos = earth.at(jd).position.km
lats = np.linspace( -90, 90, 19)
lons = np.linspace(-180, 180, 37)
LATS, LONS = np.meshgrid(lats, lons)
s = LATS.shape
points = zip(LATS.flatten(), LONS.flatten())
rr = []
for point in points:
la, lo = point
pos = earth.topos(la, lo).at(jd).position.km
r = np.sqrt( ((pos-epos)**2).sum() )
rr.append(r)
surf = np.array(rr).reshape(s)
extent …
Run Code Online (Sandbox Code Playgroud) 我的问题是 PyEphem 为至日和分点的日期以及太阳几何提供准确结果的时间跨度是多少。
到目前为止,我在 GitHub https://github.com/brandon-rhodes/pyephem/issues/61上这篇非常翔实的帖子中发现了 BC 9998-03-20 到 AD 9999-12-31 的限制 以及结果的总体指示在当前任一地点移动超过 +/- 20,000 年时变得不稳定。
我想澄清这一点,因为我试图在更长的时间内获得太阳的位置 - 通常可以追溯到 10,000 年 BP - 以便计算来自太阳在给定的高度和方位角的入射太阳辐射地点。PyEphem 似乎提供了一个很好的替代方案,例如 Berger, 1978 (J. Atmosph. Sc., 35: 2362-2367)。对我来说,PyEphem 相对于这些算法的一个基本优势是它也可以跟踪时间,而地球轨道通常固定在上述算法中的某个特定时刻(例如,3 月 21 日的春分)。
通常,地球轨道的变化与 Berger 和其他人的算法是在最后一次冰川的规模上(高达 126,000 年 BP)进行评估的。在该范围内评估 PyEphem 时,当日期远早于今天时,我遇到了一些关于至日日期的奇怪行为:
import ephem
date= ephem.date((-59000,1,1))
orbitPoints= ['vernal_equinox_start','summer_solstice',\
'autumnal_equinox','winter_solstice','vernal_equinox_end']
dates= {}
dates['vernal_equinox_start']= ephem.next_vernal_equinox(date)
dates['summer_solstice']= ephem.next_summer_solstice(dates['vernal_equinox_start'])
dates['autumnal_equinox']= ephem.next_autumnal_equinox(dates['vernal_equinox_start'])
dates['winter_solstice']= ephem.next_winter_solstice(dates['vernal_equinox_start'])
dates['vernal_equinox_end']= ephem.next_vernal_equinox(dates['winter_solstice'])
for orbitPoint in orbitPoints:
date= dates[orbitPoint]
distance= body_distance(sun, date)
hlon, hlat= body_hpos(sun, date)
print '%-20s %30s …
Run Code Online (Sandbox Code Playgroud) 更新: Skyfield 刚刚进行了重大修订,包括扩展文档和角度分离方法 - 请参阅已接受的答案。
我正在使用Skyfield计算两个物体之间的表观角距。我没有在包中找到方法,所以我“发明”了一种通过计算两个视位置向量之间的点积的方法。
这是目前最好的方法吗?在Skyfield的范围内,它本质上是正确的吗?
def separation(seconds, lat, lon):
lat, lon, seconds = float(lat), float(lon), float(seconds) # necessary it seems
place = earth.topos(lat, lon)
jd = JulianDate(utc=(2016, 3, 9, 0, 0, seconds))
mpos = place.at(jd).observe(moon).apparent().position.km
spos = place.at(jd).observe(sun).apparent().position.km
mlen = np.sqrt((mpos**2).sum())
slen = np.sqrt((spos**2).sum())
sepa = ((3600.*180./np.pi) *
np.arccos(np.dot(mpos, spos)/(mlen*slen)))
return sepa
from skyfield.api import load, now, JulianDate
import numpy as np
from scipy.optimize import minimize
data = load('de421.bsp')
sun = data['sun']
earth = data['earth']
moon = …
Run Code Online (Sandbox Code Playgroud) 我需要使用或类似方法从 space-track.org传播最近的 TLE的整个目录(需要一个免费帐户才能查看)skyfield
。列表中通常有 15k-16k TLE。我有它的工作,但它很慢。在服务器上使用 46 个核心数小时。
没有结婚skyfield
。如果astropy
或pyephem
或其他东西更快,我很乐意接受一个答案,该答案表明我正在尝试使用它来做什么。
对于我的应用程序,我将 TLE 加载到 Pandas 数据框中并在那里进行分析,因此我将在 Pandas 世界中保留我的示例。最小的例子如下。
假设卫星目录保存为catalog.txt
,设置环境,然后读取 TLE,生成sf.sgp4lib.EarthSatellite
对象,并将所有内容加载到 Pandas 数据帧中。我们还将位置偏移到了一些观察点。我将选择一个观察点留给读者(0, 0, 0 就可以了):
import skyfield as sf
import pandas as pd
from skyfield.api import load, Topos
from datetime import datetime, timezone, timedelta
with open('catalog.txt', 'r') as f:
tle_list = [line.strip() for line in f.read().split('\n')
if line is not ''] …
Run Code Online (Sandbox Code Playgroud) scipy.optimize.minimize
使用默认方法将返回初始值作为结果,而不会出现任何错误或警告消息。在使用此答案建议的Nelder-Mead方法解决问题时,我想了解:
为什么默认方法会在不警告起点的情况下返回错误答案作为答案-并且 在这种情况下,有什么方法可以防止“没有警告就错误回答”避免这种情况?
请注意,该函数separation
使用python软件包Skyfield生成无法保证平滑的最小化值,这可能就是为什么Simplex在此处更好的原因。
结果:
测试结果:[ 2.14159739 ]'正确': 2.14159265359初始值:0.0
默认结果:[ 10000。 ]“正确”:13054初始值: 10000
Nelder-Mead结果:[ 13053.81011963 ]'正确': 13054初始值:10000
FULL OUTPUT using DEFAULT METHOD:
status: 0
success: True
njev: 1
nfev: 3
hess_inv: array([[1]])
fun: 1694.98753895812
x: array([ 10000.])
message: 'Optimization terminated successfully.'
jac: array([ 0.])
nit: 0
FULL OUTPUT using Nelder-Mead METHOD:
status: 0
nfev: 63
success: True
fun: 3.2179306044608054
x: array([ 13053.81011963])
message: 'Optimization terminated …
Run Code Online (Sandbox Code Playgroud) 使用此代码定义计算日出和日落的时间点:
t0 = ts.utc(2018, 9, 12, 4)
t1 = ts.utc(2018, 9, 13, 4)
Run Code Online (Sandbox Code Playgroud)
如果我只想使用一个(开始)日期并将下一个日期设置为恰好一天之后怎么办?我不能只在day
论点中添加一个,因为这在月底是不正确的。
使用 Pythondatetime
我可以使用
from datetime import datetime, timedelta
datetime(2019, 1, 31, 12) + timedelta(days=1)
# datetime.datetime(2019, 2, 1, 12, 0)
Run Code Online (Sandbox Code Playgroud)
但我timedelta
在 Skyfield API 文档中找不到任何类似的内容。
我正在尝试编写一个非常简单的程序,以千米为单位打印到任何行星的当前距离.我正在使用Skyfield.这是我的火星代码:
from skyfield.api import earth, mars, now
ra, dec, distance = earth(now()).observe(mars).radec()
print(distance)
Run Code Online (Sandbox Code Playgroud)
这将以天文单位打印出距离.为了转换为公里,我试图乘以149597871:
from skyfield.api import earth, mars, now
ra, dec, distance = earth(now()).observe(mars).radec()
print(distance*149597871)
Run Code Online (Sandbox Code Playgroud)
但是这会返回一个错误:
TypeError: unsupported operand type(s) for *: 'Distance' and 'int'
Run Code Online (Sandbox Code Playgroud)
我能做什么?
我正在尝试使用Skyfield绘制从地球到太阳系行星的距离作为时间的函数.这非常简单,甚至在包主页的首页中给出.然而,虽然这对汞,金星和火星非常有效,但它对其他行星不起作用.我不熟悉JPL星历文件,但似乎例如Jupiter在de421.bsp文件中没有密钥条目,这可以解释这个问题.
这是一个最小的例子(来自主页的那个):
from skyfield.api import load, now
planets = load('de421.bsp')
earth, planet = planets['earth'], planets['jupiter']
jd = now()
position = earth.at(jd).observe(planet)
ra, dec, distance = position.radec()
print(distance)
Run Code Online (Sandbox Code Playgroud)
错误如下.请注意,如果您在上面的代码中将'jupiter'替换为'mars',它就不会崩溃.
----> earth, planet = planets['earth'], planets['jupiter']
KeyError: "kernel 'de421.bsp' is missing 'JUPITER' - the targets it supports are:
SOLAR SYSTEM BARYCENTER, MERCURY BARYCENTER, VENUS BARYCENTER, EARTH BARYCENTER,
MARS BARYCENTER, JUPITER BARYCENTER, SATURN BARYCENTER, URANUS BARYCENTER,
NEPTUNE BARYCENTER, PLUTO BARYCENTER, SUN, MERCURY, VENUS, MOON, EARTH, MARS"
Run Code Online (Sandbox Code Playgroud)
我是以错误的方式使用星历文件(错误的重心?)还是这只是de421.bsp文件的限制?我在Skyfield网站(这里)上阅读了星历文件的描述,但不确定我是否完全理解它.
有关如何使用Skyfield进行地球 - 木星距离简单计算的任何建议吗?
谢谢 …
我将如何计算 EarthSatellite 下方的面积,以便我可以绘制卫星经过时覆盖的土地面积?
Skyfield 有什么东西可以促进这一点吗?
编辑:只是想我会澄清我所说的卫星下方区域的意思。鉴于地球是一个球体,我需要绘制卫星下方可能观察到的最大区域。我知道如何绘制卫星路径,但现在我需要绘制一些线来表示该卫星在地球上空飞行时可见的区域。
我有一个函数,可以返回给定位置的日出,日落,太阳正午和黄昏时间。该函数使用pyephem,由于不推荐使用,我想我会重新编写该函数以使用skyfield。然而,skyfield不具备的功能.previous_rising
,.next_setting
或.next_transit
(至少,我找不到它们),这是我与pyephem使用。
skyfield确实具有function find_discrete
,它将在给定时间之间进行搜索以查找函数何时发生更改,因此我编写了以下代码进行测试:
from datetime import datetime, timedelta
from skyfield import api, almanac
import pytz
ts = api.load.timescale()
planets = api.load('de421.bsp')
sun, earth = planets['sun'], planets['earth']
lat, lon = '44.59028 N', '104.71528 W' # UFO Mooring Site
tzn, elv = 'US/Mountain', 1559
tz = pytz.timezone(tzn)
loc = api.Topos(lat, lon, elevation_m=elv)
earth_loc = earth + loc
def civil_twil(time):
"returns true/false if sun is above -6 degrees"
alt, az, dis = earth_loc.at(time).observe(sun).apparent().altaz()
return …
Run Code Online (Sandbox Code Playgroud)