nrl-tracker 1.8.0__py3-none-any.whl → 1.9.1__py3-none-any.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.
- {nrl_tracker-1.8.0.dist-info → nrl_tracker-1.9.1.dist-info}/METADATA +2 -2
- {nrl_tracker-1.8.0.dist-info → nrl_tracker-1.9.1.dist-info}/RECORD +32 -28
- pytcl/__init__.py +3 -3
- pytcl/assignment_algorithms/dijkstra_min_cost.py +0 -1
- pytcl/assignment_algorithms/network_simplex.py +0 -2
- pytcl/astronomical/ephemerides.py +8 -4
- pytcl/astronomical/relativity.py +20 -0
- pytcl/containers/__init__.py +19 -8
- pytcl/containers/base.py +82 -9
- pytcl/containers/covertree.py +14 -21
- pytcl/containers/kd_tree.py +18 -45
- pytcl/containers/rtree.py +43 -4
- pytcl/containers/vptree.py +14 -21
- pytcl/core/__init__.py +59 -2
- pytcl/core/constants.py +59 -0
- pytcl/core/exceptions.py +865 -0
- pytcl/core/optional_deps.py +531 -0
- pytcl/core/validation.py +4 -6
- pytcl/dynamic_estimation/kalman/matrix_utils.py +427 -0
- pytcl/dynamic_estimation/kalman/square_root.py +20 -213
- pytcl/dynamic_estimation/kalman/sr_ukf.py +5 -5
- pytcl/dynamic_estimation/kalman/types.py +98 -0
- pytcl/mathematical_functions/signal_processing/detection.py +19 -0
- pytcl/mathematical_functions/transforms/wavelets.py +7 -6
- pytcl/plotting/coordinates.py +25 -27
- pytcl/plotting/ellipses.py +14 -16
- pytcl/plotting/metrics.py +7 -5
- pytcl/plotting/tracks.py +8 -7
- pytcl/terrain/loaders.py +10 -6
- {nrl_tracker-1.8.0.dist-info → nrl_tracker-1.9.1.dist-info}/LICENSE +0 -0
- {nrl_tracker-1.8.0.dist-info → nrl_tracker-1.9.1.dist-info}/WHEEL +0 -0
- {nrl_tracker-1.8.0.dist-info → nrl_tracker-1.9.1.dist-info}/top_level.txt +0 -0
pytcl/containers/kd_tree.py
CHANGED
|
@@ -14,12 +14,17 @@ References
|
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
import logging
|
|
17
|
-
from typing import List,
|
|
17
|
+
from typing import List, Optional, Tuple
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
from numpy.typing import ArrayLike, NDArray
|
|
21
21
|
|
|
22
|
-
from pytcl.containers.base import
|
|
22
|
+
from pytcl.containers.base import NearestNeighborResult # Backward compatibility alias
|
|
23
|
+
from pytcl.containers.base import (
|
|
24
|
+
BaseSpatialIndex,
|
|
25
|
+
NeighborResult,
|
|
26
|
+
validate_query_input,
|
|
27
|
+
)
|
|
23
28
|
|
|
24
29
|
# Module logger
|
|
25
30
|
_logger = logging.getLogger("pytcl.containers.kd_tree")
|
|
@@ -57,21 +62,6 @@ class KDNode:
|
|
|
57
62
|
self.right: Optional["KDNode"] = None
|
|
58
63
|
|
|
59
64
|
|
|
60
|
-
class NearestNeighborResult(NamedTuple):
|
|
61
|
-
"""Result of nearest neighbor query.
|
|
62
|
-
|
|
63
|
-
Attributes
|
|
64
|
-
----------
|
|
65
|
-
indices : ndarray
|
|
66
|
-
Indices of nearest neighbors.
|
|
67
|
-
distances : ndarray
|
|
68
|
-
Distances to nearest neighbors.
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
indices: NDArray[np.intp]
|
|
72
|
-
distances: NDArray[np.floating]
|
|
73
|
-
|
|
74
|
-
|
|
75
65
|
class KDTree(BaseSpatialIndex):
|
|
76
66
|
"""
|
|
77
67
|
K-D Tree for efficient spatial queries.
|
|
@@ -157,7 +147,7 @@ class KDTree(BaseSpatialIndex):
|
|
|
157
147
|
self,
|
|
158
148
|
X: ArrayLike,
|
|
159
149
|
k: int = 1,
|
|
160
|
-
) ->
|
|
150
|
+
) -> NeighborResult:
|
|
161
151
|
"""
|
|
162
152
|
Query the tree for k nearest neighbors.
|
|
163
153
|
|
|
@@ -170,7 +160,7 @@ class KDTree(BaseSpatialIndex):
|
|
|
170
160
|
|
|
171
161
|
Returns
|
|
172
162
|
-------
|
|
173
|
-
result :
|
|
163
|
+
result : NeighborResult
|
|
174
164
|
Indices and distances of k nearest neighbors for each query.
|
|
175
165
|
|
|
176
166
|
Examples
|
|
@@ -195,7 +185,7 @@ class KDTree(BaseSpatialIndex):
|
|
|
195
185
|
all_indices[i, :n_found] = indices
|
|
196
186
|
all_distances[i, :n_found] = distances
|
|
197
187
|
|
|
198
|
-
return
|
|
188
|
+
return NeighborResult(indices=all_indices, distances=all_distances)
|
|
199
189
|
|
|
200
190
|
def _query_single(
|
|
201
191
|
self,
|
|
@@ -308,27 +298,7 @@ class KDTree(BaseSpatialIndex):
|
|
|
308
298
|
_search(self.root)
|
|
309
299
|
return indices
|
|
310
300
|
|
|
311
|
-
|
|
312
|
-
self,
|
|
313
|
-
X: ArrayLike,
|
|
314
|
-
r: float,
|
|
315
|
-
) -> List[List[int]]:
|
|
316
|
-
"""
|
|
317
|
-
Alias for query_radius (scipy compatibility).
|
|
318
|
-
|
|
319
|
-
Parameters
|
|
320
|
-
----------
|
|
321
|
-
X : array_like
|
|
322
|
-
Query points.
|
|
323
|
-
r : float
|
|
324
|
-
Query radius.
|
|
325
|
-
|
|
326
|
-
Returns
|
|
327
|
-
-------
|
|
328
|
-
indices : list of lists
|
|
329
|
-
Indices of points within radius.
|
|
330
|
-
"""
|
|
331
|
-
return self.query_radius(X, r)
|
|
301
|
+
# query_ball_point inherited from BaseSpatialIndex
|
|
332
302
|
|
|
333
303
|
|
|
334
304
|
class BallTree(BaseSpatialIndex):
|
|
@@ -444,7 +414,7 @@ class BallTree(BaseSpatialIndex):
|
|
|
444
414
|
self,
|
|
445
415
|
X: ArrayLike,
|
|
446
416
|
k: int = 1,
|
|
447
|
-
) ->
|
|
417
|
+
) -> NeighborResult:
|
|
448
418
|
"""
|
|
449
419
|
Query the tree for k nearest neighbors.
|
|
450
420
|
|
|
@@ -457,7 +427,7 @@ class BallTree(BaseSpatialIndex):
|
|
|
457
427
|
|
|
458
428
|
Returns
|
|
459
429
|
-------
|
|
460
|
-
result :
|
|
430
|
+
result : NeighborResult
|
|
461
431
|
Indices and distances of k nearest neighbors.
|
|
462
432
|
"""
|
|
463
433
|
X = validate_query_input(X, self.n_features)
|
|
@@ -473,7 +443,9 @@ class BallTree(BaseSpatialIndex):
|
|
|
473
443
|
all_indices[i, :n_found] = indices
|
|
474
444
|
all_distances[i, :n_found] = distances
|
|
475
445
|
|
|
476
|
-
return
|
|
446
|
+
return NeighborResult(indices=all_indices, distances=all_distances)
|
|
447
|
+
|
|
448
|
+
# query_ball_point inherited from BaseSpatialIndex
|
|
477
449
|
|
|
478
450
|
def query_radius(
|
|
479
451
|
self,
|
|
@@ -606,7 +578,8 @@ class BallTree(BaseSpatialIndex):
|
|
|
606
578
|
|
|
607
579
|
__all__ = [
|
|
608
580
|
"KDNode",
|
|
609
|
-
"
|
|
581
|
+
"NeighborResult",
|
|
582
|
+
"NearestNeighborResult", # Backward compatibility alias
|
|
610
583
|
"KDTree",
|
|
611
584
|
"BallTree",
|
|
612
585
|
]
|
pytcl/containers/rtree.py
CHANGED
|
@@ -19,7 +19,11 @@ from typing import List, NamedTuple, Optional, Tuple
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
from numpy.typing import ArrayLike, NDArray
|
|
21
21
|
|
|
22
|
-
from pytcl.containers.base import SpatialQueryResult
|
|
22
|
+
from pytcl.containers.base import SpatialQueryResult # Backward compatibility alias
|
|
23
|
+
from pytcl.containers.base import (
|
|
24
|
+
NeighborResult,
|
|
25
|
+
validate_query_input,
|
|
26
|
+
)
|
|
23
27
|
|
|
24
28
|
# Module logger
|
|
25
29
|
_logger = logging.getLogger("pytcl.containers.rtree")
|
|
@@ -418,7 +422,7 @@ class RTree:
|
|
|
418
422
|
self,
|
|
419
423
|
X: ArrayLike,
|
|
420
424
|
k: int = 1,
|
|
421
|
-
) ->
|
|
425
|
+
) -> NeighborResult:
|
|
422
426
|
"""
|
|
423
427
|
Query the tree for k nearest neighbors.
|
|
424
428
|
|
|
@@ -433,7 +437,7 @@ class RTree:
|
|
|
433
437
|
|
|
434
438
|
Returns
|
|
435
439
|
-------
|
|
436
|
-
result :
|
|
440
|
+
result : NeighborResult
|
|
437
441
|
Indices and distances of k nearest neighbors for each query.
|
|
438
442
|
|
|
439
443
|
Examples
|
|
@@ -460,7 +464,7 @@ class RTree:
|
|
|
460
464
|
all_indices[i, :n_found] = indices
|
|
461
465
|
all_distances[i, :n_found] = distances
|
|
462
466
|
|
|
463
|
-
return
|
|
467
|
+
return NeighborResult(indices=all_indices, distances=all_distances)
|
|
464
468
|
|
|
465
469
|
def query_radius(
|
|
466
470
|
self,
|
|
@@ -529,6 +533,36 @@ class RTree:
|
|
|
529
533
|
|
|
530
534
|
return results
|
|
531
535
|
|
|
536
|
+
def query_ball_point(
|
|
537
|
+
self,
|
|
538
|
+
X: ArrayLike,
|
|
539
|
+
r: float,
|
|
540
|
+
) -> List[List[int]]:
|
|
541
|
+
"""
|
|
542
|
+
Query the tree for all points within radius r.
|
|
543
|
+
|
|
544
|
+
This is an alias for :meth:`query_radius` provided for compatibility
|
|
545
|
+
with scipy.spatial.KDTree.
|
|
546
|
+
|
|
547
|
+
Parameters
|
|
548
|
+
----------
|
|
549
|
+
X : array_like
|
|
550
|
+
Query points of shape (n_queries, n_features) or (n_features,).
|
|
551
|
+
r : float
|
|
552
|
+
Search radius.
|
|
553
|
+
|
|
554
|
+
Returns
|
|
555
|
+
-------
|
|
556
|
+
indices : list of list of int
|
|
557
|
+
For each query point, a list of indices of data points
|
|
558
|
+
within distance r.
|
|
559
|
+
|
|
560
|
+
See Also
|
|
561
|
+
--------
|
|
562
|
+
query_radius : The underlying implementation.
|
|
563
|
+
"""
|
|
564
|
+
return self.query_radius(X, r)
|
|
565
|
+
|
|
532
566
|
def query_intersect(self, query_bbox: BoundingBox) -> RTreeResult:
|
|
533
567
|
"""
|
|
534
568
|
Find all entries intersecting a query box.
|
|
@@ -695,10 +729,15 @@ class RTree:
|
|
|
695
729
|
|
|
696
730
|
|
|
697
731
|
__all__ = [
|
|
732
|
+
# Result types
|
|
733
|
+
"NeighborResult",
|
|
734
|
+
"SpatialQueryResult", # Backward compatibility alias
|
|
735
|
+
# Bounding box utilities
|
|
698
736
|
"BoundingBox",
|
|
699
737
|
"merge_boxes",
|
|
700
738
|
"box_from_point",
|
|
701
739
|
"box_from_points",
|
|
740
|
+
# R-tree components
|
|
702
741
|
"RTreeNode",
|
|
703
742
|
"RTreeResult",
|
|
704
743
|
"RTree",
|
pytcl/containers/vptree.py
CHANGED
|
@@ -12,32 +12,22 @@ References
|
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
import logging
|
|
15
|
-
from typing import Any, Callable, List,
|
|
15
|
+
from typing import Any, Callable, List, Optional, Tuple
|
|
16
16
|
|
|
17
17
|
import numpy as np
|
|
18
18
|
from numpy.typing import ArrayLike, NDArray
|
|
19
19
|
|
|
20
|
-
from pytcl.containers.base import
|
|
20
|
+
from pytcl.containers.base import VPTreeResult # Backward compatibility alias
|
|
21
|
+
from pytcl.containers.base import (
|
|
22
|
+
MetricSpatialIndex,
|
|
23
|
+
NeighborResult,
|
|
24
|
+
validate_query_input,
|
|
25
|
+
)
|
|
21
26
|
|
|
22
27
|
# Module logger
|
|
23
28
|
_logger = logging.getLogger("pytcl.containers.vptree")
|
|
24
29
|
|
|
25
30
|
|
|
26
|
-
class VPTreeResult(NamedTuple):
|
|
27
|
-
"""Result of VP-tree query.
|
|
28
|
-
|
|
29
|
-
Attributes
|
|
30
|
-
----------
|
|
31
|
-
indices : ndarray
|
|
32
|
-
Indices of nearest neighbors.
|
|
33
|
-
distances : ndarray
|
|
34
|
-
Distances to nearest neighbors.
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
indices: NDArray[np.intp]
|
|
38
|
-
distances: NDArray[np.floating]
|
|
39
|
-
|
|
40
|
-
|
|
41
31
|
class VPNode:
|
|
42
32
|
"""Node in a VP-tree.
|
|
43
33
|
|
|
@@ -154,7 +144,7 @@ class VPTree(MetricSpatialIndex):
|
|
|
154
144
|
self,
|
|
155
145
|
X: ArrayLike,
|
|
156
146
|
k: int = 1,
|
|
157
|
-
) ->
|
|
147
|
+
) -> NeighborResult:
|
|
158
148
|
"""
|
|
159
149
|
Query the tree for k nearest neighbors.
|
|
160
150
|
|
|
@@ -167,7 +157,7 @@ class VPTree(MetricSpatialIndex):
|
|
|
167
157
|
|
|
168
158
|
Returns
|
|
169
159
|
-------
|
|
170
|
-
result :
|
|
160
|
+
result : NeighborResult
|
|
171
161
|
Indices and distances of k nearest neighbors.
|
|
172
162
|
"""
|
|
173
163
|
X = validate_query_input(X, self.n_features)
|
|
@@ -184,7 +174,9 @@ class VPTree(MetricSpatialIndex):
|
|
|
184
174
|
all_indices[i, :n_found] = indices
|
|
185
175
|
all_distances[i, :n_found] = distances
|
|
186
176
|
|
|
187
|
-
return
|
|
177
|
+
return NeighborResult(indices=all_indices, distances=all_distances)
|
|
178
|
+
|
|
179
|
+
# query_ball_point inherited from BaseSpatialIndex
|
|
188
180
|
|
|
189
181
|
def _query_single(
|
|
190
182
|
self,
|
|
@@ -295,7 +287,8 @@ class VPTree(MetricSpatialIndex):
|
|
|
295
287
|
|
|
296
288
|
|
|
297
289
|
__all__ = [
|
|
298
|
-
"
|
|
290
|
+
"NeighborResult",
|
|
291
|
+
"VPTreeResult", # Backward compatibility alias
|
|
299
292
|
"VPNode",
|
|
300
293
|
"VPTree",
|
|
301
294
|
]
|
pytcl/core/__init__.py
CHANGED
|
@@ -5,6 +5,8 @@ This module provides foundational functionality used throughout the library:
|
|
|
5
5
|
- Physical and mathematical constants
|
|
6
6
|
- Input validation utilities
|
|
7
7
|
- Array manipulation helpers compatible with MATLAB conventions
|
|
8
|
+
- Custom exception hierarchy for consistent error handling
|
|
9
|
+
- Optional dependency management
|
|
8
10
|
"""
|
|
9
11
|
|
|
10
12
|
from pytcl.core.array_utils import (
|
|
@@ -23,10 +25,36 @@ from pytcl.core.constants import (
|
|
|
23
25
|
WGS84,
|
|
24
26
|
PhysicalConstants,
|
|
25
27
|
)
|
|
28
|
+
from pytcl.core.exceptions import (
|
|
29
|
+
ComputationError,
|
|
30
|
+
ConfigurationError,
|
|
31
|
+
ConvergenceError,
|
|
32
|
+
DataError,
|
|
33
|
+
DependencyError,
|
|
34
|
+
DimensionError,
|
|
35
|
+
EmptyContainerError,
|
|
36
|
+
FormatError,
|
|
37
|
+
MethodError,
|
|
38
|
+
NumericalError,
|
|
39
|
+
ParameterError,
|
|
40
|
+
ParseError,
|
|
41
|
+
RangeError,
|
|
42
|
+
SingularMatrixError,
|
|
43
|
+
StateError,
|
|
44
|
+
TCLError,
|
|
45
|
+
UninitializedError,
|
|
46
|
+
ValidationError,
|
|
47
|
+
)
|
|
48
|
+
from pytcl.core.optional_deps import (
|
|
49
|
+
LazyModule,
|
|
50
|
+
check_dependencies,
|
|
51
|
+
import_optional,
|
|
52
|
+
is_available,
|
|
53
|
+
requires,
|
|
54
|
+
)
|
|
26
55
|
from pytcl.core.validation import (
|
|
27
56
|
ArraySpec,
|
|
28
57
|
ScalarSpec,
|
|
29
|
-
ValidationError,
|
|
30
58
|
check_compatible_shapes,
|
|
31
59
|
ensure_2d,
|
|
32
60
|
ensure_column_vector,
|
|
@@ -48,8 +76,31 @@ __all__ = [
|
|
|
48
76
|
"EARTH_ROTATION_RATE",
|
|
49
77
|
"WGS84",
|
|
50
78
|
"PhysicalConstants",
|
|
51
|
-
#
|
|
79
|
+
# Exceptions (base)
|
|
80
|
+
"TCLError",
|
|
81
|
+
# Exceptions (validation)
|
|
52
82
|
"ValidationError",
|
|
83
|
+
"DimensionError",
|
|
84
|
+
"ParameterError",
|
|
85
|
+
"RangeError",
|
|
86
|
+
# Exceptions (computation)
|
|
87
|
+
"ComputationError",
|
|
88
|
+
"ConvergenceError",
|
|
89
|
+
"NumericalError",
|
|
90
|
+
"SingularMatrixError",
|
|
91
|
+
# Exceptions (state)
|
|
92
|
+
"StateError",
|
|
93
|
+
"UninitializedError",
|
|
94
|
+
"EmptyContainerError",
|
|
95
|
+
# Exceptions (configuration)
|
|
96
|
+
"ConfigurationError",
|
|
97
|
+
"MethodError",
|
|
98
|
+
"DependencyError",
|
|
99
|
+
# Exceptions (data)
|
|
100
|
+
"DataError",
|
|
101
|
+
"FormatError",
|
|
102
|
+
"ParseError",
|
|
103
|
+
# Validation utilities
|
|
53
104
|
"validate_array",
|
|
54
105
|
"validate_inputs",
|
|
55
106
|
"validate_same_shape",
|
|
@@ -68,4 +119,10 @@ __all__ = [
|
|
|
68
119
|
"wrap_to_range",
|
|
69
120
|
"column_vector",
|
|
70
121
|
"row_vector",
|
|
122
|
+
# Optional dependencies
|
|
123
|
+
"is_available",
|
|
124
|
+
"import_optional",
|
|
125
|
+
"requires",
|
|
126
|
+
"check_dependencies",
|
|
127
|
+
"LazyModule",
|
|
71
128
|
]
|
pytcl/core/constants.py
CHANGED
|
@@ -317,3 +317,62 @@ c = SPEED_OF_LIGHT
|
|
|
317
317
|
|
|
318
318
|
#: Alias for GRAVITATIONAL_CONSTANT
|
|
319
319
|
G = GRAVITATIONAL_CONSTANT
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
__all__ = [
|
|
323
|
+
# Universal Physical Constants
|
|
324
|
+
"SPEED_OF_LIGHT",
|
|
325
|
+
"GRAVITATIONAL_CONSTANT",
|
|
326
|
+
"PLANCK_CONSTANT",
|
|
327
|
+
"BOLTZMANN_CONSTANT",
|
|
328
|
+
"STEFAN_BOLTZMANN_CONSTANT",
|
|
329
|
+
"ELEMENTARY_CHARGE",
|
|
330
|
+
"AVOGADRO_CONSTANT",
|
|
331
|
+
"UNIVERSAL_GAS_CONSTANT",
|
|
332
|
+
"STANDARD_ATMOSPHERE",
|
|
333
|
+
"ABSOLUTE_ZERO_CELSIUS",
|
|
334
|
+
# Earth Parameters
|
|
335
|
+
"EARTH_SEMI_MAJOR_AXIS",
|
|
336
|
+
"EARTH_SEMI_MINOR_AXIS",
|
|
337
|
+
"EARTH_FLATTENING",
|
|
338
|
+
"EARTH_ECCENTRICITY_SQ",
|
|
339
|
+
"EARTH_ECCENTRICITY",
|
|
340
|
+
"EARTH_ECCENTRICITY_PRIME_SQ",
|
|
341
|
+
"EARTH_ROTATION_RATE",
|
|
342
|
+
"EARTH_GM",
|
|
343
|
+
"EARTH_GM_EGM2008",
|
|
344
|
+
"EARTH_MEAN_ANGULAR_VELOCITY",
|
|
345
|
+
"EARTH_MEAN_RADIUS",
|
|
346
|
+
"STANDARD_GRAVITY",
|
|
347
|
+
# Time Constants
|
|
348
|
+
"SECONDS_PER_DAY",
|
|
349
|
+
"SECONDS_PER_JULIAN_CENTURY",
|
|
350
|
+
"DAYS_PER_JULIAN_YEAR",
|
|
351
|
+
"DAYS_PER_JULIAN_CENTURY",
|
|
352
|
+
"J2000_EPOCH_JD",
|
|
353
|
+
"MJD_OFFSET",
|
|
354
|
+
# Mathematical Constants
|
|
355
|
+
"PI",
|
|
356
|
+
"TWO_PI",
|
|
357
|
+
"HALF_PI",
|
|
358
|
+
"DEG_TO_RAD",
|
|
359
|
+
"RAD_TO_DEG",
|
|
360
|
+
"ARCSEC_TO_RAD",
|
|
361
|
+
"RAD_TO_ARCSEC",
|
|
362
|
+
# Dataclasses
|
|
363
|
+
"EllipsoidParameters",
|
|
364
|
+
"PhysicalConstants",
|
|
365
|
+
# Ellipsoid Instances
|
|
366
|
+
"WGS84",
|
|
367
|
+
"GRS80",
|
|
368
|
+
"CLARKE1866",
|
|
369
|
+
"SPHERE_EARTH",
|
|
370
|
+
# Solar System Parameters
|
|
371
|
+
"ASTRONOMICAL_UNIT",
|
|
372
|
+
"SUN_GM",
|
|
373
|
+
"MOON_GM",
|
|
374
|
+
"EARTH_MOON_MASS_RATIO",
|
|
375
|
+
# Aliases
|
|
376
|
+
"c",
|
|
377
|
+
"G",
|
|
378
|
+
]
|