keplemon 0.1.9__cp313-cp313-win_amd64.whl → 2.0.2__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
keplemon/__init__.py CHANGED
@@ -1,17 +1,35 @@
1
- from keplemon._keplemon.time import load_time_constants # type: ignore
2
- from keplemon._keplemon import get_thread_count, set_thread_count # type: ignore
1
+ from keplemon._keplemon.saal.time_func_interface import load_time_constants # type: ignore
2
+ from keplemon._keplemon import ( # type: ignore
3
+ get_thread_count,
4
+ set_thread_count,
5
+ set_license_file_path,
6
+ get_license_file_path,
7
+ set_jpl_ephemeris_file_path,
8
+ )
3
9
  from pathlib import Path
4
- from shutil import copyfile
5
10
 
6
- current_dir = Path(__file__).parent
7
11
 
8
- # Copy the license file to the current working directory if it doesn't exist
9
- working_license_path = Path.cwd() / "SGP4_Open_License.txt"
10
- if not working_license_path.exists():
11
- copyfile(current_dir / "SGP4_Open_License.txt", working_license_path)
12
+ PACKAGE_DIRECTORY = Path(__file__).parent
13
+ ASSETS_DIRECTORY = PACKAGE_DIRECTORY / "assets"
14
+
15
+ # Set the license file directory to the package directory
16
+ set_license_file_path(ASSETS_DIRECTORY.as_posix())
12
17
 
13
18
  # Load the time constants from the assets directory
14
- TIME_CONSTANTS_PATH = current_dir / "assets" / "time_constants.dat"
19
+ TIME_CONSTANTS_PATH = ASSETS_DIRECTORY / "time_constants.dat"
15
20
  load_time_constants(TIME_CONSTANTS_PATH.as_posix())
16
21
 
17
- __all__ = ["get_thread_count", "set_thread_count", "TIME_CONSTANTS_PATH"]
22
+ # Load the JPL path
23
+ JPL_EPHEMERIS_PATH = ASSETS_DIRECTORY / "JPLcon_1950_2050.405"
24
+ set_jpl_ephemeris_file_path(JPL_EPHEMERIS_PATH.as_posix())
25
+
26
+ __all__ = [
27
+ "get_thread_count",
28
+ "set_thread_count",
29
+ "TIME_CONSTANTS_PATH",
30
+ "JPL_EPHEMERIS_PATH",
31
+ "set_license_file_path",
32
+ "PACKAGE_DIRECTORY",
33
+ "ASSETS_DIRECTORY",
34
+ "get_license_file_path",
35
+ ]
keplemon/__init__.pyi CHANGED
@@ -28,3 +28,27 @@ Path to the default time constants file required by the SAAL binaries
28
28
  !!! warning
29
29
  This path should never be modified and is only exposed to allow inspection of current data.
30
30
  """
31
+
32
+ #: Path to the parent directory of the package
33
+ PACKAGE_DIRECTORY: Path
34
+ """Path to the parent directory of the package"""
35
+
36
+ #: Path to the assets directory containing supporting data files for the package
37
+ ASSETS_DIRECTORY: Path
38
+ """Path to the assets directory containing supporting data files for the package"""
39
+
40
+ def set_license_file_path(path: str) -> None:
41
+ """
42
+ Set the path to the license file required by the SAAL binaries
43
+
44
+ Args:
45
+ path: Path to the SGP4 license file
46
+ """
47
+ ...
48
+
49
+ def get_license_file_path() -> str:
50
+ """
51
+ Returns:
52
+ Path to the SGP4 license file
53
+ """
54
+ ...
Binary file
keplemon/bodies.pyi CHANGED
@@ -1,8 +1,20 @@
1
1
  # flake8: noqa
2
- from keplemon.elements import TLE, CartesianState, Ephemeris
2
+ from keplemon.elements import (
3
+ TLE,
4
+ CartesianState,
5
+ Ephemeris,
6
+ KeplerianState,
7
+ GeodeticPosition,
8
+ OrbitPlotData,
9
+ TopocentricElements,
10
+ RelativeState,
11
+ BoreToBodyAngles,
12
+ )
3
13
  from keplemon.catalogs import TLECatalog
4
14
  from keplemon.time import Epoch, TimeSpan
5
- from keplemon.events import CloseApproach, CloseApproachReport
15
+ from keplemon.events import CloseApproach, CloseApproachReport, HorizonAccessReport, FieldOfViewReport
16
+ from keplemon.propagation import ForceProperties
17
+ from keplemon.enums import ReferenceFrame
6
18
 
7
19
  class Earth:
8
20
  @staticmethod
@@ -17,16 +29,27 @@ class Earth:
17
29
  def get_kem() -> float: ...
18
30
 
19
31
  class Satellite:
20
- satellite_id: int
21
- """Number used to distinguish the satellite from other objects.
22
-
23
- !!! note
24
- Every attempt should be made to make this unique to support satellite methods that perform comparisons or
25
- bookkeeping.
32
+
33
+ id: str
34
+ """Unique identifier for the satellite."""
35
+
36
+ norad_id: int
37
+ """Number corresponding to the satellite's NORAD catalog ID.
26
38
  """
