Skip to content

Commit d0e5e20

Browse files
committed
Merge branch 'develop' into new_release
2 parents 71fcc7b + 0713f1e commit d0e5e20

13 files changed

+316
-174
lines changed

.github/ISSUE_TEMPLATE.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#### Code Sample, a minimal, complete, and verifiable piece of code
2+
3+
```python
4+
# Your code here
5+
6+
```
7+
#### Problem description
8+
9+
[this should also explain **why** the current behaviour is a problem and why the
10+
expected output is a better solution.]
11+
12+
#### Expected Output
13+
14+
#### Actual Result, Traceback if applicable
15+
16+
#### Versions of Python, package at hand and relevant dependencies
17+
18+
Thank you for reporting an issue !

.github/PULL_REQUEST_TEMPLATE.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!-- Please make the PR against the `develop` branch. -->
2+
3+
<!-- Describe what your PR does, and why -->
4+
5+
- [ ] Closes #xxxx <!-- remove if there is no corresponding issue, which should only be the case for minor changes -->
6+
- [ ] Tests added <!-- for all bug fixes or enhancements -->
7+
- [ ] Tests passed <!-- for all non-documentation changes) -->
8+
- [ ] Passes ``git diff origin/develop **/*py | flake8 --diff`` <!-- remove if you did not edit any Python files -->
9+
- [ ] Fully documented <!-- remove if this change should not be visible to users, e.g., if it is an internal clean-up, or if this is part of a larger project that will be documented later -->

doc/source/index.rst

+32-4
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,43 @@ The orbital module enables computation of satellite position and velocity at a s
2727

2828
>>> from pyorbital.orbital import Orbital
2929
>>> from datetime import datetime
30-
>>> orb = Orbital("noaa 18")
30+
>>> # Use current TLEs from the internet:
31+
>>> orb = Orbital("Suomi NPP")
3132
>>> now = datetime.utcnow()
3233
>>> # Get normalized position and velocity of the satellite:
3334
>>> orb.get_position(now)
34-
([0.57529384846822862, 0.77384005228105424, 0.59301408257897559],
35-
[0.031846489698768146, 0.021287993461926374, -0.05854106186659274])
35+
(array([-0.20015267, 0.09001458, 1.10686756]),
36+
array([ 0.06148495, 0.03234914, 0.00846805]))
3637
>>> # Get longitude, latitude and altitude of the satellite:
3738
>>> orb.get_lonlatalt(now)
38-
(-1.1625895579622014, 0.55402132517640568, 847.89381184656702)
39+
(40.374855865574951, 78.849923885700363, 839.62504115338368)
40+
41+
42+
Use actual TLEs to increase accuracy
43+
------------------------------------
44+
45+
>>> from pyorbital.orbital import Orbital
46+
>>> from datetime import datetime
47+
>>> orb = Orbital("Suomi NPP")
48+
>>> dtobj = datetime(2015,2,7,3,0)
49+
>>> orb.get_lonlatalt(dtobj)
50+
(152.11564698762811, 20.475251739329622, 829.37355785502211)
51+
52+
But since we are interesting knowing the position of the Suomi-NPP more than
53+
two and half years from now (September 26, 2017) we can not rely on the current
54+
TLEs, but rather need a TLE closer to the time of interest:
55+
56+
>>> snpp = Orbital('Suomi NPP', tle_file='/data/lang/satellit/polar/orbital_elements/TLE/201502/tle-20150207.txt')
57+
>>> snpp.get_lonlatalt(dtobj)
58+
(105.37373804512762, 79.160752404540133, 838.94605490133154)
59+
60+
If we take a TLE from one week earlier we get a slightly different result:
61+
62+
>>> snpp = Orbital('Suomi NPP', tle_file='/data/lang/satellit/polar/orbital_elements/TLE/201501/tle-20150131.txt')
63+
>>> snpp.get_lonlatalt(dtobj)
64+
(104.1539184988462, 79.328272480878141, 838.81555967963391)
65+
66+
3967

4068
Computing astronomical parameters
4169
---------------------------------

etc/platforms.txt

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ GOES-16 41866
3333
Himawari-6 28622
3434
Himawari-7 28937
3535
Himawari-8 40267
36+
Himawari-9 41836
3637
INSAT-3A 27714
3738
INSAT-3C 27298
3839
INSAT-3D 39216

pyorbital/__init__.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Copyright (c) 2017
4+
5+
# Author(s):
6+
7+
# Martin Raspaud <[email protected]>
8+
9+
# This program is free software: you can redistribute it and/or modify
10+
# it under the terms of the GNU General Public License as published by
11+
# the Free Software Foundation, either version 3 of the License, or
12+
# (at your option) any later version.
13+
14+
# This program is distributed in the hope that it will be useful,
15+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
# GNU General Public License for more details.
18+
19+
# You should have received a copy of the GNU General Public License
20+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
22+
import numpy as np
23+
24+
25+
def dt2np(utc_time):
26+
try:
27+
return np.datetime64(utc_time)
28+
except ValueError:
29+
return utc_time.astype('datetime64[ns]')

pyorbital/astronomy.py

+34-38
Original file line numberDiff line numberDiff line change
@@ -24,46 +24,36 @@
2424
Parts taken from http://www.geoastro.de/elevaz/basics/index.htm
2525
"""
2626

27-
import datetime
2827
import numpy as np
2928

29+
from pyorbital import dt2np
30+
31+
F = 1 / 298.257223563 # Earth flattening WGS-84
32+
A = 6378.137 # WGS84 Equatorial radius
33+
MFACTOR = 7.292115E-5
3034

31-
F = 1 / 298.257223563 # Earth flattening WGS-84
32-
A = 6378.137 # WGS84 Equatorial radius
33-
MFACTOR = 7.292115E-5
3435

3536
def jdays2000(utc_time):
3637
"""Get the days since year 2000.
3738
"""
38-
return _days(utc_time - datetime.datetime(2000, 1, 1, 12, 0))
39-
39+
return _days(dt2np(utc_time) - np.datetime64('2000-01-01T12:00'))
40+
4041

4142
def jdays(utc_time):
4243
"""Get the julian day of *utc_time*.
4344
"""
4445
return jdays2000(utc_time) + 2451545
4546

46-
def _fdays(dt):
47-
"""Get the days (floating point) from *d_t*.
48-
"""
49-
return (dt.days +
50-
(dt.seconds +
51-
dt.microseconds / (1000000.0)) / (24 * 3600.0))
52-
53-
_vdays = np.vectorize(_fdays)
5447

5548
def _days(dt):
5649
"""Get the days (floating point) from *d_t*.
5750
"""
58-
try:
59-
return _fdays(dt)
60-
except AttributeError:
61-
return _vdays(dt)
51+
return dt / np.timedelta64(1, 'D')
6252

6353

6454
def gmst(utc_time):
6555
"""Greenwich mean sidereal utc_time, in radians.
66-
56+
6757
As defined in the AIAA 2006 implementation:
6858
http://www.celestrak.com/publications/AIAA/2006-6753/
6959
"""
@@ -86,24 +76,25 @@ def sun_ecliptic_longitude(utc_time):
8676
jdate = jdays2000(utc_time) / 36525.0
8777
# mean anomaly, rad
8878
m_a = np.deg2rad(357.52910 +
89-
35999.05030*jdate -
90-
0.0001559*jdate*jdate -
91-
0.00000048*jdate*jdate*jdate)
79+
35999.05030 * jdate -
80+
0.0001559 * jdate * jdate -
81+
0.00000048 * jdate * jdate * jdate)
9282
# mean longitude, deg
93-
l_0 = 280.46645 + 36000.76983*jdate + 0.0003032*jdate*jdate
94-
d_l = ((1.914600 - 0.004817*jdate - 0.000014*jdate*jdate)*np.sin(m_a) +
95-
(0.019993 - 0.000101*jdate)*np.sin(2*m_a) + 0.000290*np.sin(3*m_a))
83+
l_0 = 280.46645 + 36000.76983 * jdate + 0.0003032 * jdate * jdate
84+
d_l = ((1.914600 - 0.004817 * jdate - 0.000014 * jdate * jdate) * np.sin(m_a) +
85+
(0.019993 - 0.000101 * jdate) * np.sin(2 * m_a) + 0.000290 * np.sin(3 * m_a))
9686
# true longitude, deg
9787
l__ = l_0 + d_l
9888
return np.deg2rad(l__)
9989

90+
10091
def sun_ra_dec(utc_time):
10192
"""Right ascension and declination of the sun at *utc_time*.
10293
"""
10394
jdate = jdays2000(utc_time) / 36525.0
104-
eps = np.deg2rad(23.0 + 26.0/60.0 + 21.448/3600.0 -
105-
(46.8150*jdate + 0.00059*jdate*jdate -
106-
0.001813*jdate*jdate*jdate) / 3600)
95+
eps = np.deg2rad(23.0 + 26.0 / 60.0 + 21.448 / 3600.0 -
96+
(46.8150 * jdate + 0.00059 * jdate * jdate -
97+
0.001813 * jdate * jdate * jdate) / 3600)
10798
eclon = sun_ecliptic_longitude(utc_time)
10899
x__ = np.cos(eclon)
109100
y__ = np.cos(eps) * np.sin(eclon)
@@ -115,13 +106,15 @@ def sun_ra_dec(utc_time):
115106
right_ascension = 2 * np.arctan2(y__, (x__ + r__))
116107
return right_ascension, declination
117108

109+
118110
def _local_hour_angle(utc_time, longitude, right_ascension):
119111
"""Hour angle at *utc_time* for the given *longitude* and
120112
*right_ascension*
121113
longitude in radians
122114
"""
123115
return _lmst(utc_time, longitude) - right_ascension
124116

117+
125118
def get_alt_az(utc_time, lon, lat):
126119
"""Return sun altitude and azimuth from *utc_time*, *lon*, and *lat*.
127120
lon,lat in degrees
@@ -132,10 +125,11 @@ def get_alt_az(utc_time, lon, lat):
132125

133126
ra_, dec = sun_ra_dec(utc_time)
134127
h__ = _local_hour_angle(utc_time, lon, ra_)
135-
return (np.arcsin(np.sin(lat)*np.sin(dec) +
128+
return (np.arcsin(np.sin(lat) * np.sin(dec) +
136129
np.cos(lat) * np.cos(dec) * np.cos(h__)),
137-
np.arctan2(-np.sin(h__), (np.cos(lat)*np.tan(dec) -
138-
np.sin(lat)*np.cos(h__))))
130+
np.arctan2(-np.sin(h__), (np.cos(lat) * np.tan(dec) -
131+
np.sin(lat) * np.cos(h__))))
132+
139133

140134
def cos_zen(utc_time, lon, lat):
141135
"""Cosine of the sun-zenith angle for *lon*, *lat* at *utc_time*.
@@ -147,7 +141,8 @@ def cos_zen(utc_time, lon, lat):
147141

148142
r_a, dec = sun_ra_dec(utc_time)
149143
h__ = _local_hour_angle(utc_time, lon, r_a)
150-
return (np.sin(lat)*np.sin(dec) + np.cos(lat) * np.cos(dec) * np.cos(h__))
144+
return (np.sin(lat) * np.sin(dec) + np.cos(lat) * np.cos(dec) * np.cos(h__))
145+
151146

152147
def sun_zenith_angle(utc_time, lon, lat):
153148
"""Sun-zenith angle for *lon*, *lat* at *utc_time*.
@@ -156,6 +151,7 @@ def sun_zenith_angle(utc_time, lon, lat):
156151
"""
157152
return np.rad2deg(np.arccos(cos_zen(utc_time, lon, lat)))
158153

154+
159155
def sun_earth_distance_correction(utc_time):
160156
"""Calculate the sun earth distance correction, relative to 1 AU.
161157
"""
@@ -170,19 +166,20 @@ def sun_earth_distance_correction(utc_time):
170166
# corr_me = (r / AU) ** 2
171167

172168
# from known software.
173-
corr = 1 - 0.0334 * np.cos(2 * np.pi * (jdays2000(utc_time) - 2) / year)
169+
corr = 1 - 0.0334 * np.cos(2 * np.pi * (jdays2000(utc_time) - 2) / year)
174170

175171
return corr
176172

173+
177174
def observer_position(time, lon, lat, alt):
178175
"""Calculate observer ECI position.
179176
180177
http://celestrak.com/columns/v02n03/
181178
"""
182-
179+
183180
lon = np.deg2rad(lon)
184181
lat = np.deg2rad(lat)
185-
182+
186183
theta = (gmst(time) + lon) % (2 * np.pi)
187184
c = 1 / np.sqrt(1 + F * (F - 2) * np.sin(lat)**2)
188185
sq = c * (1 - F)**2
@@ -192,9 +189,8 @@ def observer_position(time, lon, lat, alt):
192189
y = achcp * np.sin(theta)
193190
z = (A * sq + alt) * np.sin(lat)
194191

195-
vx = -MFACTOR*y # kilometers/second
196-
vy = MFACTOR*x
192+
vx = -MFACTOR * y # kilometers/second
193+
vy = MFACTOR * x
197194
vz = 0
198195

199196
return (x, y, z), (vx, vy, vz)
200-

0 commit comments

Comments
 (0)