Skip to content

Commit d570c06

Browse files
committed
*eci* functions no longer require Numpy
1 parent 5d4234a commit d570c06

3 files changed

Lines changed: 39 additions & 80 deletions

File tree

src/pymap3d/eci.py

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33
from __future__ import annotations
44

55
from datetime import datetime
6-
import sys
7-
import logging
86

9-
from ._typing import FloatLike, NDArray
7+
from .mathfun import cos, sin
8+
from ._typing import FloatLike
109

1110
try:
12-
import numpy as np
1311
import astropy.units as u
1412
from astropy.coordinates import GCRS, ITRS, CartesianRepresentation, EarthLocation
1513
except ImportError:
@@ -52,20 +50,16 @@ def eci2ecef(
5250
z ECEF coordinate
5351
"""
5452

55-
if "astropy" in sys.modules and not force_non_astropy:
56-
xe, ye, ze = eci2ecef_astropy(x, y, z, time)
57-
elif "numpy" in sys.modules:
58-
logging.warning(f"{__name__}: Numpy implementation has much less accuracy than Astropy")
59-
xe, ye, ze = eci2ecef_numpy(x, y, z, time)
60-
else:
61-
raise ImportError("eci2ecef requires either Numpy or Astropy")
53+
if force_non_astropy:
54+
return eci2ecef_stdlib(x, y, z, time)
6255

63-
return xe, ye, ze
56+
try:
57+
return eci2ecef_astropy(x, y, z, time)
58+
except NameError:
59+
return eci2ecef_stdlib(x, y, z, time)
6460

6561

66-
def eci2ecef_astropy(
67-
x: FloatLike, y: FloatLike, z: FloatLike, t: datetime
68-
) -> tuple[NDArray, NDArray, NDArray]:
62+
def eci2ecef_astropy(x, y, z, t: datetime) -> tuple:
6963
"""
7064
eci2ecef using Astropy
7165
@@ -82,17 +76,15 @@ def eci2ecef_astropy(
8276
return x_ecef, y_ecef, z_ecef
8377

8478

85-
def eci2ecef_numpy(x, y, z, t: datetime) -> tuple:
86-
"""
87-
eci2ecef using Numpy
88-
79+
def eci2ecef_stdlib(x, y, z, t: datetime) -> tuple:
80+
""" eci2ecef without Astropy
8981
see eci2ecef() for description
9082
"""
9183

9284
gst = greenwichsrt(juliandate(t))
9385

94-
c = np.cos(gst)
95-
s = np.sin(gst)
86+
c = cos(gst)
87+
s = sin(gst)
9688

9789
x_ecef = c * x + s * y
9890
y_ecef = -s * x + c * y
@@ -132,20 +124,16 @@ def ecef2eci(
132124
z ECI coordinate
133125
"""
134126

135-
if "astropy" in sys.modules and not force_non_astropy:
136-
xe, ye, ze = ecef2eci_astropy(x, y, z, time)
137-
elif "numpy" in sys.modules:
138-
logging.warning(f"{__name__}: Numpy implementation has much less accuracy than Astropy")
139-
xe, ye, ze = ecef2eci_numpy(x, y, z, time)
140-
else:
141-
raise ImportError("ecef2eci requires either Numpy or Astropy")
127+
if force_non_astropy:
128+
return ecef2eci_stdlib(x, y, z, time)
142129

143-
return xe, ye, ze
130+
try:
131+
return ecef2eci_astropy(x, y, z, time)
132+
except NameError:
133+
return ecef2eci_stdlib(x, y, z, time)
144134

145135

146-
def ecef2eci_astropy(
147-
x: FloatLike, y: FloatLike, z: FloatLike, t: datetime
148-
) -> tuple[NDArray, NDArray, NDArray]:
136+
def ecef2eci_astropy(x, y, z, t: datetime) -> tuple:
149137
"""ecef2eci using Astropy
150138
see ecef2eci() for description
151139
"""
@@ -156,15 +144,15 @@ def ecef2eci_astropy(
156144
return eci.x.value, eci.y.value, eci.z.value
157145

158146

159-
def ecef2eci_numpy(x, y, z, t: datetime) -> tuple:
160-
"""ecef2eci using Numpy
147+
def ecef2eci_stdlib(x, y, z, t: datetime) -> tuple:
148+
"""ecef2eci without Astropy
161149
see ecef2eci() for description
162150
"""
163151

164152
gst = greenwichsrt(juliandate(t))
165153

166-
c = np.cos(gst)
167-
s = np.sin(gst)
154+
c = cos(gst)
155+
s = sin(gst)
168156

169157
x_eci = c * x - s * y
170158
y_eci = s * x + c * y

src/pymap3d/latitude.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646

4747

4848
def geoc2geod(
49-
geocentric_lat,
50-
geocentric_distance,
49+
geocentric_lat: FloatLike,
50+
geocentric_distance: FloatLike,
5151
ell: Ellipsoid | None = None,
5252
deg: bool = True,
5353
):
@@ -97,7 +97,7 @@ def geoc2geod(
9797
return degrees(geodetic_lat) if deg else geodetic_lat
9898

9999

100-
def geodetic2geocentric(geodetic_lat, alt_m, ell: Ellipsoid | None = None, deg: bool = True):
100+
def geodetic2geocentric(geodetic_lat: FloatLike, alt_m: FloatLike, ell: Ellipsoid | None = None, deg: bool = True):
101101
"""
102102
convert geodetic latitude to geocentric latitude on spheroid surface
103103
@@ -142,7 +142,7 @@ def geodetic2geocentric(geodetic_lat, alt_m, ell: Ellipsoid | None = None, deg:
142142
geod2geoc = geodetic2geocentric
143143

144144

145-
def geocentric2geodetic(geocentric_lat, alt_m, ell: Ellipsoid | None = None, deg: bool = True):
145+
def geocentric2geodetic(geocentric_lat: FloatLike, alt_m, ell: Ellipsoid | None = None, deg: bool = True):
146146
"""
147147
converts from geocentric latitude to geodetic latitude
148148
@@ -184,7 +184,7 @@ def geocentric2geodetic(geocentric_lat, alt_m, ell: Ellipsoid | None = None, deg
184184
return degrees(geodetic_lat) if deg else geodetic_lat
185185

186186

187-
def geodetic2isometric(geodetic_lat, ell: Ellipsoid | None = None, deg: bool = True):
187+
def geodetic2isometric(geodetic_lat: FloatArray, ell: Ellipsoid | None = None, deg: bool = True):
188188
"""
189189
computes isometric latitude on an ellipsoid
190190
@@ -248,7 +248,7 @@ def geodetic2isometric(geodetic_lat, ell: Ellipsoid | None = None, deg: bool = T
248248
return isometric_lat
249249

250250

251-
def isometric2geodetic(isometric_lat, ell: Ellipsoid | None = None, deg: bool = True):
251+
def isometric2geodetic(isometric_lat: FloatLike, ell: Ellipsoid | None = None, deg: bool = True):
252252
"""
253253
converts from isometric latitude to geodetic latitude
254254
@@ -284,7 +284,7 @@ def isometric2geodetic(isometric_lat, ell: Ellipsoid | None = None, deg: bool =
284284
return degrees(geodetic_lat) if deg else geodetic_lat
285285

286286

287-
def conformal2geodetic(conformal_lat, ell: Ellipsoid | None = None, deg: bool = True):
287+
def conformal2geodetic(conformal_lat: FloatLike, ell: Ellipsoid | None = None, deg: bool = True):
288288
"""
289289
converts from conformal latitude to geodetic latitude
290290
@@ -437,7 +437,7 @@ def geodetic2rectifying(
437437
return degrees(rectifying_lat) if deg else rectifying_lat
438438

439439

440-
def rectifying2geodetic(rectifying_lat, ell: Ellipsoid | None = None, deg: bool = True):
440+
def rectifying2geodetic(rectifying_lat: FloatLike, ell: Ellipsoid | None = None, deg: bool = True):
441441
"""
442442
converts from rectifying latitude to geodetic latitude
443443
@@ -488,7 +488,7 @@ def rectifying2geodetic(rectifying_lat, ell: Ellipsoid | None = None, deg: bool
488488

489489

490490
# %% authalic
491-
def geodetic2authalic(geodetic_lat, ell: Ellipsoid | None = None, deg: bool = True):
491+
def geodetic2authalic(geodetic_lat: FloatArray, ell: Ellipsoid | None = None, deg: bool = True):
492492
"""
493493
converts from geodetic latitude to authalic latitude
494494
@@ -536,7 +536,7 @@ def geodetic2authalic(geodetic_lat, ell: Ellipsoid | None = None, deg: bool = Tr
536536
return degrees(authalic_lat) if deg else authalic_lat
537537

538538

539-
def authalic2geodetic(authalic_lat, ell: Ellipsoid | None = None, deg: bool = True):
539+
def authalic2geodetic(authalic_lat: FloatLike, ell: Ellipsoid | None = None, deg: bool = True):
540540
"""
541541
converts from authalic latitude to geodetic latitude
542542
@@ -585,7 +585,7 @@ def authalic2geodetic(authalic_lat, ell: Ellipsoid | None = None, deg: bool = Tr
585585

586586

587587
# %% parametric
588-
def geodetic2parametric(geodetic_lat, ell: Ellipsoid | None = None, deg: bool = True):
588+
def geodetic2parametric(geodetic_lat: FloatLike, ell: Ellipsoid | None = None, deg: bool = True):
589589
"""
590590
converts from geodetic latitude to parametric latitude
591591
@@ -623,7 +623,7 @@ def geodetic2parametric(geodetic_lat, ell: Ellipsoid | None = None, deg: bool =
623623
return degrees(parametric_lat) if deg else parametric_lat
624624

625625

626-
def parametric2geodetic(parametric_lat, ell: Ellipsoid | None = None, deg: bool = True):
626+
def parametric2geodetic(parametric_lat: FloatLike, ell: Ellipsoid | None = None, deg: bool = True):
627627
"""
628628
converts from parametric latitude to geodetic latitude
629629

src/pymap3d/tests/test_eci.py

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,9 @@
1313
ECEF = [-5762640.0, -1682738.0, 3156028.0]
1414
UTC = datetime.datetime(2019, 1, 4, 12, tzinfo=datetime.timezone.utc)
1515

16-
17-
def test_eci2ecef():
18-
pytest.importorskip("numpy")
19-
# this example from Matlab eci2ecef docs
20-
ecef = pm.eci2ecef(*ECI, UTC)
21-
22-
assert isinstance(ecef[0], float)
23-
assert isinstance(ecef[1], float)
24-
assert isinstance(ecef[2], float)
25-
26-
27-
def test_eci2ecef_numpy():
28-
pytest.importorskip("numpy")
29-
30-
ecef = pm.eci2ecef(*ECI, UTC, force_non_astropy=True)
31-
16+
@pytest.mark.parametrize("force_non_astropy", [True, False])
17+
def test_eci2ecef(force_non_astropy):
18+
ecef = pm.eci2ecef(*ECI, UTC, force_non_astropy=force_non_astropy)
3219
rel = 0.025
3320

3421
assert ecef == approx(ECEF, rel=rel)
@@ -52,20 +39,8 @@ def test_eci2ecef_astropy():
5239

5340
@pytest.mark.parametrize("force_non_astropy", [True, False])
5441
def test_ecef2eci(force_non_astropy):
55-
pytest.importorskip("numpy")
5642
# this example from Matlab ecef2eci docs
5743
eci = pm.ecef2eci(*ECEF, UTC, force_non_astropy=force_non_astropy)
58-
59-
assert isinstance(eci[0], float)
60-
assert isinstance(eci[1], float)
61-
assert isinstance(eci[2], float)
62-
63-
64-
def test_ecef2eci_numpy():
65-
pytest.importorskip("numpy")
66-
67-
eci = pm.eci.ecef2eci_numpy(*ECEF, UTC)
68-
6944
rel = 0.025
7045

7146
assert eci == approx(ECI, rel=rel)
@@ -88,8 +63,6 @@ def test_ecef2eci_astropy():
8863

8964

9065
def test_eci2geodetic():
91-
pytest.importorskip("numpy")
92-
9366
lla = pm.eci2geodetic(*ECI, UTC)
9467

9568
rel = 0.01 if astropy is None else 0.0001
@@ -98,7 +71,6 @@ def test_eci2geodetic():
9871

9972

10073
def test_geodetic2eci():
101-
pytest.importorskip("numpy")
10274

10375
lla = [27.880801, -163.722058, 408850.646]
10476

@@ -111,7 +83,6 @@ def test_geodetic2eci():
11183

11284
def test_eci_aer():
11385
# test coords from Matlab eci2aer
114-
pytest.importorskip("numpy")
11586
t = datetime.datetime(2022, 1, 2, 3, 4, 5, tzinfo=datetime.timezone.utc)
11687

11788
eci = [4500000, -45000000, 3000000]

0 commit comments

Comments
 (0)