39
+
40
+ force_properties: ForceProperties
41
+ """Force properties of the satellite used for propagation"""
42
+
27
43
  name: str | None
28
44
  """Human-readable name of the satellite"""
29
45
 
46
+ keplerian_state: KeplerianState | None
47
+ """Keplerian state of the satellite at the epoch of the TLE, if available"""
48
+
49
+ geodetic_position: GeodeticPosition | None
50
+ """Geodetic position of the satellite at the epoch of the TLE, if available"""
51
+
52
+ def __init__(self) -> None: ...
30
53
  @classmethod
31
54
  def from_tle(cls, tle: TLE) -> Satellite:
32
55
  """
@@ -59,11 +82,52 @@ class Satellite:
59
82
  """
60
83
  ...
61
84
 
85
+ def get_relative_state_at_epoch(self, other: Satellite, epoch: Epoch) -> RelativeState | None:
86
+ """
87
+ Calculate the relative state between this satellite and another satellite at a given epoch.
88
+
89
+ Args:
90
+ other: Secondary satellite to calculate the relative state against
91
+ epoch: UTC epoch at which the relative state will be calculated
92
+ """
93
+ ...
94
+
95
+ def get_body_angles_at_epoch(self, other: Satellite, epoch: Epoch) -> BoreToBodyAngles | None:
96
+ """
97
+ Calculate the bore-to-body angles between this satellite and another satellite at a given epoch.
98
+
99
+ Args:
100
+ other: Secondary satellite to calculate the bore-to-body angles against
101
+ epoch: UTC epoch at which the bore-to-body angles will be calculated
102
+ """
103
+ ...
104
+
105
+ def get_plot_data(self, start: Epoch, end: Epoch, step: TimeSpan) -> OrbitPlotData | None: ...
106
+ def get_observatory_access_report(
107
+ self,
108
+ observatories: list[Observatory],
109
+ start: Epoch,
110
+ end: Epoch,
111
+ min_el: float,
112
+ min_duration: TimeSpan,
113
+ ) -> HorizonAccessReport | None:
114
+ """
115
+ Calculate horizon access from multiple observatories to this satellite.
116
+
117
+ Args:
118
+ observatories: List of observatories to check for horizon access
119
+ start: UTC epoch of the start of the report
120
+ end: UTC epoch of the end of the report
121
+ min_el: Minimum elevation angle in **_degrees_**
122
+ min_duration: Minimum duration of access
123
+
124
+ Returns:
125
+ Horizon access report containing accesses from all observatories to the satellite,
126
+ or None if the satellite ephemeris cannot be generated
127
+ """
128
+ ...
129
+
62
130
  class Constellation:
63
- """
64
- Args:
65
- name: Identifier of the constellation
66
- """
67
131
 
68
132
  count: int
69
133
  """Number of satellites in the constellation"""
@@ -71,7 +135,8 @@ class Constellation:
71
135
  name: str | None
72
136
  """Human-readable name of the constellation"""
73
137
 
74
- def __init__(self, name: str) -> None: ...
138
+ def __init__(self) -> None: ...
139
+ def get_plot_data(self, start: Epoch, end: Epoch, step: TimeSpan) -> dict[str, OrbitPlotData]: ...
75
140
  @classmethod
76
141
  def from_tle_catalog(cls, tle_catalog: TLECatalog) -> Constellation:
