open-space-toolkit-physics 11.2.1__py313-none-manylinux2014_x86_64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. open_space_toolkit_physics-11.2.1.dist-info/METADATA +29 -0
  2. open_space_toolkit_physics-11.2.1.dist-info/RECORD +81 -0
  3. open_space_toolkit_physics-11.2.1.dist-info/WHEEL +5 -0
  4. open_space_toolkit_physics-11.2.1.dist-info/top_level.txt +1 -0
  5. open_space_toolkit_physics-11.2.1.dist-info/zip-safe +1 -0
  6. ostk/__init__.py +1 -0
  7. ostk/physics/OpenSpaceToolkitPhysicsPy.cpython-313-x86_64-linux-gnu.so +0 -0
  8. ostk/physics/__init__.py +6 -0
  9. ostk/physics/libopen-space-toolkit-physics.so.11 +0 -0
  10. ostk/physics/test/__init__.py +1 -0
  11. ostk/physics/test/coordinate/__init__.py +1 -0
  12. ostk/physics/test/coordinate/frame/__init__.py +1 -0
  13. ostk/physics/test/coordinate/frame/provider/__init__.py +1 -0
  14. ostk/physics/test/coordinate/frame/provider/iers/__init__.py +1 -0
  15. ostk/physics/test/coordinate/frame/provider/iers/conftest.py +38 -0
  16. ostk/physics/test/coordinate/frame/provider/iers/data/finals2000A.data +10953 -0
  17. ostk/physics/test/coordinate/frame/provider/iers/data/ser7.dat +524 -0
  18. ostk/physics/test/coordinate/frame/provider/iers/test_bulletin_a.py +108 -0
  19. ostk/physics/test/coordinate/frame/provider/iers/test_finals_2000a.py +93 -0
  20. ostk/physics/test/coordinate/frame/provider/iers/test_manager.py +205 -0
  21. ostk/physics/test/coordinate/spherical/__init__.py +1 -0
  22. ostk/physics/test/coordinate/spherical/test_aer.py +143 -0
  23. ostk/physics/test/coordinate/spherical/test_lla.py +490 -0
  24. ostk/physics/test/coordinate/test_axes.py +116 -0
  25. ostk/physics/test/coordinate/test_frame.py +107 -0
  26. ostk/physics/test/coordinate/test_position.py +206 -0
  27. ostk/physics/test/coordinate/test_transform.py +294 -0
  28. ostk/physics/test/coordinate/test_velocity.py +180 -0
  29. ostk/physics/test/data/conftest.py +34 -0
  30. ostk/physics/test/data/data/manifest.json +22 -0
  31. ostk/physics/test/data/provider/test_provider.py +34 -0
  32. ostk/physics/test/data/test_direction.py +40 -0
  33. ostk/physics/test/data/test_manifest.py +43 -0
  34. ostk/physics/test/data/test_manifest_manager.py +62 -0
  35. ostk/physics/test/data/test_scalar.py +54 -0
  36. ostk/physics/test/data/test_vector.py +70 -0
  37. ostk/physics/test/environment/__init__.py +1 -0
  38. ostk/physics/test/environment/atmospheric/__init__.py +1 -0
  39. ostk/physics/test/environment/atmospheric/earth/__init__.py +1 -0
  40. ostk/physics/test/environment/atmospheric/earth/conftest.py +67 -0
  41. ostk/physics/test/environment/atmospheric/earth/data/SW-Last5Years.test.csv +22 -0
  42. ostk/physics/test/environment/atmospheric/earth/data/SpaceWeather-All-v1.2.test.txt +811 -0
  43. ostk/physics/test/environment/atmospheric/earth/test_cssi_space_weather.py +126 -0
  44. ostk/physics/test/environment/atmospheric/earth/test_exponential.py +34 -0
  45. ostk/physics/test/environment/atmospheric/earth/test_manager.py +173 -0
  46. ostk/physics/test/environment/atmospheric/earth/test_nrlmsise00.py +34 -0
  47. ostk/physics/test/environment/atmospheric/test_earth.py +141 -0
  48. ostk/physics/test/environment/gravitational/__init__.py +1 -0
  49. ostk/physics/test/environment/gravitational/earth/__init__.py +1 -0
  50. ostk/physics/test/environment/gravitational/earth/test_manager.py +76 -0
  51. ostk/physics/test/environment/gravitational/test_earth.py +103 -0
  52. ostk/physics/test/environment/gravitational/test_moon.py +55 -0
  53. ostk/physics/test/environment/gravitational/test_spherical.py +36 -0
  54. ostk/physics/test/environment/gravitational/test_sun.py +53 -0
  55. ostk/physics/test/environment/magnetic/__init__.py +1 -0
  56. ostk/physics/test/environment/magnetic/earth/test_manager.py +64 -0
  57. ostk/physics/test/environment/magnetic/test_earth.py +38 -0
  58. ostk/physics/test/environment/object/__init__.py +1 -0
  59. ostk/physics/test/environment/object/celestial/__init__ .py +1 -0
  60. ostk/physics/test/environment/object/celestial/test_earth.py +174 -0
  61. ostk/physics/test/environment/object/celestial/test_moon.py +17 -0
  62. ostk/physics/test/environment/object/celestial/test_sun.py +17 -0
  63. ostk/physics/test/environment/object/test_celestial.py +12 -0
  64. ostk/physics/test/test_environment.py +97 -0
  65. ostk/physics/test/test_import.py +25 -0
  66. ostk/physics/test/time/__init__.py +1 -0
  67. ostk/physics/test/time/test_date.py +136 -0
  68. ostk/physics/test/time/test_date_time.py +230 -0
  69. ostk/physics/test/time/test_duration.py +215 -0
  70. ostk/physics/test/time/test_instant.py +103 -0
  71. ostk/physics/test/time/test_interval.py +432 -0
  72. ostk/physics/test/time/test_scale.py +11 -0
  73. ostk/physics/test/time/test_time.py +114 -0
  74. ostk/physics/test/unit/__init__.py +1 -0
  75. ostk/physics/test/unit/derived/__init__.py +1 -0
  76. ostk/physics/test/unit/derived/test_angle.py +368 -0
  77. ostk/physics/test/unit/test_derived.py +152 -0
  78. ostk/physics/test/unit/test_electric_current.py +5 -0
  79. ostk/physics/test/unit/test_length.py +297 -0
  80. ostk/physics/test/unit/test_mass.py +141 -0
  81. ostk/physics/test/unit/test_time.py +101 -0
