Skip to content

Commit 964edf1

Browse files
committed
recovering coverage for deep space part as well
1 parent e65f19f commit 964edf1

1 file changed

Lines changed: 242 additions & 0 deletions

File tree

tests/test_deep_space.py

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import unittest
2+
import importlib
3+
from types import SimpleNamespace
4+
from unittest.mock import patch
25

36
import dsgp4
7+
import dsgp4.deep_space as deep_space
48
import numpy as np
59
import sgp4.earth_gravity
610
import sgp4.io
711
import sgp4.propagation
812
import torch
913

1014

15+
dsgp4_sgp4_module = importlib.import_module("dsgp4.sgp4")
16+
17+
1118
DEEP_SPACE_TLES = [
1219
(
1320
"1 14128U 83058A 06176.02844893 -.00000158 00000-0 10000-3 0 9627",
@@ -68,5 +75,240 @@ def test_mixed_batch_matches_reference(self):
6875
self.assertTrue(np.allclose(out, ref, atol=1e-8, rtol=0.0))
6976

7077

78+
class DeepSpaceCoverageBranchesTestCase(unittest.TestCase):
79+
@staticmethod
80+
def _tensor(v):
81+
return torch.tensor(float(v))
82+
83+
def _make_dpper_satellite(self):
84+
z = self._tensor(0.0)
85+
return SimpleNamespace(
86+
_zmos=z,
87+
_zmol=z,
88+
_t=z,
89+
_se2=z,
90+
_se3=z,
91+
_si2=z,
92+
_si3=z,
93+
_sl2=z,
94+
_sl3=z,
95+
_sl4=z,
96+
_sgh2=z,
97+
_sgh3=z,
98+
_sgh4=z,
99+
_sh2=z,
100+
_sh3=z,
101+
_ee2=z,
102+
_e3=z,
103+
_xi2=z,
104+
_xi3=z,
105+
_xl2=z,
106+
_xl3=z,
107+
_xl4=z,
108+
_xgh2=z,
109+
_xgh3=z,
110+
_xgh4=z,
111+
_xh2=z,
112+
_xh3=z,
113+
_peo=z,
114+
_pinco=z,
115+
_plo=z,
116+
_pgho=z,
117+
_pho=self._tensor(0.1),
118+
)
119+
120+
def _make_dsinit_satellite(self):
121+
return SimpleNamespace(
122+
_t=self._tensor(60.0),
123+
_xke=self._tensor(0.0743669161),
124+
_gsto=self._tensor(0.2),
125+
_mo=self._tensor(0.3),
126+
_nodeo=self._tensor(0.4),
127+
_argpo=self._tensor(0.1),
128+
_mdot=self._tensor(0.001),
129+
_nodedot=self._tensor(0.002),
130+
_no_unkozai=self._tensor(0.0086),
131+
)
132+
133+
def test_private_helpers_and_dpper_low_inclination_wrap(self):
134+
x = torch.tensor(1.23)
135+
self.assertIs(deep_space._to_tensor(x, x), x)
136+
self.assertTrue(deep_space._to_bool(True))
137+
138+
sat = self._make_dpper_satellite()
139+
ep, inclp, nodep, argpp, mp = deep_space.dpper(
140+
satellite=sat,
141+
inclo=self._tensor(0.1),
142+
init="n",
143+
ep=self._tensor(0.1),
144+
inclp=self._tensor(0.1),
145+
nodep=self._tensor(0.1),
146+
argpp=self._tensor(0.0),
147+
mp=self._tensor(0.0),
148+
opsmode="a",
149+
)
150+
151+
self.assertLess(float(nodep), 0.0)
152+
self.assertTrue(torch.isfinite(ep))
153+
self.assertTrue(torch.isfinite(inclp))
154+
self.assertTrue(torch.isfinite(argpp))
155+
self.assertTrue(torch.isfinite(mp))
156+
157+
def test_dpper_negative_node_wraps_for_afspc_mode(self):
158+
sat = self._make_dpper_satellite()
159+
_, _, nodep, _, _ = deep_space.dpper(
160+
satellite=sat,
161+
inclo=self._tensor(0.1),
162+
init="n",
163+
ep=self._tensor(0.1),
164+
inclp=self._tensor(0.1),
165+
nodep=self._tensor(-0.1),
166+
argpp=self._tensor(0.0),
167+
mp=self._tensor(0.0),
168+
opsmode="a",
169+
)
170+
171+
self.assertGreaterEqual(float(nodep), 0.0)
172+
173+
def _call_dsinit(self, ecco):
174+
sat = self._make_dsinit_satellite()
175+
one = self._tensor(1.0)
176+
half = self._tensor(0.5)
177+
em = self._tensor(ecco)
178+
eccsq = self._tensor(ecco * ecco)
179+
inclm = self._tensor(0.35)
180+
sinim = torch.sin(inclm)
181+
cosim = torch.cos(inclm)
182+
183+
return deep_space.dsinit(
184+
satellite=sat,
185+
cosim=cosim,
186+
emsq=eccsq,
187+
argpo=self._tensor(0.1),
188+
s1=one,
189+
s2=one,
190+
s3=one,
191+
s4=one,
192+
s5=one,
193+
sinim=sinim,
194+
ss1=one,
195+
ss2=one,
196+
ss3=one,
197+
ss4=one,
198+
ss5=one,
199+
sz1=half,
200+
sz3=half,
201+
sz11=half,
202+
sz13=half,
203+
sz21=half,
204+
sz23=half,
205+
sz31=half,
206+
sz33=half,
207+
z1=half,
208+
z3=half,
209+
z11=half,
210+
z13=half,
211+
z21=half,
212+
z23=half,
213+
z31=half,
214+
z33=half,
215+
ecco=em,
216+
eccsq=eccsq,
217+
em=em,
218+
argpm=self._tensor(0.2),
219+
inclm=inclm,
220+
mm=self._tensor(0.3),
221+
nm=self._tensor(0.0086),
222+
nodem=self._tensor(0.4),
223+
xpidot=self._tensor(0.001),
224+
)
225+
226+
def test_dsinit_irez2_low_eccentricity_branch(self):
227+
out = self._call_dsinit(ecco=0.6)
228+
self.assertEqual(out["irez"], 2)
229+
self.assertNotEqual(float(out["d2201"]), 0.0)
230+
self.assertNotEqual(float(out["d5232"]), 0.0)
231+
232+
def test_dsinit_irez2_high_eccentricity_branch(self):
233+
out = self._call_dsinit(ecco=0.8)
234+
self.assertEqual(out["irez"], 2)
235+
self.assertNotEqual(float(out["d5421"]), 0.0)
236+
self.assertNotEqual(float(out["d5433"]), 0.0)
237+
238+
def test_dsinit_irez2_mid_high_eccentricity_branch(self):
239+
out = self._call_dsinit(ecco=0.7)
240+
self.assertEqual(out["irez"], 2)
241+
self.assertNotEqual(float(out["d5220"]), 0.0)
242+
243+
def test_dspace_irez2_integration_branch(self):
244+
sat = SimpleNamespace(
245+
_gsto=self._tensor(0.3),
246+
_t=self._tensor(1000.0),
247+
_dedt=self._tensor(0.0),
248+
_didt=self._tensor(0.0),
249+
_domdt=self._tensor(0.0),
250+
_dnodt=self._tensor(0.0),
251+
_dmdt=self._tensor(0.0),
252+
_irez=2,
253+
_atime=self._tensor(0.0),
254+
_xni=self._tensor(0.0086),
255+
_xli=self._tensor(0.2),
256+
_no_unkozai=self._tensor(0.0086),
257+
_xlamo=self._tensor(0.2),
258+
_xfact=self._tensor(1.0e-4),
259+
_argpo=self._tensor(0.1),
260+
_argpdot=self._tensor(2.0e-4),
261+
_d2201=self._tensor(1.0e-6),
262+
_d2211=self._tensor(1.0e-6),
263+
_d3210=self._tensor(1.0e-6),
264+
_d3222=self._tensor(1.0e-6),
265+
_d4410=self._tensor(1.0e-6),
266+
_d4422=self._tensor(1.0e-6),
267+
_d5220=self._tensor(1.0e-6),
268+
_d5232=self._tensor(1.0e-6),
269+
_d5421=self._tensor(1.0e-6),
270+
_d5433=self._tensor(1.0e-6),
271+
)
272+
273+
em, argpm, inclm, mm, nodem, nm = deep_space.dspace(
274+
satellite=sat,
275+
em=self._tensor(0.7),
276+
argpm=self._tensor(0.2),
277+
inclm=self._tensor(0.3),
278+
mm=self._tensor(0.4),
279+
nodem=self._tensor(0.5),
280+
nm=self._tensor(0.0086),
281+
)
282+
283+
self.assertNotEqual(float(sat._atime), 0.0)
284+
self.assertTrue(torch.isfinite(em))
285+
self.assertTrue(torch.isfinite(argpm))
286+
self.assertTrue(torch.isfinite(inclm))
287+
self.assertTrue(torch.isfinite(mm))
288+
self.assertTrue(torch.isfinite(nodem))
289+
self.assertTrue(torch.isfinite(nm))
290+
291+
def test_sgp4_deep_space_edge_guards(self):
292+
tle = dsgp4.tle.TLE([DEEP_SPACE_TLES[0][0], DEEP_SPACE_TLES[0][1]])
293+
dsgp4.initialize_tle(tle, gravity_constant_name="wgs-84")
294+
self.assertEqual(tle._method, "d")
295+
296+
with patch.object(
297+
dsgp4_sgp4_module,
298+
"dpper",
299+
return_value=(
300+
torch.tensor([1.1]),
301+
torch.tensor([-np.pi]),
302+
torch.tensor([0.2]),
303+
torch.tensor([0.1]),
304+
torch.tensor([0.3]),
305+
),
306+
):
307+
dsgp4_sgp4_module.sgp4(tle, torch.tensor([10.0]))
308+
309+
self.assertEqual(int(tle._error), 3)
310+
self.assertTrue(torch.isfinite(tle._xlcof).all())
311+
312+
71313
if __name__ == "__main__":
72314
unittest.main()

0 commit comments

Comments
 (0)