77
142
  """
@@ -97,7 +162,7 @@ class Constellation:
97
162
  start: Epoch,
98
163
  end: Epoch,
99
164
  step: TimeSpan,
100
- ) -> dict[int, Ephemeris]:
165
+ ) -> dict[str, Ephemeris]:
101
166
  """
102
167
  Args:
103
168
  start: UTC epoch of the start of the ephemeris
@@ -152,7 +217,30 @@ class Constellation:
152
217
  """
153
218
  ...
154
219
 
155
- def __getitem__(self, satellite_id: int) -> Satellite: ...
220
+ def __getitem__(self, satellite_id: str) -> Satellite: ...
221
+ def __setitem__(self, satellite_id: str, sat: Satellite) -> None: ...
222
+ def get_horizon_access_report(
223
+ self,
224
+ site: Observatory,
225
+ start: Epoch,
226
+ end: Epoch,
227
+ min_el: float,
228
+ min_duration: TimeSpan,
229
+ ) -> HorizonAccessReport:
230
+ """
231
+ Calculate horizon access to a given observatory.
232
+
233
+ Args:
234
+ site: Observatory to check for horizon access
235
+ start: UTC epoch of the start of the report
236
+ end: UTC epoch of the end of the report
237
+ min_el: Minimum elevation angle in **_degrees_**
238
+ min_duration: Minimum duration of access
239
+
240
+ Returns:
241
+ Horizon access report for the constellation from the observatory
242
+ """
243
+ ...
156
244
 
157
245
  class Sensor:
158
246
  """
@@ -161,7 +249,9 @@ class Sensor:
161
249
  angular_noise: Angular noise in **_degrees_**
162
250
  """
163
251
 
164
- name: str
252
+ id: str
253
+ """Unique identifier for the sensor."""
254
+ name: str | None
165
255
  angular_noise: float
166
256
  range_noise: float | None
167
257
  """Range noise in **_kilometers_**"""
@@ -171,18 +261,19 @@ class Sensor:
171
261
 
172
262
  angular_rate_noise: float | None
173
263
  """Angular rate noise in **_degrees per second_**"""
174
- def __init__(self, name: str, angular_noise: float) -> None: ...
264
+ def __init__(self, angular_noise: float) -> None: ...
175
265
 
176
266
  class Observatory:
177
267
  """
178
268
  Args:
179
- name: Identifier of the observatory
180
269
  latitude: Latitude in **_degrees_**
181
270
  longitude: Longitude in **_degrees_**
182
271
  altitude: Altitude in **_kilometers_**
183
272
  """
184
273
 
185
274
  name: str
275
+ id: str
276
+ """Unique identifier for the observatory."""
186
277
  latitude: float
187
278
  longitude: float
188
279
  altitude: float
@@ -190,7 +281,6 @@ class Observatory:
190
281
  """List of sensors at the observatory"""
191
282
  def __init__(
192
283
  self,
193
- name: str,
194
284
  latitude: float,
195
285
  longitude: float,
196
286
  altitude: float,
@@ -204,3 +294,84 @@ class Observatory:
204
294
  TEME Cartesian state of the observatory in **_kilometers_** and **_kilometers per second_**
205
295
  """
206
296
  ...