@@ -0,0 +1,490 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+ import numpy as np
5
+
6
+ from ostk.core.type import String
7
+
8
+ from ostk.physics import Environment
9
+ from ostk.physics.unit import Angle, Length
10
+ from ostk.physics.coordinate.spherical import LLA
11
+ from ostk.physics.environment.gravitational import Earth as EarthGravitationalModel
12
+
13
+ Spherical = EarthGravitationalModel.spherical
14
+ WGS84_EGM96 = EarthGravitationalModel.WGS84_EGM96
15
+
16
+ ENVIRONMENT = Environment.default(True) # set global environment
17
+
18
+
19
+ @pytest.fixture
20
+ def latitude_deg() -> float:
21
+ return 30.0
22
+
23
+
24
+ @pytest.fixture
25
+ def longitude_deg() -> float:
26
+ return 30.0
27
+
28
+
29
+ @pytest.fixture
30
+ def altitude_deg() -> float:
31
+ return 1000.0
32
+
33
+
34
+ @pytest.fixture
35
+ def latitude(latitude_deg: float) -> Angle:
36
+ return Angle(latitude_deg, Angle.Unit.Degree)
37
+
38
+
39
+ @pytest.fixture
40
+ def longitude(longitude_deg: float) -> Angle:
41
+ return Angle(longitude_deg, Angle.Unit.Degree)
42
+
43
+
44
+ @pytest.fixture
45
+ def altitude(altitude_deg: float) -> Length:
46
+ return Length(altitude_deg, Length.Unit.Meter)
47
+
48
+
49
+ @pytest.fixture
50
+ def lla(
51
+ latitude: Angle,
52
+ longitude: Angle,
53
+ altitude: Length,
54
+ ) -> LLA:
55
+ return LLA(latitude, longitude, altitude)
56
+
57
+
58
+ @pytest.fixture
59
+ def lla_point_equator_1() -> LLA:
60
+ return LLA(
61
+ Angle(0.0, Angle.Unit.Degree),
62
+ Angle(0.0, Angle.Unit.Degree),
63
+ Length(1.0, Length.Unit.Meter),
64
+ )
65
+
66
+
67
+ @pytest.fixture
68
+ def lla_point_equator_2() -> LLA:
69
+ return LLA(
70
+ Angle(0.0, Angle.Unit.Degree),
71
+ Angle(90.0, Angle.Unit.Degree),
72
+ Length(1.0, Length.Unit.Meter),
73
+ )
74
+
75
+
76
+ @pytest.fixture
77
+ def lla_point_equator_3() -> LLA:
78
+ return LLA(
79
+ Angle(0.0, Angle.Unit.Degree),
80
+ Angle(180.0, Angle.Unit.Degree),
81
+ Length(1.0, Length.Unit.Meter),
82
+ )
83
+
84
+
85
+ @pytest.fixture
86
+ def lla_north_pole() -> LLA:
87
+ return LLA(
88
+ Angle(90.0, Angle.Unit.Degree),
89
+ Angle(0.0, Angle.Unit.Degree),
90
+ Length(1.0, Length.Unit.Meter),
91
+ )
92
+
93
+
94
+ @pytest.fixture
95
+ def lla_south_pole() -> LLA:
96
+ return LLA(
97
+ Angle(-90.0, Angle.Unit.Degree),
98
+ Angle(0.0, Angle.Unit.Degree),
99
+ Length(1.0, Length.Unit.Meter),
100
+ )
101
+
102
+
103
+ class TestLLA:
104
+ def test_constructor_list_success(
105
+ self,
106
+ latitude_deg: float,
107
+ longitude_deg: float,
108
+ altitude_deg: float,
109
+ ):
110
+ lla: LLA = LLA.vector([latitude_deg, longitude_deg, altitude_deg])
111
+ assert lla is not None
112
+
113
+ def test_constructor_tuple_success(
114
+ self,
115
+ latitude_deg: float,
116
+ longitude_deg: float,
117
+ altitude_deg: float,
118
+ ):
119
+ lla: LLA = LLA.vector((latitude_deg, longitude_deg, altitude_deg))
120
+ assert lla is not None
121
+
122
+ def test_constructor_numpy_array_success(
123
+ self,
124
+ latitude_deg: float,
125
+ longitude_deg: float,
126
+ altitude_deg: float,
127
+ ):
128
+ lla: LLA = LLA.vector(np.array((latitude_deg, longitude_deg, altitude_deg)))
129
+ assert lla is not None
130
+
131
+ def test_constructor_vector_failure_latitude(self):
132
+ with pytest.raises(RuntimeError):
133
+ lla: LLA = LLA.vector((95.0, 1.0, 1.0))
134
+
135
+ def test_constructor_vector_failure_longitude(self):
136
+ with pytest.raises(RuntimeError):
137
+ lla: LLA = LLA.vector((1.0, -181.0, 1.0))
138
+
139
+ def test_constructor_vector_success_altitude_negative(self):
140
+ lla: LLA = LLA.vector((5.0, 1.0, -1.0))
141
+ assert lla is not None
142
+
143
+ def test_constructor_cartesian_success(self):
144
+ lla: LLA = LLA.cartesian([1.0, 1.0, 1.0], Length(1.0, Length.Unit.Meter), 0.001)
145
+ assert lla is not None
146
+
147
+ def test_comparator(
148
+ self,
149
+ lla_point_equator_1: LLA,
150
+ lla_point_equator_2: LLA,
151
+ ):
152
+ assert lla_point_equator_1 == lla_point_equator_1
153
+ assert lla_point_equator_2 == lla_point_equator_2
154
+ assert lla_point_equator_1 != lla_point_equator_2
155
+
156
+ def test_is_defined(
157
+ self,
158
+ lla: LLA,
159
+ ):
160
+ assert lla.is_defined()
161
+ assert lla.undefined().is_defined() is False
162
+
163
+ def test_getters(
164
+ self,
165
+ latitude: Angle,
166
+ longitude: Angle,
167
+ altitude: Length,
168
+ lla: LLA,
169
+ ):
170
+ assert lla.get_latitude() == latitude
171
+ assert lla.get_longitude() == longitude
172
+ assert lla.get_altitude() == altitude
173
+
174
+ def test_on_surface(
175
+ self,
176
+ lla: LLA,
177
+ ):
178
+ assert lla.on_surface() is not None
179
+
180
+ def test_calculate_distance_to(
181
+ self,
182
+ lla_north_pole: LLA,
183
+ lla_south_pole: LLA,
184
+ ):
185
+ zero_distance_spherical: Length = lla_north_pole.calculate_distance_to(
186
+ lla_north_pole,
187
+ Spherical.equatorial_radius,
188
+ Spherical.flattening,
189
+ )
190
+ assert zero_distance_spherical is not None
191
+ assert zero_distance_spherical.in_meters() == 0.0
192
+
193
+ distance_spherical_poles: Length = lla_south_pole.calculate_distance_to(
194
+ lla_north_pole,
195
+ Spherical.equatorial_radius,
196
+ Spherical.flattening,
197
+ )
198
+ assert (
199
+ distance_spherical_poles.in_meters()
200
+ == Spherical.equatorial_radius.in_meters() * np.pi
201
+ )
202
+
203
+ assert lla_south_pole.calculate_distance_to(lla_north_pole) is not None
204
+
205
+ def test_calculate_azimuth_to(
206
+ self,
207
+ lla_point_equator_1: LLA,
208
+ lla_point_equator_2: LLA,
209
+ ):
210
+ azimuths: Angle = lla_point_equator_1.calculate_azimuth_to(
211
+ lla_point_equator_2,
212
+ Spherical.equatorial_radius,
213
+ Spherical.flattening,
214
+ )
215
+ assert azimuths is not None
216
+ assert isinstance(azimuths, tuple)
217
+ assert len(azimuths) == 2
218
+ assert isinstance(azimuths[0], Angle)
219
+ assert isinstance(azimuths[1], Angle)
220
+
221
+ assert lla_point_equator_1.calculate_azimuth_to(lla_point_equator_2) is not None
222
+
223
+ def test_calculate_intermediate_to(
224
+ self,
225
+ lla_point_equator_1: LLA,
226
+ lla_point_equator_2: LLA,
227
+ ):
228
+ lla_intermediate: LLA = lla_point_equator_1.calculate_intermediate_to(
229
+ lla_point_equator_2,
230
+ 0.3,
231
+ Spherical.equatorial_radius,
232
+ Spherical.flattening,
233
+ )
234
+ assert lla_intermediate is not None
235
+ assert isinstance(lla_intermediate, LLA)
236
+
237
+ assert (
238
+ lla_point_equator_1.calculate_intermediate_to(lla_point_equator_2, 0.3)
239
+ is not None
240
+ )
241
+
242
+ def test_calculate_forward(
243
+ self,
244
+ lla: LLA,
245
+ ):
246
+ lla_forward: LLA = lla.calculate_forward(
247
+ Angle.degrees(0.0),
248
+ Length.meters(5000.0),
249
+ Spherical.equatorial_radius,
250
+ Spherical.flattening,
251
+ )
252
+ assert lla_forward is not None
253
+ assert isinstance(lla_forward, LLA)
254
+
255
+ assert (
256
+ lla.calculate_forward(Angle.degrees(0.0), Length.meters(5000.0)) is not None
257
+ )
258
+
259
+ def test_calculate_linspace_to(
260
+ self,
261
+ lla_point_equator_1: LLA,
262
+ lla_point_equator_2: LLA,
263
+ ):
264
+ n_points: int = 10
265
+ llas: LLA = lla_point_equator_1.calculate_linspace_to(
266
+ lla_point_equator_2,
267
+ n_points,
268
+ Spherical.equatorial_radius,
269
+ Spherical.flattening,
270
+ )
271
+ assert llas is not None
272
+ assert len(llas) == n_points
273
+
274
+ assert (
275
+ lla_point_equator_1.calculate_linspace_to(lla_point_equator_2, n_points)
276
+ is not None
277
+ )
278
+
279
+ def test_to_vector(
280
+ self,
281
+ latitude_deg: float,
282
+ longitude_deg: float,
283
+ altitude_deg: float,
284
+ lla: LLA,
285
+ ):
286
+ vector: np.ndarray = lla.to_vector()
287
+
288
+ assert vector[0] == latitude_deg
289
+ assert vector[1] == longitude_deg
290
+ assert vector[2] == altitude_deg
291
+
292
+ def test_to_cartesian(
293
+ self,
294
+ lla: LLA,
295
+ ):
296
+ cartesian: np.ndarray = LLA.to_cartesian(lla, Length.meters(3.0), 3.0)
297
+ assert cartesian is not None
298
+
299
+ assert LLA.to_cartesian(lla) is not None
300
+
301
+ def test_conversion_string(
302
+ self,
303
+ latitude_deg: float,
304
+ longitude_deg: float,
305
+ altitude_deg: float,
306
+ lla: LLA,
307
+ ):
308
+ lla_string: String = lla.to_string()
309
+
310
+ assert lla_string is not None
311
+ assert isinstance(lla_string, String)
312
+ assert (
313
+ lla_string
314
+ == f"[{latitude_deg} [deg], {longitude_deg} [deg], {altitude_deg} [m]]"
315
+ )
316
+
317
+ def test_distance_between(
318
+ self,
319
+ lla_point_equator_1: LLA,
320
+ lla_point_equator_2: LLA,
321
+ lla_point_equator_3: LLA,
322
+ lla_north_pole: LLA,
323
+ lla_south_pole: LLA,
324
+ ):
325
+ zero_distance_spherical: Length = LLA.distance_between(
326
+ lla_point_equator_1,
327
+ lla_point_equator_1,
328
+ Spherical.equatorial_radius,
329
+ Spherical.flattening,
330
+ )
331
+ assert zero_distance_spherical is not None
332
+ assert zero_distance_spherical.in_meters() == 0.0
333
+
334
+ distance_spherical_equatorial_1_2: Length = LLA.distance_between(
335
+ lla_point_equator_1,
336
+ lla_point_equator_2,
337
+ Spherical.equatorial_radius,
338
+ Spherical.flattening,
339
+ )
340
+ distance_spherical_equatorial_2_1: Length = LLA.distance_between(
341
+ lla_point_equator_2,
342
+ lla_point_equator_1,
343
+ Spherical.equatorial_radius,
344
+ Spherical.flattening,
345
+ )
346
+ assert (
347
+ distance_spherical_equatorial_1_2.in_meters()
348
+ == Spherical.equatorial_radius.in_meters() * np.pi / 2
349
+ )
350
+ assert (
351
+ distance_spherical_equatorial_2_1.in_meters()
352
+ == Spherical.equatorial_radius.in_meters() * np.pi / 2
353
+ )
354
+
355
+ distance_spherical_equatorial_1_3: Length = LLA.distance_between(
356
+ lla_point_equator_1,
357
+ lla_point_equator_3,
358
+ Spherical.equatorial_radius,
359
+ Spherical.flattening,
360
+ )
361
+ distance_spherical_equatorial_3_1: Length = LLA.distance_between(
362
+ lla_point_equator_3,
363
+ lla_point_equator_1,
364
+ Spherical.equatorial_radius,
365
+ Spherical.flattening,
366
+ )
367
+ assert (
368
+ distance_spherical_equatorial_1_3.in_meters()
369
+ == Spherical.equatorial_radius.in_meters() * np.pi
370
+ )
371
+ assert (
372
+ distance_spherical_equatorial_3_1.in_meters()
373
+ == Spherical.equatorial_radius.in_meters() * np.pi
374
+ )
375
+
376
+ distance_spherical_poles: Length = LLA.distance_between(
377
+ lla_north_pole,
378
+ lla_south_pole,
379
+ Spherical.equatorial_radius,
380
+ Spherical.flattening,
381
+ )
382
+ assert distance_spherical_poles == distance_spherical_equatorial_1_3
383
+
384
+ distance_wgs84_equatorial_1_2: Length = LLA.distance_between(
385
+ lla_point_equator_1,
386
+ lla_point_equator_2,
387
+ WGS84_EGM96.equatorial_radius,
388
+ WGS84_EGM96.flattening,
389
+ )
390
+ assert (
391
+ distance_wgs84_equatorial_1_2 == distance_spherical_equatorial_1_2
392
+ ) # on equator
393
+
394
+ distance_wgs84_equatorial_1_3: Length = LLA.distance_between(
395
+ lla_point_equator_1,
396
+ lla_point_equator_3,
397
+ WGS84_EGM96.equatorial_radius,
398
+ WGS84_EGM96.flattening,
399
+ ) # through the poles
400
+ distance_wgs84_equatorial_3_1: Length = LLA.distance_between(
401
+ lla_point_equator_3,
402
+ lla_point_equator_1,
403
+ WGS84_EGM96.equatorial_radius,
404
+ WGS84_EGM96.flattening,
405
+ ) # through the poles
406
+ distance_wgs84_equatorial_2_3: Length = LLA.distance_between(
407
+ lla_point_equator_2,
408
+ lla_point_equator_3,
409
+ WGS84_EGM96.equatorial_radius,
410
+ WGS84_EGM96.flattening,
411
+ )
412
+
413
+ assert distance_wgs84_equatorial_3_1 == distance_wgs84_equatorial_1_3
414
+ assert (
415
+ distance_wgs84_equatorial_1_3
416
+ < distance_wgs84_equatorial_1_2 + distance_wgs84_equatorial_2_3
417
+ )
418
+
419
+ distance_wgs84_1_north_pole: Length = LLA.distance_between(
420
+ lla_point_equator_1,
421
+ lla_north_pole,
422
+ WGS84_EGM96.equatorial_radius,
423
+ WGS84_EGM96.flattening,
424
+ )
425
+ assert (
426
+ distance_wgs84_1_north_pole < distance_wgs84_equatorial_1_2
427
+ ) # flattened surface at poles
428
+ assert distance_wgs84_1_north_pole < distance_spherical_equatorial_1_2
429
+
430
+ def test_azimuth_between(
431
+ self,
432
+ lla_point_equator_1: LLA,
433
+ lla_point_equator_2: LLA,
434
+ ):
435
+ azimuths: Angle = LLA.azimuth_between(
436
+ lla_point_equator_1,
437
+ lla_point_equator_2,
438
+ Spherical.equatorial_radius,
439
+ Spherical.flattening,
440
+ )
441
+ assert azimuths is not None
442
+ assert isinstance(azimuths, tuple)
443
+ assert len(azimuths) == 2
444
+ assert isinstance(azimuths[0], Angle)
445
+ assert isinstance(azimuths[1], Angle)
446
+
447
+ def test_intermediate_between(
448
+ self,
449
+ lla_point_equator_1: LLA,
450
+ lla_point_equator_2: LLA,
451
+ ):
452
+ lla_intermediate: LLA = LLA.intermediate_between(
453
+ lla_point_equator_1,
454
+ lla_point_equator_2,
455
+ 0.3,
456
+ Spherical.equatorial_radius,
457
+ Spherical.flattening,
458
+ )
459
+ assert lla_intermediate is not None
460
+ assert isinstance(lla_intermediate, LLA)
461
+
462
+ def test_forward(
463
+ self,
464
+ lla: LLA,
465
+ ):
466
+ lla_forward: LLA = LLA.forward(
467
+ lla,
468
+ Angle.degrees(0.0),
469
+ Length.meters(5000.0),
470
+ Spherical.equatorial_radius,
471
+ Spherical.flattening,
472
+ )
473
+ assert lla_forward is not None
474
+ assert isinstance(lla_forward, LLA)
475
+
476
+ def test_linspace(
477
+ self,
478
+ lla_point_equator_1: LLA,
479
+ lla_point_equator_2: LLA,
480
+ ):
481
+ n_points: int = 10
482
+ llas: LLA = LLA.linspace(
483
+ lla_point_equator_1,
484
+ lla_point_equator_2,
485
+ n_points,
486
+ Spherical.equatorial_radius,
487
+ Spherical.flattening,
488
+ )
489
+ assert llas is not None
490
+ assert len(llas) == n_points
@@ -0,0 +1,116 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+ import numpy as np
5
+
6
+ import ostk.physics as physics
7
+
8
+ Scale = physics.time.Scale
9
+ DateTime = physics.time.DateTime
10
+ Instant = physics.time.Instant
11
+ Frame = physics.coordinate.Frame
12
+ Axes = physics.coordinate.Axes
13
+
14
+
15
+ def test_coordinate_axes_constructors():
16
+ # Construct arbitrary Frame
17
+ frame: Frame = Frame.GCRF()
18
+
19
+ # Construction using python lists
20
+ vector_1 = [1.0, 0.0, 0.0]
21
+ vector_2 = [0.0, 1.0, 0.0]
22
+ vector_3 = [0.0, 0.0, 1.0]
23
+
24
+ axes: Axes = Axes(vector_1, vector_2, vector_3, frame)
25
+
26
+ assert axes is not None
27
+ assert isinstance(axes, Axes)
28
+ assert axes.is_defined() is True
29
+
30
+ # Construction using python tuples
31
+ vector_1 = (1.0, 0.0, 0.0)
32
+ vector_2 = (0.0, 1.0, 0.0)
33
+ vector_3 = (0.0, 0.0, 1.0)
34
+
35
+ axes: Axes = Axes(vector_1, vector_2, vector_3, frame)
36
+
37
+ assert axes is not None
38
+ assert isinstance(axes, Axes)
39
+ assert axes.is_defined() is True
40
+
41
+ # Construction using python numpy arrays
42
+ vector_1 = np.array(vector_1)
43
+ vector_2 = np.array(vector_2)
44
+ vector_3 = np.array(vector_3)
45
+
46
+ axes: Axes = Axes(vector_1, vector_2, vector_3, frame)
47
+
48
+ assert axes is not None
49
+ assert isinstance(axes, Axes)
50
+ assert axes.is_defined() is True
51
+
52
+ # Construction using undefined method
53
+
54
+ axes: Axes = Axes.undefined()
55
+
56
+ assert axes is not None
57
+ assert isinstance(axes, Axes)
58
+ assert axes.is_defined() is False
59
+
60
+
61
+ def test_coordinate_axes_xyz():
62
+ frame: Frame = Frame.GCRF()
63
+ vector_1 = [1.0, 0.0, 0.0]
64
+ vector_2 = [0.0, 1.0, 0.0]
65
+ vector_3 = [0.0, 0.0, 1.0]
66
+
67
+ axes: Axes = Axes(vector_1, vector_2, vector_3, frame)
68
+
69
+ x = axes.x()
70
+ y = axes.y()
71
+ z = axes.z()
72
+
73
+ assert x is not None
74
+ assert isinstance(x, np.ndarray)
75
+ assert np.array_equal(x, vector_1)
76
+
77
+ assert y is not None
78
+ assert isinstance(y, np.ndarray)
79
+ assert np.array_equal(y, vector_2)
80
+
81
+ assert z is not None
82
+ assert isinstance(z, np.ndarray)
83
+ assert np.array_equal(z, vector_3)
84
+
85
+
86
+ def test_coordinate_axes_get_frame():
87
+ frame: Frame = Frame.GCRF()
88
+ vector_1 = [1.0, 0.0, 0.0]
89
+ vector_2 = [0.0, 1.0, 0.0]
90
+ vector_3 = [0.0, 0.0, 1.0]
91
+
92
+ axes: Axes = Axes(vector_1, vector_2, vector_3, frame)
93
+
94
+ assert axes.get_frame() is not None
95
+ assert isinstance(axes.get_frame(), Frame)
96
+ assert axes.get_frame() == frame
97
+
98
+
99
+ @pytest.mark.skip
100
+ def test_coordinate_axes_in_frame():
101
+ frame: Frame = Frame.GCRF()
102
+ vector_1 = [1.0, 0.0, 0.0]
103
+ vector_2 = [0.0, 1.0, 0.0]
104
+ vector_3 = [0.0, 0.0, 1.0]
105
+
106
+ axes: Axes = Axes(vector_1, vector_2, vector_3, frame)
107
+
108
+ instant: Instant = Instant.date_time(DateTime(2020, 1, 1, 0, 0, 0), Scale.UTC)
109
+
110
+ assert axes.in_frame(Frame.GCRF(), instant) is not None
111
+ assert isinstance(axes.in_frame(Frame.GCRF(), instant), Axes)
112
+ assert axes.in_frame(Frame.GCRF(), instant) == axes
113
+
114
+ assert axes.in_frame(Frame.TEME(), instant) is not None
115
+ assert isinstance(axes.in_frame(Frame.TEME(), instant), Axes)
116
+ assert axes.in_frame(Frame.TEME(), instant) != axes
@@ -0,0 +1,107 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ import numpy as np
6
+
7
+ from ostk.physics.time import Instant
8
+ from ostk.physics.time import DateTime
9
+ from ostk.physics.time import Scale
10
+ from ostk.physics.coordinate import Frame
11
+ from ostk.physics.coordinate.frame.provider import iau
12
+ from ostk.physics.coordinate.frame.provider import Dynamic
13
+
14
+
15
+ @pytest.fixture
16
+ def epoch() -> Instant:
17
+ return Instant.date_time(DateTime(2020, 1, 1, 0, 0, 0), Scale.UTC)
18
+
19
+
20
+ @pytest.fixture
21
+ def frame() -> Frame:
22
+ return Frame.ITRF()
23
+
24
+
25
+ class TestFrame:
26
+ def test_is_defined(self, frame: Frame):
27
+ assert frame.is_defined() is True
28
+
29
+ def test_is_quasi_inertial(self, frame: Frame):
30
+ assert frame.is_quasi_inertial() is False
31
+
32
+ def test_has_parent(self, frame: Frame):
33
+ assert frame.has_parent() is True
34
+
35
+ def test_access_parent(self, frame: Frame):
36
+ assert frame.access_parent() is not None
37
+
38
+ def test_access_ancestor(self, frame: Frame):
39
+ assert frame.access_ancestor(ancestor_degree=1) is not None
40
+
41
+ def test_access_provider(self, frame: Frame):
42
+ assert frame.access_provider()
43
+
44
+ def test_get_name(self, frame: Frame):
45
+ assert frame.get_name() == "ITRF"
46
+
47
+ def test_get_origin_in(self, epoch: Instant, frame: Frame):
48
+ assert frame.get_origin_in(frame=frame, instant=epoch) is not None
49
+
50
+ def test_get_velocity_in(self, epoch: Instant, frame: Frame):
51
+ assert frame.get_velocity_in(frame=frame, instant=epoch) is not None
52
+
53
+ def test_get_axes_in(self, epoch: Instant, frame: Frame):
54
+ assert frame.get_axes_in(frame=frame, instant=epoch) is not None
55
+
56
+ def test_get_transform_to(self, epoch: Instant, frame: Frame):
57
+ assert frame.get_transform_to(frame=frame, instant=epoch) is not None
58
+
59
+ def test_undefined(self):
60
+ assert Frame.undefined() is not None
61
+
62
+ def test_GCRF(self):
63
+ assert Frame.GCRF() is not None
64
+
65
+ def test_J2000(self):
66
+ assert Frame.J2000(theory=iau.Theory.IAU_2006) is not None
67
+
68
+ def test_MOD(self, epoch: Instant):
69
+ assert Frame.MOD(epoch=epoch) is not None
70
+
71
+ def test_TOD(self, epoch: Instant):
72
+ assert Frame.TOD(epoch=epoch, theory=iau.Theory.IAU_2006) is not None
73
+
74
+ def test_TEME(self):
75
+ assert Frame.TEME() is not None
76
+
77
+ def test_TEME_of_epoch(self, epoch: Instant):
78
+ assert Frame.TEME_of_epoch(epoch=epoch) is not None
79
+
80
+ def test_CIRF(self):
81
+ assert Frame.CIRF() is not None
82
+
83
+ def test_TIRF(self):
84
+ assert Frame.TIRF() is not None
85
+
86
+ def test_ITRF(self):
87
+ assert Frame.ITRF() is not None
88
+
89
+ def test_with_name(self, frame: Frame):
90
+ assert Frame.with_name(name=frame.get_name()) is not None
91
+
92
+ def test_exists(self, frame: Frame):
93
+ assert Frame.exists(name=frame.get_name()) is True
94
+
95
+ def test_construct_destruct(self, frame: Frame):
96
+ custom_frame = Frame.construct(
97
+ name="Custom Frame",
98
+ is_quasi_inertial=True,
99
+ parent_frame=frame,
100
+ provider=Dynamic(lambda _: None),
101
+ )
102
+
103
+ assert custom_frame is not None
104
+
105
+ Frame.destruct(custom_frame.get_name())
106
+
107
+ assert Frame.exists(name="Custom Frame") is False