Skip to content

Commit a8a90ae

Browse files
committed
eci: astropy optional, but with substantial error tolerance
v2.4.1
1 parent 81540a2 commit a8a90ae

File tree

12 files changed

+221
-141
lines changed

12 files changed

+221
-141
lines changed

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = pymap3d
3-
version = 2.4.0
3+
version = 2.4.1
44
author = Michael Hirsch, Ph.D.
55
author_email = [email protected]
66
description = pure Python (no prereqs) coordinate conversions, following convention of several popular Matlab routines.

src/pymap3d/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from .enu import enu2geodetic, geodetic2enu, aer2enu, enu2aer
3737
from .ned import ned2ecef, ned2geodetic, geodetic2ned, ecef2nedv, ned2aer, aer2ned, ecef2ned
3838
from .ecef import geodetic2ecef, ecef2geodetic, eci2geodetic, geodetic2eci, ecef2enuv, enu2ecef, ecef2enu, enu2uvw, uvw2enu
39-
from .sidereal import datetime2sidereal
39+
from .sidereal import datetime2sidereal, greenwichsrt
4040
from .latitude import (
4141
geod2geoc,
4242
geoc2geod,
@@ -66,9 +66,9 @@
6666
from .lox import meridian_arc, meridian_dist, loxodrome_inverse, loxodrome_direct, departure, meanm
6767
from .los import lookAtSpheroid
6868
from .timeconv import str2dt
69+
from .eci import eci2ecef, ecef2eci
6970

7071
try:
7172
from .azelradec import radec2azel, azel2radec
72-
from .eci import eci2ecef, ecef2eci
7373
except ImportError:
7474
from .vallado import radec2azel, azel2radec

src/pymap3d/aer.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
from .enu import geodetic2enu, aer2enu, enu2aer
77
from .ellipsoid import Ellipsoid
88

9-
try:
10-
from .eci import eci2ecef, ecef2eci
11-
except ImportError:
12-
eci2ecef = ecef2eci = None
9+
from .eci import eci2ecef, ecef2eci
10+
1311

1412
__all__ = ["aer2ecef", "ecef2aer", "geodetic2aer", "aer2geodetic", "eci2aer", "aer2eci"]
1513

@@ -165,7 +163,16 @@ def aer2geodetic(
165163

166164

167165
def eci2aer(
168-
x: "ndarray", y: "ndarray", z: "ndarray", lat0: "ndarray", lon0: "ndarray", h0: "ndarray", t: datetime
166+
x: "ndarray",
167+
y: "ndarray",
168+
z: "ndarray",
169+
lat0: "ndarray",
170+
lon0: "ndarray",
171+
h0: "ndarray",
172+
t: datetime,
173+
*,
174+
deg: bool = True,
175+
use_astropy: bool = True
169176
) -> typing.Tuple["ndarray", "ndarray", "ndarray"]:
170177
"""
171178
takes Earth Centered Inertial x,y,z ECI coordinates of point and gives az, el, slant range from Observer
@@ -187,6 +194,10 @@ def eci2aer(
187194
observer altitude above geodetic ellipsoid (meters)
188195
t : datetime.datetime
189196
Observation time
197+
deg : bool, optional
198+
true: degrees, false: radians
199+
use_astropy: bool, optional
200+
use Astropy (recommended)
190201
191202
Returns
192203
-------
@@ -197,12 +208,10 @@ def eci2aer(
197208
srange : "ndarray"
198209
slant range [meters]
199210
"""
200-
if eci2ecef is None:
201-
raise ImportError("pip install astropy")
202211

203-
xecef, yecef, zecef = eci2ecef(x, y, z, t)
212+
xecef, yecef, zecef = eci2ecef(x, y, z, t, use_astropy=use_astropy)
204213

205-
return ecef2aer(xecef, yecef, zecef, lat0, lon0, h0)
214+
return ecef2aer(xecef, yecef, zecef, lat0, lon0, h0, deg=deg)
206215

207216

208217
def aer2eci(
@@ -214,7 +223,9 @@ def aer2eci(
214223
h0: "ndarray",
215224
t: datetime,
216225
ell=None,
226+
*,
217227
deg: bool = True,
228+
use_astropy: bool = True
218229
) -> typing.Tuple["ndarray", "ndarray", "ndarray"]:
219230
"""
220231
gives ECI of a point from an observer at az, el, slant range
@@ -239,6 +250,8 @@ def aer2eci(
239250
reference ellipsoid
240251
deg : bool, optional
241252
degrees input/output (False: radians in/out)
253+
use_astropy : bool, optional
254+
use AstroPy (recommended)
242255
243256
Returns
244257
-------
@@ -252,12 +265,9 @@ def aer2eci(
252265
z : "ndarray"
253266
ECEF z coordinate (meters)
254267
"""
255-
if ecef2eci is None:
256-
raise ImportError("pip install numpy")
257-
258-
x, y, z = aer2ecef(az, el, srange, lat0, lon0, h0, ell, deg)
268+
x, y, z = aer2ecef(az, el, srange, lat0, lon0, h0, ell, deg=deg)
259269

260-
return ecef2eci(x, y, z, t)
270+
return ecef2eci(x, y, z, t, use_astropy=use_astropy)
261271

262272

263273
def aer2ecef(

src/pymap3d/azelradec.py

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121

2222
def azel2radec(
23-
az_deg: "ndarray", el_deg: "ndarray", lat_deg: "ndarray", lon_deg: "ndarray", time: datetime, usevallado: bool = False
23+
az_deg: "ndarray", el_deg: "ndarray", lat_deg: "ndarray", lon_deg: "ndarray", time: datetime, *, use_astropy: bool = True
2424
) -> typing.Tuple["ndarray", "ndarray"]:
2525
"""
2626
viewing angle (az, el) to sky coordinates (ra, dec)
@@ -37,8 +37,8 @@ def azel2radec(
3737
observer longitude [-180, 180] (degrees)
3838
time : datetime.datetime or str
3939
time of observation
40-
usevallado : bool, optional
41-
default use astropy. If true, use Vallado algorithm
40+
use_astropy : bool, optional
41+
default use astropy.
4242
4343
Returns
4444
-------
@@ -48,20 +48,21 @@ def azel2radec(
4848
ecliptic declination (degrees)
4949
"""
5050

51-
if usevallado or Time is None: # non-AstroPy method, less accurate
52-
return vazel2radec(az_deg, el_deg, lat_deg, lon_deg, time)
51+
if use_astropy and Time is not None:
5352

54-
obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg)
53+
obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg)
5554

56-
direc = AltAz(location=obs, obstime=Time(str2dt(time)), az=az_deg * u.deg, alt=el_deg * u.deg)
55+
direc = AltAz(location=obs, obstime=Time(str2dt(time)), az=az_deg * u.deg, alt=el_deg * u.deg)
5756

58-
sky = SkyCoord(direc.transform_to(ICRS()))
57+
sky = SkyCoord(direc.transform_to(ICRS()))
5958

60-
return sky.ra.deg, sky.dec.deg
59+
return sky.ra.deg, sky.dec.deg
60+
61+
return vazel2radec(az_deg, el_deg, lat_deg, lon_deg, time)
6162

6263

6364
def radec2azel(
64-
ra_deg: "ndarray", dec_deg: "ndarray", lat_deg: "ndarray", lon_deg: "ndarray", time: datetime, usevallado: bool = False
65+
ra_deg: "ndarray", dec_deg: "ndarray", lat_deg: "ndarray", lon_deg: "ndarray", time: datetime, *, use_astropy: bool = False
6566
) -> typing.Tuple["ndarray", "ndarray"]:
6667
"""
6768
sky coordinates (ra, dec) to viewing angle (az, el)
@@ -78,8 +79,8 @@ def radec2azel(
7879
observer longitude [-180, 180] (degrees)
7980
time : datetime.datetime or str
8081
time of observation
81-
usevallado : bool, optional
82-
default use astropy. If true, use Vallado algorithm
82+
use_astropy : bool, optional
83+
default use astropy.
8384
8485
Returns
8586
-------
@@ -89,13 +90,11 @@ def radec2azel(
8990
elevation [degrees above horizon (neglecting aberration)]
9091
"""
9192

92-
if usevallado or Time is None:
93-
return vradec2azel(ra_deg, dec_deg, lat_deg, lon_deg, time)
94-
95-
obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg)
96-
97-
points = SkyCoord(Angle(ra_deg, unit=u.deg), Angle(dec_deg, unit=u.deg), equinox="J2000.0")
93+
if use_astropy and Time is not None:
94+
obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg)
95+
points = SkyCoord(Angle(ra_deg, unit=u.deg), Angle(dec_deg, unit=u.deg), equinox="J2000.0")
96+
altaz = points.transform_to(AltAz(location=obs, obstime=Time(str2dt(time))))
9897