297
+
298
+ @classmethod
299
+ def from_cartesian_state(cls, state: CartesianState) -> Observatory:
300
+ """
301
+ Create an observatory from a Cartesian state.
302
+
303
+ Args:
304
+ state: Cartesian state of the observatory
305
+
306
+ """
307
+ ...
308
+
309
+ def get_theta(self, epoch: Epoch) -> float:
310
+ """
311
+ Calculate the Greenwich angle plus the observatory longitude at a given epoch.
312
+
313
+ Args:
314
+ epoch: UTC epoch for the calculation
315
+
316
+ Returns:
317
+ Greenwich angle plus the observatory longitude in **_radians_**
318
+ """
319
+ ...
320
+
321
+ def get_horizon_access_report(
322
+ self,
323
+ satellite: Satellite,
324
+ start: Epoch,
325
+ end: Epoch,
326
+ min_el: float,
327
+ min_duration: TimeSpan,
328
+ ) -> HorizonAccessReport:
329
+ """
330
+ Calculate horizon access for a satellite from the observatory.
331
+
332
+ Args:
333
+ satellite: Satellite to check for horizon access
334
+ start: UTC epoch of the start of the report
335
+ end: UTC epoch of the end of the report
336
+ min_el: Minimum elevation angle in **_degrees_**
337
+ min_duration: Minimum duration of access in **_seconds_**
338
+
339
+ Returns:
340
+ Horizon access report for the satellite from the observatory
341
+ """
342
+ ...
343
+
344
+ def get_field_of_view_report(
345
+ self,
346
+ epoch: Epoch,
347
+ sensor_direction: TopocentricElements,
348
+ angular_threshold: float,
349
+ sats: Constellation,
350
+ reference_frame: ReferenceFrame,
351
+ ) -> FieldOfViewReport:
352
+ """
353
+ Calculate satellites in the field of view from a given time and direction.
354
+
355
+ Args:
356
+ epoch: UTC epoch of the report
357
+ sensor_direction: Topocentric direction the sensor is pointing
358
+ angular_threshold: Angular threshold in **_degrees_**
359
+ sats: Constellation of satellites to check for being in the field of view
360
+ reference_frame: Reference frame of the output direction elements
361
+ """
362
+ ...
363
+
364
+ def get_topocentric_to_satellite(
365
+ self,
366
+ epoch: Epoch,
367
+ sat: Satellite,
368
+ reference_frame: ReferenceFrame,
369
+ ) -> TopocentricElements:
370
+ """
371
+ Get the topocentric elements of a satellite as seen from the observatory.
372
+ Args:
373
+ epoch: UTC epoch of the observation
374
+ sat: Satellite to observe
375
+ reference_frame: Reference frame of the output direction elements
376
+ """
377
+ ...
keplemon/catalogs.pyi CHANGED
@@ -1,5 +1,5 @@
1
1
  # flake8: noqa
2
- from keplemon.elements import TLE
2
+ from keplemon.elements import TLE, OrbitPlotData
3
3
 
4
4
  class TLECatalog:
5
5
  count: int
@@ -8,9 +8,10 @@ class TLECatalog:
8
8
  @classmethod
9
9
  def from_tle_file(cls, filename: str) -> TLECatalog: ...
10
10
  def add(self, tle: TLE) -> None: ...
11
- def get(self, satellite_id: int) -> TLE: ...
12
- def remove(self, satellite_id: int) -> None: ...
13
- def keys(self) -> list[int]: ...
11
+ def get(self, satellite_id: str) -> TLE: ...
12
+ def remove(self, satellite_id: str) -> None: ...
13
+ def keys(self) -> list[str]: ...
14
14
  def get_count(self) -> int: ...
15
15
  def clear(self) -> None: ...
16
- def __getitem__(self, satellite_id: int) -> TLE: ...
16
+ def __getitem__(self, satellite_id: str) -> TLE: ...
17
+ def get_plot_data(self) -> OrbitPlotData: ...
keplemon/elements.py CHANGED
@@ -7,6 +7,14 @@ from keplemon._keplemon.elements import ( # type: ignore
7
7
  Ephemeris,
8
8
  SphericalVector,
9
9
  TopocentricElements,
10
+ HorizonState,
11
+ HorizonElements,
12
+ GeodeticPosition,
13
+ OrbitPlotData,
14
+ OrbitPlotState,
15
+ RelativeState,
16
+ BoreToBodyAngles,
17
+ TopocentricState,
10
18
  )
11
19
 
