nrl-tracker 1.8.0__py3-none-any.whl → 1.9.0__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.
@@ -14,12 +14,17 @@ References
14
14
  """
15
15
 
16
16
  import logging
17
- from typing import List, NamedTuple, Optional, Tuple
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 BaseSpatialIndex, validate_query_input
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
- ) -> NearestNeighborResult:
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 : NearestNeighborResult
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 NearestNeighborResult(indices=all_indices, distances=all_distances)
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
- def query_ball_point(
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
- ) -> NearestNeighborResult:
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 : NearestNeighborResult
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 NearestNeighborResult(indices=all_indices, distances=all_distances)
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
- "NearestNeighborResult",
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, validate_query_input
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
- ) -> SpatialQueryResult:
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 : SpatialQueryResult
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 SpatialQueryResult(indices=all_indices, distances=all_distances)
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",
@@ -12,32 +12,22 @@ References
12
12
  """
13
13
 
14
14
  import logging
15
- from typing import Any, Callable, List, NamedTuple, Optional, Tuple
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 MetricSpatialIndex, validate_query_input
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
- ) -> VPTreeResult:
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 : VPTreeResult
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 VPTreeResult(indices=all_indices, distances=all_distances)
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
- "VPTreeResult",
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
- # Validation
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
+ ]