nrl-tracker 1.8.0__tar.gz → 1.9.0__tar.gz

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.
Files changed (233) hide show
  1. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/CONTRIBUTING.md +6 -6
  2. {nrl_tracker-1.8.0/nrl_tracker.egg-info → nrl_tracker-1.9.0}/PKG-INFO +2 -2
  3. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/README.md +1 -1
  4. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0/nrl_tracker.egg-info}/PKG-INFO +2 -2
  5. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/nrl_tracker.egg-info/SOURCES.txt +6 -0
  6. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pyproject.toml +1 -1
  7. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/__init__.py +3 -3
  8. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/dijkstra_min_cost.py +0 -1
  9. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/network_simplex.py +0 -2
  10. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/astronomical/ephemerides.py +8 -4
  11. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/astronomical/relativity.py +20 -0
  12. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/containers/__init__.py +19 -8
  13. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/containers/base.py +82 -9
  14. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/containers/covertree.py +14 -21
  15. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/containers/kd_tree.py +18 -45
  16. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/containers/rtree.py +43 -4
  17. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/containers/vptree.py +14 -21
  18. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/core/__init__.py +59 -2
  19. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/core/constants.py +59 -0
  20. nrl_tracker-1.9.0/pytcl/core/exceptions.py +865 -0
  21. nrl_tracker-1.9.0/pytcl/core/optional_deps.py +531 -0
  22. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/core/validation.py +4 -6
  23. nrl_tracker-1.9.0/pytcl/dynamic_estimation/kalman/matrix_utils.py +427 -0
  24. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/kalman/square_root.py +20 -213
  25. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/kalman/sr_ukf.py +5 -5
  26. nrl_tracker-1.9.0/pytcl/dynamic_estimation/kalman/types.py +98 -0
  27. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/signal_processing/detection.py +19 -0
  28. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/transforms/wavelets.py +7 -6
  29. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/plotting/coordinates.py +25 -27
  30. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/plotting/ellipses.py +14 -16
  31. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/plotting/metrics.py +7 -5
  32. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/plotting/tracks.py +8 -7
  33. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/terrain/loaders.py +10 -6
  34. nrl_tracker-1.9.0/tests/test_exceptions.py +328 -0
  35. nrl_tracker-1.9.0/tests/test_optional_deps.py +361 -0
  36. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/LICENSE +0 -0
  37. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/MANIFEST.in +0 -0
  38. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/nrl_tracker.egg-info/dependency_links.txt +0 -0
  39. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/nrl_tracker.egg-info/requires.txt +0 -0
  40. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/nrl_tracker.egg-info/top_level.txt +0 -0
  41. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/__init__.py +0 -0
  42. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/data_association.py +0 -0
  43. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/gating.py +0 -0
  44. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/jpda.py +0 -0
  45. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/nd_assignment.py +0 -0
  46. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/network_flow.py +0 -0
  47. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/three_dimensional/__init__.py +0 -0
  48. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/three_dimensional/assignment.py +0 -0
  49. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/two_dimensional/__init__.py +0 -0
  50. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/two_dimensional/assignment.py +0 -0
  51. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/assignment_algorithms/two_dimensional/kbest.py +0 -0
  52. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/astronomical/__init__.py +0 -0
  53. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/astronomical/lambert.py +0 -0
  54. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/astronomical/orbital_mechanics.py +0 -0
  55. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/astronomical/reference_frames.py +0 -0
  56. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/astronomical/sgp4.py +0 -0
  57. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/astronomical/special_orbits.py +0 -0
  58. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/astronomical/time_systems.py +0 -0
  59. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/astronomical/tle.py +0 -0
  60. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/atmosphere/__init__.py +0 -0
  61. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/atmosphere/ionosphere.py +0 -0
  62. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/atmosphere/models.py +0 -0
  63. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/atmosphere/nrlmsise00.py +0 -0
  64. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/clustering/__init__.py +0 -0
  65. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/clustering/dbscan.py +0 -0
  66. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/clustering/gaussian_mixture.py +0 -0
  67. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/clustering/hierarchical.py +0 -0
  68. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/clustering/kmeans.py +0 -0
  69. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/containers/cluster_set.py +0 -0
  70. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/containers/measurement_set.py +0 -0
  71. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/containers/track_list.py +0 -0
  72. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/coordinate_systems/__init__.py +0 -0
  73. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/coordinate_systems/conversions/__init__.py +0 -0
  74. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/coordinate_systems/conversions/geodetic.py +0 -0
  75. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/coordinate_systems/conversions/spherical.py +0 -0
  76. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/coordinate_systems/jacobians/__init__.py +0 -0
  77. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/coordinate_systems/jacobians/jacobians.py +0 -0
  78. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/coordinate_systems/projections/__init__.py +0 -0
  79. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/coordinate_systems/projections/projections.py +0 -0
  80. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/coordinate_systems/rotations/__init__.py +0 -0
  81. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/coordinate_systems/rotations/rotations.py +0 -0
  82. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/core/array_utils.py +0 -0
  83. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/__init__.py +0 -0
  84. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/batch_estimation/__init__.py +0 -0
  85. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/gaussian_sum_filter.py +0 -0
  86. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/imm.py +0 -0
  87. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/information_filter.py +0 -0
  88. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/kalman/__init__.py +0 -0
  89. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/kalman/constrained.py +0 -0
  90. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/kalman/extended.py +0 -0
  91. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/kalman/h_infinity.py +0 -0
  92. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/kalman/linear.py +0 -0
  93. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/kalman/ud_filter.py +0 -0
  94. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/kalman/unscented.py +0 -0
  95. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/measurement_update/__init__.py +0 -0
  96. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/particle_filters/__init__.py +0 -0
  97. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/particle_filters/bootstrap.py +0 -0
  98. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/rbpf.py +0 -0
  99. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_estimation/smoothers.py +0 -0
  100. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/__init__.py +0 -0
  101. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/continuous_time/__init__.py +0 -0
  102. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/continuous_time/dynamics.py +0 -0
  103. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/discrete_time/__init__.py +0 -0
  104. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/discrete_time/coordinated_turn.py +0 -0
  105. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/discrete_time/polynomial.py +0 -0
  106. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/discrete_time/singer.py +0 -0
  107. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/process_noise/__init__.py +0 -0
  108. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/process_noise/coordinated_turn.py +0 -0
  109. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/process_noise/polynomial.py +0 -0
  110. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/dynamic_models/process_noise/singer.py +0 -0
  111. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/gravity/__init__.py +0 -0
  112. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/gravity/clenshaw.py +0 -0
  113. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/gravity/egm.py +0 -0
  114. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/gravity/models.py +0 -0
  115. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/gravity/spherical_harmonics.py +0 -0
  116. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/gravity/tides.py +0 -0
  117. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/logging_config.py +0 -0
  118. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/magnetism/__init__.py +0 -0
  119. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/magnetism/emm.py +0 -0
  120. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/magnetism/igrf.py +0 -0
  121. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/magnetism/wmm.py +0 -0
  122. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/__init__.py +0 -0
  123. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/basic_matrix/__init__.py +0 -0
  124. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/basic_matrix/decompositions.py +0 -0
  125. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/basic_matrix/special_matrices.py +0 -0
  126. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/combinatorics/__init__.py +0 -0
  127. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/combinatorics/combinatorics.py +0 -0
  128. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/continuous_optimization/__init__.py +0 -0
  129. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/geometry/__init__.py +0 -0
  130. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/geometry/geometry.py +0 -0
  131. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/interpolation/__init__.py +0 -0
  132. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/interpolation/interpolation.py +0 -0
  133. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/numerical_integration/__init__.py +0 -0
  134. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/numerical_integration/quadrature.py +0 -0
  135. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/polynomials/__init__.py +0 -0
  136. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/signal_processing/__init__.py +0 -0
  137. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/signal_processing/filters.py +0 -0
  138. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/signal_processing/matched_filter.py +0 -0
  139. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/special_functions/__init__.py +0 -0
  140. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/special_functions/bessel.py +0 -0
  141. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/special_functions/debye.py +0 -0
  142. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/special_functions/elliptic.py +0 -0
  143. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/special_functions/error_functions.py +0 -0
  144. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/special_functions/gamma_functions.py +0 -0
  145. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/special_functions/hypergeometric.py +0 -0
  146. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/special_functions/lambert_w.py +0 -0
  147. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/special_functions/marcum_q.py +0 -0
  148. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/statistics/__init__.py +0 -0
  149. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/statistics/distributions.py +0 -0
  150. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/statistics/estimators.py +0 -0
  151. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/transforms/__init__.py +0 -0
  152. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/transforms/fourier.py +0 -0
  153. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/mathematical_functions/transforms/stft.py +0 -0
  154. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/misc/__init__.py +0 -0
  155. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/navigation/__init__.py +0 -0
  156. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/navigation/geodesy.py +0 -0
  157. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/navigation/great_circle.py +0 -0
  158. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/navigation/ins.py +0 -0
  159. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/navigation/ins_gnss.py +0 -0
  160. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/navigation/rhumb.py +0 -0
  161. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/performance_evaluation/__init__.py +0 -0
  162. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/performance_evaluation/estimation_metrics.py +0 -0
  163. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/performance_evaluation/track_metrics.py +0 -0
  164. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/physical_values/__init__.py +0 -0
  165. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/plotting/__init__.py +0 -0
  166. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/scheduling/__init__.py +0 -0
  167. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/static_estimation/__init__.py +0 -0
  168. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/static_estimation/least_squares.py +0 -0
  169. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/static_estimation/maximum_likelihood.py +0 -0
  170. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/static_estimation/robust.py +0 -0
  171. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/terrain/__init__.py +0 -0
  172. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/terrain/dem.py +0 -0
  173. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/terrain/visibility.py +0 -0
  174. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/trackers/__init__.py +0 -0
  175. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/trackers/hypothesis.py +0 -0
  176. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/trackers/mht.py +0 -0
  177. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/trackers/multi_target.py +0 -0
  178. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/trackers/single_target.py +0 -0
  179. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/pytcl/transponders/__init__.py +0 -0
  180. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/setup.cfg +0 -0
  181. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/__init__.py +0 -0
  182. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/conftest.py +0 -0
  183. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_additional_trees.py +0 -0
  184. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_assignment_algorithms.py +0 -0
  185. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_astronomical.py +0 -0
  186. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_clustering.py +0 -0
  187. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_constrained_ekf.py +0 -0
  188. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_coordinate_systems.py +0 -0
  189. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_coverage_boost.py +0 -0
  190. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_coverage_boost_2.py +0 -0
  191. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_dynamic_models.py +0 -0
  192. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_egm.py +0 -0
  193. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_emm.py +0 -0
  194. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_ephemerides.py +0 -0
  195. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_gaussian_mixtures.py +0 -0
  196. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_gaussian_sum_filter.py +0 -0
  197. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_geophysical.py +0 -0
  198. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_great_circle.py +0 -0
  199. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_h_infinity.py +0 -0
  200. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_ins.py +0 -0
  201. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_ins_gnss.py +0 -0
  202. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_jpda.py +0 -0
  203. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_kalman_filters.py +0 -0
  204. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_mathematical_functions.py +0 -0
  205. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_maximum_likelihood.py +0 -0
  206. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_mht.py +0 -0
  207. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_nd_assignment.py +0 -0
  208. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_network_flow.py +0 -0
  209. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_nrlmsise00.py +0 -0
  210. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_performance_evaluation.py +0 -0
  211. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_phase6_specialized.py +0 -0
  212. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_plotting.py +0 -0
  213. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_projections.py +0 -0
  214. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_rbpf.py +0 -0
  215. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_relativity.py +0 -0
  216. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_rhumb.py +0 -0
  217. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_sgp4.py +0 -0
  218. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_signal_processing.py +0 -0
  219. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_smoothers.py +0 -0
  220. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_spatial_containers_parametrized.py +0 -0
  221. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_spatial_structures.py +0 -0
  222. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_special_functions.py +0 -0
  223. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_special_orbits.py +0 -0
  224. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_static_estimation.py +0 -0
  225. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_terrain.py +0 -0
  226. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_terrain_loaders.py +0 -0
  227. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_tides.py +0 -0
  228. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_tod_mod.py +0 -0
  229. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_trackers.py +0 -0
  230. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_tracking_containers.py +0 -0
  231. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_transforms.py +0 -0
  232. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/test_validation.py +0 -0
  233. {nrl_tracker-1.8.0 → nrl_tracker-1.9.0}/tests/unit/test_core.py +0 -0