99-
altaz = points.transform_to(AltAz(location=obs, obstime=Time(str2dt(time))))
98+
return altaz.az.degree, altaz.alt.degree
10099

101-
return altaz.az.degree, altaz.alt.degree
100+
return vradec2azel(ra_deg, dec_deg, lat_deg, lon_deg, time)

src/pymap3d/ecef.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
""" Transforms involving ECEF: earth-centered, earth-fixed frame """
22
try:
33
from numpy import radians, sin, cos, tan, arctan as atan, hypot, degrees, arctan2 as atan2, sqrt, pi, vectorize
4-
from .eci import eci2ecef, ecef2eci
54
except ImportError:
65
from math import radians, sin, cos, tan, atan, hypot, degrees, atan2, sqrt, pi
76

8-
vectorize = eci2ecef = None
7+
vectorize = None
98
import typing
109
from datetime import datetime
1110

1211
from .ellipsoid import Ellipsoid
1312
from .utils import sanitize
13+
from .eci import eci2ecef, ecef2eci
1414

1515
# py < 3.6 compatible
1616
tau = 2 * pi
@@ -331,7 +331,7 @@ def uvw2enu(
331331

332332

333333
def eci2geodetic(
334-
x: "ndarray", y: "ndarray", z: "ndarray", t: datetime, ell: Ellipsoid = None, deg: bool = True
334+
x: "ndarray", y: "ndarray", z: "ndarray", t: datetime, ell: Ellipsoid = None, *, deg: bool = True, use_astropy: bool = True
335335
) -> typing.Tuple["ndarray", "ndarray", "ndarray"]:
336336
"""
337337
convert Earth Centered Internal ECI to geodetic coordinates
@@ -348,10 +348,12 @@ def eci2geodetic(
348348
ECI z-location [meters]
349349
t : datetime.datetime, "ndarray"
350350
UTC time
351-
ell : Ellipsoid (optional)
351+
ell : Ellipsoid, optional
352352
planet ellipsoid model
353-
deg : bool (optional)
353+
deg : bool, optional
354354
if True, degrees. if False, radians
355+
use_astropy : bool, optional
356+
use AstroPy (recommended)
355357
356358
Results
357359
-------
@@ -364,16 +366,21 @@ def eci2geodetic(
364366
365367
eci2geodetic() a.k.a. eci2lla()
366368
"""
367-
if eci2ecef is None:
368-
raise ImportError("pip install astropy")
369369

370-
xecef, yecef, zecef = eci2ecef(x, y, z, t)
370+
xecef, yecef, zecef = eci2ecef(x, y, z, t, use_astropy=use_astropy)
371371

372372
return ecef2geodetic(xecef, yecef, zecef, ell, deg)
373373

374374

375375
def geodetic2eci(
376-
lat: "ndarray", lon: "ndarray", alt: "ndarray", t: datetime, ell: Ellipsoid = None, deg: bool = True
376+
lat: "ndarray",
377+
lon: "ndarray",
378+
alt: "ndarray",
379+
t: datetime,
380+
ell: Ellipsoid = None,
381+
*,
382+
deg: bool = True,
383+
use_astropy: bool = True
377384
) -> typing.Tuple["ndarray", "ndarray", "ndarray"]:
378385
"""
379386
convert geodetic coordinates to Earth Centered Internal ECI
@@ -390,10 +397,12 @@ def geodetic2eci(
390397
altitude above ellipsoid (meters)
391398
t : datetime.datetime, "ndarray"
392399
UTC time
393-
ell : Ellipsoid (optional)
400+
ell : Ellipsoid, optional
394401
planet ellipsoid model
395-
deg : bool (optional)
402+
deg : bool, optional
396403
if True, degrees. if False, radians
404+
use_astropy: bool, optional
405+
use AstroPy (recommended)
397406
398407
Results
399408
-------
@@ -406,12 +415,9 @@ def geodetic2eci(
406415
407416
geodetic2eci() a.k.a lla2eci()
408417
"""
409-
if ecef2eci is None:
410-
raise ImportError("pip install astropy")
411-
412418
x, y, z = geodetic2ecef(lat, lon, alt, ell, deg)
413419

414-
return ecef2eci(x, y, z, t)
420+
return ecef2eci(x, y, z, t, use_astropy=use_astropy)
415421

416422

417423
def enu2ecef(

0 commit comments

Comments
 (0)