Skip to content

Commit 39e262d

Browse files
committed
ecef2eci: scalar output for scalar input with Numpy backend
add test for Numpy and AstroPy backends
1 parent bf34608 commit 39e262d

File tree

2 files changed

+69
-64
lines changed

2 files changed

+69
-64
lines changed

src/pymap3d/eci.py

Lines changed: 41 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -54,25 +54,7 @@ def eci2ecef_astropy(x, y, z, t: datetime) -> tuple:
5454
"""
5555
eci2ecef using Astropy
5656
57-
Parameters
58-
----------
59-
x : float
60-
ECI x-location [meters]
61-
y : float
62-
ECI y-location [meters]
63-
z : float
64-
ECI z-location [meters]
65-
t : datetime.datetime
66-
time of obsevation (UTC)
67-
68-
Results
69-
-------
70-
x_ecef : float
71-
x ECEF coordinate
72-
y_ecef : float
73-
y ECEF coordinate
74-
z_ecef : float
75-
z ECEF coordinate
57+
see eci2ecef() for description
7658
"""
7759

7860
gcrs = GCRS(CartesianRepresentation(x * u.m, y * u.m, z * u.m), obstime=t)
@@ -89,27 +71,7 @@ def eci2ecef_numpy(x, y, z, t: datetime) -> tuple:
8971
"""
9072
eci2ecef using Numpy
9173
92-
less accurate than astropy, but may be good enough.
93-
94-
Parameters
95-
----------
96-
x : float
97-
ECI x-location [meters]
98-
y : float
99-
ECI y-location [meters]
100-
z : float
101-
ECI z-location [meters]
102-
t : datetime.datetime
103-
time of obsevation (UTC)
104-
105-
Results
106-
-------
107-
x_ecef : float
108-
x ECEF coordinate
109-
y_ecef : float
110-
y ECEF coordinate
111-
z_ecef : float
112-
z ECEF coordinate
74+
see eci2ecef() for description
11375
"""
11476

11577
x = numpy.atleast_1d(x)
@@ -165,33 +127,50 @@ def ecef2eci(x, y, z, time: datetime) -> tuple:
165127
"""
166128

167129
try:
168-
itrs = ITRS(CartesianRepresentation(x * u.m, y * u.m, z * u.m), obstime=time)
169-
gcrs = itrs.transform_to(GCRS(obstime=time))
170-
eci = EarthLocation(*gcrs.cartesian.xyz)
171-
172-
x_eci = eci.x.value
173-
y_eci = eci.y.value
174-
z_eci = eci.z.value
130+
return ecef2eci_astropy(x, y, z, time)
175131
except NameError:
176-
x = numpy.atleast_1d(x)
177-
y = numpy.atleast_1d(y)
178-
z = numpy.atleast_1d(z)
179-
gst = numpy.atleast_1d(greenwichsrt(juliandate(time)))
180-
assert x.shape == y.shape == z.shape
181-
assert x.size == gst.size
182-
183-
ecef = numpy.column_stack((x.ravel(), y.ravel(), z.ravel()))
184-
eci = numpy.empty((x.size, 3))
185-
for i in range(x.size):
186-
eci[i, :] = R3(gst[i]).T @ ecef[i, :]
187-
188-
x_eci = eci[:, 0].reshape(x.shape)
189-
y_eci = eci[:, 1].reshape(y.shape)
190-
z_eci = eci[:, 2].reshape(z.shape)
132+
return ecef2eci_numpy(x, y, z, time)
133+
134+
135+
def ecef2eci_astropy(x, y, z, t: datetime) -> tuple:
136+
"""ecef2eci using Astropy
137+
see ecef2eci() for description
138+
"""
139+
itrs = ITRS(CartesianRepresentation(x * u.m, y * u.m, z * u.m), obstime=t)
140+
gcrs = itrs.transform_to(GCRS(obstime=t))
141+
eci = EarthLocation(*gcrs.cartesian.xyz)
142+
143+
x_eci = eci.x.value
144+
y_eci = eci.y.value
145+
z_eci = eci.z.value
191146

192147
return x_eci, y_eci, z_eci
193148

194149

150+
def ecef2eci_numpy(x, y, z, t: datetime) -> tuple:
151+
"""ecef2eci using Numpy
152+
see ecef2eci() for description
153+
"""
154+
155+
x = numpy.atleast_1d(x)
156+
y = numpy.atleast_1d(y)
157+
z = numpy.atleast_1d(z)
158+
gst = numpy.atleast_1d(greenwichsrt(juliandate(t)))
159+
assert x.shape == y.shape == z.shape
160+
assert x.size == gst.size
161+
162+
ecef = numpy.column_stack((x.ravel(), y.ravel(), z.ravel()))
163+
eci = numpy.empty((x.size, 3))
164+
for i in range(x.size):
165+
eci[i, :] = R3(gst[i]).T @ ecef[i, :]
166+
167+
x_eci = eci[:, 0].reshape(x.shape)
168+
y_eci = eci[:, 1].reshape(y.shape)
169+
z_eci = eci[:, 2].reshape(z.shape)
170+
171+
return x_eci.squeeze()[()], y_eci.squeeze()[()], z_eci.squeeze()[()]
172+
173+
195174
def R3(x: float):
196175
"""Rotation matrix for ECI"""
197176
return numpy.array(

src/pymap3d/tests/test_eci.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,35 @@ def test_ecef2eci():
5555
# this example from Matlab ecef2eci docs
5656
eci = pm.ecef2eci(*ECEF, UTC)
5757

58-
rel = 0.01 if astropy is None else 0.0001
58+
assert isinstance(eci[0], float)
59+
assert isinstance(eci[1], float)
60+
assert isinstance(eci[2], float)
61+
62+
63+
def test_ecef2eci_numpy():
64+
pytest.importorskip("numpy")
65+
66+
eci = pm.eci.ecef2eci_numpy(*ECEF, UTC)
67+
68+
rel = 0.025
69+
70+
assert eci == approx(ECI, rel=rel)
71+
assert isinstance(eci[0], float)
72+
assert isinstance(eci[1], float)
73+
assert isinstance(eci[2], float)
74+
75+
76+
def test_ecef2eci_astropy():
77+
pytest.importorskip("astropy")
78+
79+
eci = pm.eci.ecef2eci_astropy(*ECEF, UTC)
80+
81+
rel = 0.0001
5982

60-
assert eci == approx([-2981810.6, 5207039.5, 3161595.1], rel=rel)
83+
assert eci == approx(ECI, rel=rel)
84+
assert isinstance(eci[0], float)
85+
assert isinstance(eci[1], float)
86+
assert isinstance(eci[2], float)
6187

6288

6389
def test_eci2geodetic():

0 commit comments

Comments
 (0)