@@ -222,10 +222,10 @@ When porting a function from the original MATLAB library:
222
222
 
223
223
  ## Current Development Status
224
224
 
225
- **Version:** v1.8.0
226
- **MATLAB Parity:** 100% ✅
227
- **Test Suite:** 2,057 tests passing (13 skipped for Phase 1 optimization)
228
- **Code Coverage:** 76% (target 80%+ in v2.0.0)
225
+ **Version:** v1.9.0
226
+ **MATLAB Parity:** 100% ✅
227
+ **Test Suite:** 2,133 tests passing
228
+ **Code Coverage:** 76% (target 80%+ in v2.0.0)
229
229
  **Quality:** 100% compliance (black, isort, flake8, mypy --strict)
230
230
 
231
231
  ## v2.0.0 Roadmap - 8 Phases Over 18 Months
@@ -301,10 +301,10 @@ pytest --collect-only -q | tail -1
301
301
  pytest --cov=pytcl --cov-report=term
302
302
  ```
303
303
 
304
- Current metrics (v1.8.0):
304
+ Current metrics (v1.9.0):
305
305
  - **Functions:** 1,070+
306
306
  - **Modules:** 150+
307
- - **Tests:** 2,070 (all passing)
307
+ - **Tests:** 2,133 (all passing)
308
308
  - **Coverage:** 76%
309
309
  - **MATLAB Parity:** 100%
310
310
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nrl-tracker
3
- Version: 1.8.0
3
+ Version: 1.9.0
4
4
  Summary: Python port of the U.S. Naval Research Laboratory's Tracker Component Library for target tracking algorithms
5
5
  Author: Original: David F. Crouse, Naval Research Laboratory
6
6
  Maintainer: Python Port Contributors
@@ -63,7 +63,7 @@ Requires-Dist: nrl-tracker[astronomy,dev,geodesy,optimization,signal,visualizati
63
63
 
64
64
  # Tracker Component Library (Python)
65
65
 
66
- [![PyPI version](https://img.shields.io/badge/pypi-v1.8.0-blue.svg)](https://pypi.org/project/nrl-tracker/)
66
+ [![PyPI version](https://img.shields.io/badge/pypi-v1.9.0-blue.svg)](https://pypi.org/project/nrl-tracker/)
67
67
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
68
68
  [![License: Public Domain](https://img.shields.io/badge/License-Public%20Domain-brightgreen.svg)](https://en.wikipedia.org/wiki/Public_domain)
69
69
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
@@ -1,6 +1,6 @@
1
1
  # Tracker Component Library (Python)
2
2
 
3
- [![PyPI version](https://img.shields.io/badge/pypi-v1.8.0-blue.svg)](https://pypi.org/project/nrl-tracker/)
3
+ [![PyPI version](https://img.shields.io/badge/pypi-v1.9.0-blue.svg)](https://pypi.org/project/nrl-tracker/)
4
4
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
5
5
  [![License: Public Domain](https://img.shields.io/badge/License-Public%20Domain-brightgreen.svg)](https://en.wikipedia.org/wiki/Public_domain)
6
6
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nrl-tracker
3
- Version: 1.8.0
3
+ Version: 1.9.0
4
4
  Summary: Python port of the U.S. Naval Research Laboratory's Tracker Component Library for target tracking algorithms
5
5
  Author: Original: David F. Crouse, Naval Research Laboratory
6
6
  Maintainer: Python Port Contributors
@@ -63,7 +63,7 @@ Requires-Dist: nrl-tracker[astronomy,dev,geodesy,optimization,signal,visualizati
63
63
 
64
64
  # Tracker Component Library (Python)
65
65
 
66
- [![PyPI version](https://img.shields.io/badge/pypi-v1.8.0-blue.svg)](https://pypi.org/project/nrl-tracker/)
66
+ [![PyPI version](https://img.shields.io/badge/pypi-v1.9.0-blue.svg)](https://pypi.org/project/nrl-tracker/)
67
67
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
68
68
  [![License: Public Domain](https://img.shields.io/badge/License-Public%20Domain-brightgreen.svg)](https://en.wikipedia.org/wiki/Public_domain)
69
69
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
@@ -64,6 +64,8 @@ pytcl/coordinate_systems/rotations/rotations.py
64
64
  pytcl/core/__init__.py
65
65
  pytcl/core/array_utils.py
66
66
  pytcl/core/constants.py
67
+ pytcl/core/exceptions.py
68
+ pytcl/core/optional_deps.py
67
69
  pytcl/core/validation.py
68
70
  pytcl/dynamic_estimation/__init__.py
69
71
  pytcl/dynamic_estimation/gaussian_sum_filter.py
@@ -77,8 +79,10 @@ pytcl/dynamic_estimation/kalman/constrained.py
77
79
  pytcl/dynamic_estimation/kalman/extended.py
78
80
  pytcl/dynamic_estimation/kalman/h_infinity.py
79
81
  pytcl/dynamic_estimation/kalman/linear.py
82
+ pytcl/dynamic_estimation/kalman/matrix_utils.py
80
83
  pytcl/dynamic_estimation/kalman/square_root.py
81
84
  pytcl/dynamic_estimation/kalman/sr_ukf.py
85
+ pytcl/dynamic_estimation/kalman/types.py
82
86
  pytcl/dynamic_estimation/kalman/ud_filter.py
83
87
  pytcl/dynamic_estimation/kalman/unscented.py
84
88
  pytcl/dynamic_estimation/measurement_update/__init__.py
@@ -184,6 +188,7 @@ tests/test_dynamic_models.py
184
188
  tests/test_egm.py
185
189
  tests/test_emm.py
186
190
  tests/test_ephemerides.py
191
+ tests/test_exceptions.py
187
192
  tests/test_gaussian_mixtures.py
188
193
  tests/test_gaussian_sum_filter.py
189
194
  tests/test_geophysical.py
@@ -199,6 +204,7 @@ tests/test_mht.py
199
204
  tests/test_nd_assignment.py
200
205
  tests/test_network_flow.py
201
206
  tests/test_nrlmsise00.py
207
+ tests/test_optional_deps.py
202
208
  tests/test_performance_evaluation.py
203
209
  tests/test_phase6_specialized.py
204
210
  tests/test_plotting.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "nrl-tracker"
7
- version = "1.8.0"
7
+ version = "1.9.0"
8
8
  description = "Python port of the U.S. Naval Research Laboratory's Tracker Component Library for target tracking algorithms"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -6,8 +6,8 @@ systems, dynamic models, estimation algorithms, and mathematical functions.
6
6
 
7
7
  This is a Python port of the U.S. Naval Research Laboratory's Tracker Component
8
8
  Library originally written in MATLAB.
9
- **Current Version:** 1.8.0 (January 4, 2026)
10
- **Status:** Production-ready, 2,070 tests passing, 76% line coverage
9
+ **Current Version:** 1.9.0 (January 4, 2026)
10
+ **Status:** Production-ready, 2,133 tests passing, 76% line coverage
11
11
  Examples
12
12
  --------
13
13
  >>> import pytcl as pytcl
@@ -21,7 +21,7 @@ References
21
21
  no. 5, pp. 18-27, May 2017.
22
22
  """
23
23
 
24
- __version__ = "1.8.0"
24
+ __version__ = "1.9.0"
25
25
  __author__ = "Python Port Contributors"
26
26
  __original_author__ = "David F. Crouse, Naval Research Laboratory"
27
27
 
@@ -21,7 +21,6 @@ This is based on:
21
21
  """
22
22
 
23
23
  import heapq
24
- from collections.abc import Sequence
25
24
  from typing import Any
26
25
 
27
26
  import numpy as np
@@ -21,8 +21,6 @@ This is empirically faster than pure successive shortest paths because:
21
21
  - Better cache locality
22
22
  """
23
23
 
24
- from typing import Any
25
-
26
24
  import numpy as np
27
25
  from numpy.typing import NDArray
28
26
 
@@ -54,6 +54,8 @@ from typing import Any, Literal, Optional, Tuple
54
54
  import numpy as np
55
55
  from numpy.typing import NDArray
56
56
 
57
+ from pytcl.core.exceptions import DependencyError
58
+
57
59
  # Constants for unit conversion
58
60
  AU_PER_KM = 1.0 / 149597870.7 # 1 AU in km
59
61
  KM_PER_DAY_TO_AU_PER_DAY = AU_PER_KM # velocity conversion factor
@@ -94,7 +96,7 @@ class DEEphemeris:
94
96
 
95
97
  Raises
96
98
  ------
97
- ImportError
99
+ DependencyError
98
100
  If jplephem is not installed
99
101
  ValueError
100
102
  If version is not recognized
@@ -145,9 +147,11 @@ class DEEphemeris:
145
147
  try:
146
148
  import jplephem
147
149
  except ImportError as e:
148
- raise ImportError(
149
- "jplephem is required for ephemeris access. "
150
- "Install with: pip install jplephem"
150
+ raise DependencyError(
151
+ "jplephem is required for ephemeris access.",
152
+ package="jplephem",
153
+ feature="JPL ephemeris access",
154
+ install_command="pip install pytcl[astronomy]",
151
155
  ) from e
152
156
 
153
157
  self.version = version
@@ -471,3 +471,23 @@ def relativistic_range_correction(
471
471
  doppler_correction = (relative_velocity**2) / (3.0 * C_LIGHT**2)
472
472
 
473
473
  return grav_correction + doppler_correction
474
+
475
+
476
+ __all__ = [
477
+ # Constants
478
+ "C_LIGHT",
479
+ "G_GRAV",
480
+ "GM_EARTH",
481
+ "GM_SUN",
482
+ "AU",
483
+ # Functions
484
+ "schwarzschild_radius",
485
+ "gravitational_time_dilation",
486
+ "proper_time_rate",
487
+ "shapiro_delay",
488
+ "schwarzschild_precession_per_orbit",
489
+ "post_newtonian_acceleration",
490
+ "geodetic_precession",
491
+ "lense_thirring_precession",
492
+ "relativistic_range_correction",
493
+ ]
@@ -20,8 +20,17 @@ a common interface for k-nearest neighbor and radius queries:
20
20
 
21
21
  from pytcl.containers.base import (
22
22
  BaseSpatialIndex,
23
+ CoverTreeResult,
23
24
  MetricSpatialIndex,
25
+ NearestNeighborResult,
26
+ NeighborResult,
27
+ )
28
+ from pytcl.containers.base import (
29
+ RTreeResult as RTreeQueryResult, # Backward compatibility aliases; Avoid conflict with rtree.RTreeResult
30
+ )
31
+ from pytcl.containers.base import (
24
32
  SpatialQueryResult,
33
+ VPTreeResult,
25
34
  validate_query_input,
26
35
  )
27
36
  from pytcl.containers.cluster_set import (
@@ -32,8 +41,8 @@ from pytcl.containers.cluster_set import (
32
41
  cluster_tracks_kmeans,
33
42
  compute_cluster_centroid,
34
43
  )
35
- from pytcl.containers.covertree import CoverTree, CoverTreeNode, CoverTreeResult
36
- from pytcl.containers.kd_tree import BallTree, KDNode, KDTree, NearestNeighborResult
44
+ from pytcl.containers.covertree import CoverTree, CoverTreeNode
45
+ from pytcl.containers.kd_tree import BallTree, KDNode, KDTree
37
46
  from pytcl.containers.measurement_set import (
38
47
  Measurement,
39
48
  MeasurementQuery,
@@ -49,17 +58,21 @@ from pytcl.containers.rtree import (
49
58
  merge_boxes,
50
59
  )
51
60
  from pytcl.containers.track_list import TrackList, TrackListStats, TrackQuery
52
- from pytcl.containers.vptree import VPNode, VPTree, VPTreeResult
61
+ from pytcl.containers.vptree import VPNode, VPTree
53
62
 
54
63
  __all__ = [
55
- # Base classes
64
+ # Base classes and unified result type
56
65
  "BaseSpatialIndex",
57
66
  "MetricSpatialIndex",
58
- "SpatialQueryResult",
67
+ "NeighborResult",
59
68
  "validate_query_input",
69
+ # Backward compatibility aliases for result types
70
+ "SpatialQueryResult",
71
+ "NearestNeighborResult",
72
+ "VPTreeResult",
73
+ "CoverTreeResult",
60
74
  # K-D Tree
61
75
  "KDNode",
62
- "NearestNeighborResult",
63
76
  "KDTree",
64
77
  "BallTree",
65
78
  # R-Tree
@@ -71,11 +84,9 @@ __all__ = [
71
84
  "RTreeResult",
72
85
  "RTree",
73
86
  # VP-Tree
74
- "VPTreeResult",
75
87
  "VPNode",
76
88
  "VPTree",
77
89
  # Cover Tree
78
- "CoverTreeResult",
79
90
  "CoverTreeNode",
80
91
  "CoverTree",
81
92
  # Track List
@@ -4,6 +4,11 @@ Base classes for spatial data structures.
4
4
  This module provides abstract base classes that define the common interface
5
5
  for spatial indexing data structures like KD-trees, VP-trees, R-trees, and
6
6
  Cover trees.
7
+
8
+ The unified interface ensures all spatial indices provide consistent:
9
+ - Constructor patterns (data, optional parameters)
10
+ - Query methods (query, query_radius, query_ball_point)
11
+ - Return types (NeighborResult)
7
12
  """
8
13
 
9
14
  import logging
@@ -17,21 +22,52 @@ from numpy.typing import ArrayLike, NDArray
17
22
  _logger = logging.getLogger("pytcl.containers")
18
23
 
19
24
 
20
- class SpatialQueryResult(NamedTuple):
21
- """Result of a spatial query.
25
+ class NeighborResult(NamedTuple):
26
+ """
27
+ Unified result type for spatial index queries.
28
+
29
+ All spatial index implementations (KDTree, BallTree, VPTree, CoverTree,
30
+ RTree) return this type from their query methods, ensuring a consistent
31
+ interface across the library.
22
32
 
23
33
  Attributes
24
34
  ----------
25
- indices : ndarray
26
- Indices of matching points in the original data.
27
- distances : ndarray
28
- Distances to matching points.
35
+ indices : ndarray of shape (n_queries, k) or (n_queries,)
36
+ Indices of the k nearest neighbors in the original data array.
37
+ For k=1, may be 1D. For k>1, shape is (n_queries, k).
38
+ distances : ndarray of shape (n_queries, k) or (n_queries,)
39
+ Distances to the k nearest neighbors.
40
+ Same shape as indices.
41
+
42
+ Examples
43
+ --------
44
+ >>> from pytcl.containers import KDTree
45
+ >>> import numpy as np
46
+ >>> points = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
47
+ >>> tree = KDTree(points)
48
+ >>> result = tree.query([[0.1, 0.1]], k=2)
49
+ >>> result.indices
50
+ array([[0, 2]])
51
+ >>> result.distances
52
+ array([[0.14142136, 0.9 ]])
53
+
54
+ See Also
55
+ --------
56
+ BaseSpatialIndex : Abstract base class for spatial indices.
29
57
  """
30
58
 
31
59
  indices: NDArray[np.intp]
32
60
  distances: NDArray[np.floating]
33
61
 
34
62
 
63
+ # Backward compatibility aliases - all map to NeighborResult
64
+ SpatialQueryResult = NeighborResult
65
+ NearestNeighborResult = NeighborResult
66
+ VPTreeResult = NeighborResult
67
+ CoverTreeResult = NeighborResult
68
+ RTreeResult = NeighborResult
69
+
70
+
35
71
  class BaseSpatialIndex(ABC):
36
72
  """
37
73
  Abstract base class for spatial indexing data structures.
@@ -82,7 +118,7 @@ class BaseSpatialIndex(ABC):
82
118
  self,
83
119
  X: ArrayLike,
84
120
  k: int = 1,
85
- ) -> SpatialQueryResult:
121
+ ) -> NeighborResult:
86
122
  """
87
123
  Query the index for k nearest neighbors.
88
124
 
@@ -95,7 +131,7 @@ class BaseSpatialIndex(ABC):
95
131
 
96
132
  Returns
97
133
  -------
98
- result : SpatialQueryResult
134
+ result : NeighborResult
99
135
  Named tuple with indices and distances of k nearest neighbors
100
136
  for each query point.
101
137
  """
@@ -125,6 +161,36 @@ class BaseSpatialIndex(ABC):
125
161
  """
126
162
  pass
127
163
 
164
+ def query_ball_point(
165
+ self,
166
+ X: ArrayLike,
167
+ r: float,
168
+ ) -> List[List[int]]:
169
+ """
170
+ Query the index for all points within radius r.
171
+
172
+ This is an alias for :meth:`query_radius` provided for compatibility
173
+ with scipy.spatial.KDTree.
174
+
175
+ Parameters
176
+ ----------
177
+ X : array_like
178
+ Query points of shape (n_queries, n_features) or (n_features,).
179
+ r : float
180
+ Search radius.
181
+
182
+ Returns
183
+ -------
184
+ indices : list of list of int
185
+ For each query point, a list of indices of data points
186
+ within distance r.
187
+
188
+ See Also
189
+ --------
190
+ query_radius : The underlying implementation.
191
+ """
192
+ return self.query_radius(X, r)
193
+
128
194
  def __len__(self) -> int:
129
195
  """Return number of indexed points."""
130
196
  return self.n_samples
@@ -212,8 +278,15 @@ def validate_query_input(
212
278
 
213
279
 
214
280
  __all__ = [
215
- "SpatialQueryResult",
281
+ # Primary types
282
+ "NeighborResult",
216
283
  "BaseSpatialIndex",
217
284
  "MetricSpatialIndex",
218
285
  "validate_query_input",
286
+ # Backward compatibility aliases
287
+ "SpatialQueryResult",
288
+ "NearestNeighborResult",
289
+ "VPTreeResult",
290
+ "CoverTreeResult",
291
+ "RTreeResult",
219
292
  ]
@@ -12,32 +12,22 @@ References
12
12
  """
13
13
 
14
14
  import logging
15
- from typing import Any, Callable, List, NamedTuple, Optional, Set, Tuple
15
+ from typing import Any, Callable, List, Optional, Set, 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 CoverTreeResult # 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.covertree")
24
29
 
25
30
 
26
- class CoverTreeResult(NamedTuple):
27
- """Result of Cover 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 CoverTreeNode:
42
32
  """Node in a Cover tree.
43
33
 
@@ -234,7 +224,7 @@ class CoverTree(MetricSpatialIndex):
234
224
  self,
235
225
  X: ArrayLike,
236
226
  k: int = 1,
237
- ) -> CoverTreeResult:
227
+ ) -> NeighborResult:
238
228
  """
239
229
  Query the tree for k nearest neighbors.
240
230
 
@@ -247,7 +237,7 @@ class CoverTree(MetricSpatialIndex):
247
237
 
248
238
  Returns
249
239
  -------
250
- result : CoverTreeResult
240
+ result : NeighborResult
251
241
  Indices and distances of k nearest neighbors.
252
242
  """
253
243
  X = validate_query_input(X, self.n_features)
@@ -264,7 +254,9 @@ class CoverTree(MetricSpatialIndex):
264
254
  all_indices[i, :n_found] = indices
265
255
  all_distances[i, :n_found] = distances
266
256
 
267
- return CoverTreeResult(indices=all_indices, distances=all_distances)
257
+ return NeighborResult(indices=all_indices, distances=all_distances)
258
+
259
+ # query_ball_point inherited from BaseSpatialIndex
268
260
 
269
261
  def _query_single(
270
262
  self,
@@ -410,7 +402,8 @@ class CoverTree(MetricSpatialIndex):
410
402
 
411
403
 
412
404
  __all__ = [
413
- "CoverTreeResult",
405
+ "NeighborResult",
406
+ "CoverTreeResult", # Backward compatibility alias
414
407
  "CoverTreeNode",
415
408
  "CoverTree",
416
409
  ]
@@ -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
  ]