12
20
  __all__ = [
@@ -18,4 +26,12 @@ __all__ = [
18
26
  "Ephemeris",
19
27
  "SphericalVector",
20
28
  "TopocentricElements",
29
+ "HorizonState",
30
+ "HorizonElements",
31
+ "GeodeticPosition",
32
+ "OrbitPlotData",
33
+ "OrbitPlotState",
34
+ "RelativeState",
35
+ "BoreToBodyAngles",
36
+ "TopocentricState",
21
37
  ]
keplemon/elements.pyi CHANGED
@@ -2,8 +2,112 @@
2
2
  from __future__ import annotations
3
3
  from keplemon.time import Epoch
4
4
  from keplemon.enums import Classification, KeplerianType, ReferenceFrame
5
- from keplemon.propagation import ForceProperties
6
5
  from keplemon.events import CloseApproach
6
+ from keplemon.bodies import Observatory
7
+
8
+ class RelativeState:
9
+ epoch: Epoch
10
+ position: CartesianVector
11
+ velocity: CartesianVector
12
+ origin_satellite_id: str
13
+ secondary_satellite_id: str
14
+
15
+ class BoreToBodyAngles:
16
+ earth_angle: float
17
+ sun_angle: float
18
+ moon_angle: float
19
+
20
+ class OrbitPlotData:
21
+ satellite_id: str
22
+ epochs: list[str]
23
+ semi_major_axes: list[float]
24
+ eccentricities: list[float]
25
+ inclinations: list[float]
26
+ raans: list[float]
27
+ radii: list[float]
28
+ apogee_radii: list[float]
29
+ perigee_radii: list[float]
30
+ latitudes: list[float]
31
+ longitudes: list[float]
32
+ altitudes: list[float]
33
+
34
+ class GeodeticPosition:
35
+ """
36
+ Args:
37
+ latitude: Latitude in **_degrees_**
38
+ longitude: Longitude in **_degrees_**
39
+ altitude: Altitude in **_kilometers_**
40
+ """
41
+
42
+ latitude: float
43
+ """Latitude in **_degrees_**"""
44
+
45
+ longitude: float
46
+ """Longitude in **_degrees_**"""
47
+
48
+ altitude: float
49
+ """Altitude in **_kilometers_**"""
50
+
51
+ def __init__(self, latitude: float, longitude: float, altitude: float) -> None: ...
52
+
53
+ class HorizonElements:
54
+ """
55
+ Args:
56
+ range: Range in **_kilometers_**
57
+ az: Azimuth in **_degrees_**
58
+ el: Elevation in **_degrees_**
59
+ range_rate: Range rate in **_kilometers per second_**
60
+ az_rate: Azimuth rate in **_degrees per second_**
61
+ el_rate: Elevation rate in **_degrees per second_**
62
+ """
63
+
64
+ range: float | None
65
+ azimuth: float
66
+ elevation: float
67
+ range_rate: float | None
68
+ azimuth_rate: float | None
69
+ elevation_rate: float | None
70
+
71
+ def __init__(
72
+ self,
73
+ azimuth: float,
74
+ elevation: float,
75
+ ) -> None: ...
76
+
77
+ class HorizonState:
78
+ """
79
+ Args:
80
+ epoch: UTC epoch of the state
81
+ elements: HorizonElements of the state
82
+ """
83
+
84
+ epoch: Epoch
85
+ """UTC epoch of the state"""
86
+
87
+ elements: HorizonElements
88
+ """Horizon elements of the state"""
89
+
90
+ range: float | None
91
+ """Range in **_kilometers_**"""
92
+
93
+ azimuth: float
94
+ """Azimuth in **_degrees_**"""
95
+
96
+ elevation: float
97
+ """Elevation in **_degrees_**"""
98
+
99
+ range_rate: float | None
100
+ """Range rate in **_kilometers per second_**"""
101
+
102
+ azimuth_rate: float | None
103
+ """Azimuth rate in **_degrees per second_**"""
104
+
105
+ elevation_rate: float | None
106
+ """Elevation rate in **_degrees per second_**"""
107
+
108
+ def __init__(self, epoch: Epoch, elements: HorizonElements) -> None: ...
109
+ @classmethod
110
+ def from_topocentric_state(cls, state: TopocentricState, observer: Observatory) -> HorizonState: ...
7
111
 
8
112
  class KeplerianElements:
9
113
  """
@@ -34,7 +138,11 @@ class KeplerianElements:
34
138
  ) -> None: ...
35
139
 
36
140
  class TLE:
37
- satellite_id: int
141
+
142
+ norad_id: int
143
+ """NORAD catalog ID of the satellite"""
144
+
145
+ satellite_id: str
38
146
  """"""
39
147
 
40
148
  name: str
@@ -88,6 +196,13 @@ class TLE:
88
196
  cartesian_state: CartesianState
89
197
  """TEME cartesian state of the TLE at epoch"""
90
198
 
199
+ semi_major_axis: float
200
+ """Average distance from the central body in **_kilometers_**
201
+
202
+ !!! note
203
+ This is always calculated using Brouwer mean motion and will differ slightly from Kozai-computed SMA.
204
+ """
205
+
91
206
  @classmethod
92
207
  def from_lines(cls, line_1: str, line_2: str, line_3: str | None = None) -> TLE:
93
208
  """
@@ -284,8 +399,8 @@ class Ephemeris:
284
399
  class TopocentricElements:
285
400
  """
286
401
  Args:
287
- ra: TEME right ascension in **_degrees_**
288
- dec: TEME declination in **_degrees_**
402
+ right_ascension: TEME right ascension in **_degrees_**
403
+ declination: TEME declination in **_degrees_**
289
404
  """
290
405
 
291
406
  range: float | None
@@ -302,7 +417,7 @@ class TopocentricElements:
302
417
  declination_rate: float | None
303
418
  """Declination rate in **_degrees per second**"""
304
419
 
305
- def __init__(self, ra: float, dec: float) -> None: ...
420
+ def __init__(self, right_ascension: float, declination: float) -> None: ...
306
421
  @classmethod
307
422
  def from_j2000(cls, epoch: Epoch, ra: float, dec: float) -> TopocentricElements:
308
423
  """
@@ -312,3 +427,44 @@ class TopocentricElements:
312
427
  dec: J2000 declination in **_degrees_**
313
428
  """
314
429
  ...
430
+
431
+ class TopocentricState:
432
+ """
433
+ Args:
434
+ epoch: UTC epoch of the state
435
+ elements: TopocentricElements of the state
436
+ """
437
+
438
+ epoch: Epoch
439
+ """UTC epoch of the state"""
440
+
441
+ elements: TopocentricElements
442
+ """Topocentric elements of the state"""
443
+
444
+ range: float | None
445
+ """Range in **_kilometers_**"""
446
+
447
+ right_ascension: float
448
+ """TEME right ascension in **_degrees_**"""
449
+
450
+ declination: float
451
+ """TEME declination in **_degrees_**"""
452
+
453
+ range_rate: float | None
454
+ """Range rate in **_kilometers per second_**"""
455
+
456
+ right_ascension_rate: float | None
457
+ """Right ascension rate in **_degrees per second**"""
458
+
459
+ declination_rate: float | None
460
+ """Declination rate in **_degrees per second**"""
461
+
462
+ def __init__(self, epoch: Epoch, elements: TopocentricElements) -> None: ...
463
+ @classmethod
464
+ def from_horizon_state(cls, horizon_state: HorizonState, observer: Observatory) -> TopocentricState:
465
+ """
466
+ Args:
467
+ horizon_state: HorizonState of the target
468
+ observer: Position of the observer
469
+ """
470
+ ...
keplemon/estimation.pyi CHANGED
@@ -13,10 +13,13 @@ class Observation:
13
13
  Args:
14
14
  sensor: Sensor that made the observation
15
15
  epoch: Time of the observation
16
- observed_teme_topo: Topocentric elements of the satellite at the time of observation
17
- observer_teme_pos: Position of the observer in TEME coordinates
16
+ observed_teme_topocentric: Topocentric elements of the satellite at the time of observation
17
+ observer_teme_position: Position of the observer in TEME coordinates
18
18
  """
19
19
 
20
+ id: str
21
+ """Unique identifier for the observation"""
22
+
20
23
  sensor: Sensor
21
24
  """Sensor which produced the observation"""
22
25
 
@@ -48,8 +51,8 @@ class Observation:
48
51
  self,
49
52
  sensor: Sensor,
50
53
  epoch: Epoch,
51
- observed_teme_topo: TopocentricElements,
52
- observer_teme_pos: CartesianVector,
54
+ observed_teme_topocentric: TopocentricElements,
55
+ observer_teme_position: CartesianVector,
53
56
  ) -> None: ...
54
57
  def get_residual(self, sat: Satellite) -> ObservationResidual | None:
55
58
  """
keplemon/events.py CHANGED
@@ -1,6 +1,17 @@
1
1
  from keplemon._keplemon.events import ( # type: ignore
2
2
  CloseApproach,
3
3
  CloseApproachReport,
4
+ HorizonAccess,
5
+ HorizonAccessReport,
6
+ FieldOfViewCandidate,
7
+ FieldOfViewReport,
4
8
  )
5
9
 
6
- __all__ = ["CloseApproach", "CloseApproachReport"]
10
+ __all__ = [
11
+ "CloseApproach",
12
+ "CloseApproachReport",
13
+ "HorizonAccess",
14
+ "HorizonAccessReport",
15
+ "FieldOfViewCandidate",
16
+ "FieldOfViewReport",
17
+ ]