nrl-tracker 1.8.0__tar.gz → 1.9.1__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.
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/CONTRIBUTING.md +6 -6
- {nrl_tracker-1.8.0/nrl_tracker.egg-info → nrl_tracker-1.9.1}/PKG-INFO +2 -2
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/README.md +1 -1
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1/nrl_tracker.egg-info}/PKG-INFO +2 -2
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/nrl_tracker.egg-info/SOURCES.txt +6 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pyproject.toml +1 -1
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/__init__.py +3 -3
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/dijkstra_min_cost.py +0 -1
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/network_simplex.py +0 -2
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/astronomical/ephemerides.py +8 -4
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/astronomical/relativity.py +20 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/containers/__init__.py +19 -8
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/containers/base.py +82 -9
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/containers/covertree.py +14 -21
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/containers/kd_tree.py +18 -45
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/containers/rtree.py +43 -4
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/containers/vptree.py +14 -21
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/core/__init__.py +59 -2
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/core/constants.py +59 -0
- nrl_tracker-1.9.1/pytcl/core/exceptions.py +865 -0
- nrl_tracker-1.9.1/pytcl/core/optional_deps.py +531 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/core/validation.py +4 -6
- nrl_tracker-1.9.1/pytcl/dynamic_estimation/kalman/matrix_utils.py +427 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/kalman/square_root.py +20 -213
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/kalman/sr_ukf.py +5 -5
- nrl_tracker-1.9.1/pytcl/dynamic_estimation/kalman/types.py +98 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/signal_processing/detection.py +19 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/transforms/wavelets.py +7 -6
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/plotting/coordinates.py +25 -27
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/plotting/ellipses.py +14 -16
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/plotting/metrics.py +7 -5
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/plotting/tracks.py +8 -7
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/terrain/loaders.py +10 -6
- nrl_tracker-1.9.1/tests/test_exceptions.py +328 -0
- nrl_tracker-1.9.1/tests/test_optional_deps.py +361 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/LICENSE +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/MANIFEST.in +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/nrl_tracker.egg-info/dependency_links.txt +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/nrl_tracker.egg-info/requires.txt +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/nrl_tracker.egg-info/top_level.txt +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/data_association.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/gating.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/jpda.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/nd_assignment.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/network_flow.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/three_dimensional/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/three_dimensional/assignment.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/two_dimensional/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/two_dimensional/assignment.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/assignment_algorithms/two_dimensional/kbest.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/astronomical/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/astronomical/lambert.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/astronomical/orbital_mechanics.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/astronomical/reference_frames.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/astronomical/sgp4.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/astronomical/special_orbits.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/astronomical/time_systems.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/astronomical/tle.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/atmosphere/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/atmosphere/ionosphere.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/atmosphere/models.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/atmosphere/nrlmsise00.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/clustering/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/clustering/dbscan.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/clustering/gaussian_mixture.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/clustering/hierarchical.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/clustering/kmeans.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/containers/cluster_set.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/containers/measurement_set.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/containers/track_list.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/coordinate_systems/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/coordinate_systems/conversions/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/coordinate_systems/conversions/geodetic.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/coordinate_systems/conversions/spherical.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/coordinate_systems/jacobians/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/coordinate_systems/jacobians/jacobians.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/coordinate_systems/projections/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/coordinate_systems/projections/projections.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/coordinate_systems/rotations/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/coordinate_systems/rotations/rotations.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/core/array_utils.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/batch_estimation/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/gaussian_sum_filter.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/imm.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/information_filter.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/kalman/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/kalman/constrained.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/kalman/extended.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/kalman/h_infinity.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/kalman/linear.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/kalman/ud_filter.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/kalman/unscented.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/measurement_update/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/particle_filters/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/particle_filters/bootstrap.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/rbpf.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_estimation/smoothers.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/continuous_time/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/continuous_time/dynamics.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/discrete_time/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/discrete_time/coordinated_turn.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/discrete_time/polynomial.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/discrete_time/singer.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/process_noise/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/process_noise/coordinated_turn.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/process_noise/polynomial.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/dynamic_models/process_noise/singer.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/gravity/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/gravity/clenshaw.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/gravity/egm.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/gravity/models.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/gravity/spherical_harmonics.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/gravity/tides.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/logging_config.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/magnetism/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/magnetism/emm.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/magnetism/igrf.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/magnetism/wmm.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/basic_matrix/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/basic_matrix/decompositions.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/basic_matrix/special_matrices.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/combinatorics/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/combinatorics/combinatorics.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/continuous_optimization/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/geometry/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/geometry/geometry.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/interpolation/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/interpolation/interpolation.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/numerical_integration/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/numerical_integration/quadrature.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/polynomials/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/signal_processing/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/signal_processing/filters.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/signal_processing/matched_filter.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/special_functions/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/special_functions/bessel.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/special_functions/debye.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/special_functions/elliptic.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/special_functions/error_functions.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/special_functions/gamma_functions.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/special_functions/hypergeometric.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/special_functions/lambert_w.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/special_functions/marcum_q.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/statistics/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/statistics/distributions.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/statistics/estimators.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/transforms/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/transforms/fourier.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/mathematical_functions/transforms/stft.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/misc/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/navigation/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/navigation/geodesy.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/navigation/great_circle.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/navigation/ins.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/navigation/ins_gnss.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/navigation/rhumb.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/performance_evaluation/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/performance_evaluation/estimation_metrics.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/performance_evaluation/track_metrics.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/physical_values/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/plotting/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/scheduling/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/static_estimation/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/static_estimation/least_squares.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/static_estimation/maximum_likelihood.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/static_estimation/robust.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/terrain/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/terrain/dem.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/terrain/visibility.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/trackers/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/trackers/hypothesis.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/trackers/mht.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/trackers/multi_target.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/trackers/single_target.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/pytcl/transponders/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/setup.cfg +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/__init__.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/conftest.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_additional_trees.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_assignment_algorithms.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_astronomical.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_clustering.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_constrained_ekf.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_coordinate_systems.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_coverage_boost.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_coverage_boost_2.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_dynamic_models.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_egm.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_emm.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_ephemerides.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_gaussian_mixtures.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_gaussian_sum_filter.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_geophysical.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_great_circle.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_h_infinity.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_ins.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_ins_gnss.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_jpda.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_kalman_filters.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_mathematical_functions.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_maximum_likelihood.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_mht.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_nd_assignment.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_network_flow.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_nrlmsise00.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_performance_evaluation.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_phase6_specialized.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_plotting.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_projections.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_rbpf.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_relativity.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_rhumb.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_sgp4.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_signal_processing.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_smoothers.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_spatial_containers_parametrized.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_spatial_structures.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_special_functions.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_special_orbits.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_static_estimation.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_terrain.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_terrain_loaders.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_tides.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_tod_mod.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_trackers.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_tracking_containers.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_transforms.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/tests/test_validation.py +0 -0
- {nrl_tracker-1.8.0 → nrl_tracker-1.9.1}/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.
|
|
226
|
-
**MATLAB Parity:** 100% ✅
|
|
227
|
-
**Test Suite:** 2,
|
|
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.
|
|
304
|
+
Current metrics (v1.9.0):
|
|
305
305
|
- **Functions:** 1,070+
|
|
306
306
|
- **Modules:** 150+
|
|
307
|
-
- **Tests:** 2,
|
|
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.
|
|
3
|
+
Version: 1.9.1
|
|
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
|
-
[](https://pypi.org/project/nrl-tracker/)
|
|
67
67
|
[](https://www.python.org/downloads/)
|
|
68
68
|
[](https://en.wikipedia.org/wiki/Public_domain)
|
|
69
69
|
[](https://github.com/psf/black)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Tracker Component Library (Python)
|
|
2
2
|
|
|
3
|
-
[](https://pypi.org/project/nrl-tracker/)
|
|
4
4
|
[](https://www.python.org/downloads/)
|
|
5
5
|
[](https://en.wikipedia.org/wiki/Public_domain)
|
|
6
6
|
[](https://github.com/psf/black)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: nrl-tracker
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.9.1
|
|
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
|
-
[](https://pypi.org/project/nrl-tracker/)
|
|
67
67
|
[](https://www.python.org/downloads/)
|
|
68
68
|
[](https://en.wikipedia.org/wiki/Public_domain)
|
|
69
69
|
[](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.
|
|
7
|
+
version = "1.9.1"
|
|
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.
|
|
10
|
-
**Status:** Production-ready, 2,
|
|
9
|
+
**Current Version:** 1.9.1 (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.
|
|
24
|
+
__version__ = "1.9.1"
|
|
25
25
|
__author__ = "Python Port Contributors"
|
|
26
26
|
__original_author__ = "David F. Crouse, Naval Research Laboratory"
|
|
27
27
|
|
|
@@ -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
|
-
|
|
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
|
|
149
|
-
"jplephem is required for ephemeris access.
|
|
150
|
-
"
|
|
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
|
|
36
|
-
from pytcl.containers.kd_tree import BallTree, KDNode, KDTree
|
|
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
|
|
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
|
-
"
|
|
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
|
|
21
|
-
"""
|
|
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
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
) ->
|
|
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 :
|
|
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
|
-
|
|
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,
|
|
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
|
|
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
|
-
) ->
|
|
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 :
|
|
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
|
|
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
|
-
"
|
|
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,
|
|
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
|
]
|