nrl-tracker 1.7.0__py3-none-any.whl → 1.7.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. {nrl_tracker-1.7.0.dist-info → nrl_tracker-1.7.1.dist-info}/METADATA +3 -2
  2. {nrl_tracker-1.7.0.dist-info → nrl_tracker-1.7.1.dist-info}/RECORD +75 -75
  3. pytcl/__init__.py +2 -2
  4. pytcl/assignment_algorithms/__init__.py +15 -15
  5. pytcl/assignment_algorithms/gating.py +10 -10
  6. pytcl/assignment_algorithms/jpda.py +40 -40
  7. pytcl/assignment_algorithms/nd_assignment.py +5 -4
  8. pytcl/assignment_algorithms/network_flow.py +18 -8
  9. pytcl/assignment_algorithms/three_dimensional/assignment.py +3 -3
  10. pytcl/astronomical/__init__.py +6 -6
  11. pytcl/astronomical/ephemerides.py +14 -11
  12. pytcl/astronomical/reference_frames.py +8 -4
  13. pytcl/astronomical/relativity.py +6 -5
  14. pytcl/astronomical/special_orbits.py +9 -13
  15. pytcl/atmosphere/__init__.py +6 -6
  16. pytcl/atmosphere/nrlmsise00.py +153 -152
  17. pytcl/clustering/dbscan.py +2 -2
  18. pytcl/clustering/gaussian_mixture.py +3 -3
  19. pytcl/clustering/hierarchical.py +15 -15
  20. pytcl/clustering/kmeans.py +4 -4
  21. pytcl/containers/base.py +3 -3
  22. pytcl/containers/cluster_set.py +12 -2
  23. pytcl/containers/covertree.py +5 -3
  24. pytcl/containers/rtree.py +1 -1
  25. pytcl/containers/vptree.py +4 -2
  26. pytcl/coordinate_systems/conversions/geodetic.py +31 -7
  27. pytcl/coordinate_systems/jacobians/jacobians.py +2 -2
  28. pytcl/coordinate_systems/projections/projections.py +2 -2
  29. pytcl/coordinate_systems/rotations/rotations.py +10 -6
  30. pytcl/core/validation.py +3 -3
  31. pytcl/dynamic_estimation/__init__.py +16 -16
  32. pytcl/dynamic_estimation/gaussian_sum_filter.py +20 -38
  33. pytcl/dynamic_estimation/imm.py +14 -14
  34. pytcl/dynamic_estimation/kalman/__init__.py +1 -1
  35. pytcl/dynamic_estimation/kalman/constrained.py +35 -23
  36. pytcl/dynamic_estimation/kalman/extended.py +8 -8
  37. pytcl/dynamic_estimation/kalman/h_infinity.py +2 -2
  38. pytcl/dynamic_estimation/kalman/square_root.py +8 -2
  39. pytcl/dynamic_estimation/kalman/sr_ukf.py +3 -3
  40. pytcl/dynamic_estimation/kalman/ud_filter.py +11 -5
  41. pytcl/dynamic_estimation/kalman/unscented.py +8 -6
  42. pytcl/dynamic_estimation/particle_filters/bootstrap.py +15 -15
  43. pytcl/dynamic_estimation/rbpf.py +36 -40
  44. pytcl/gravity/spherical_harmonics.py +3 -3
  45. pytcl/gravity/tides.py +6 -6
  46. pytcl/logging_config.py +3 -3
  47. pytcl/magnetism/emm.py +10 -3
  48. pytcl/magnetism/wmm.py +4 -4
  49. pytcl/mathematical_functions/combinatorics/combinatorics.py +5 -5
  50. pytcl/mathematical_functions/geometry/geometry.py +5 -5
  51. pytcl/mathematical_functions/numerical_integration/quadrature.py +6 -6
  52. pytcl/mathematical_functions/signal_processing/detection.py +24 -24
  53. pytcl/mathematical_functions/signal_processing/filters.py +14 -14
  54. pytcl/mathematical_functions/signal_processing/matched_filter.py +12 -12
  55. pytcl/mathematical_functions/special_functions/bessel.py +15 -3
  56. pytcl/mathematical_functions/special_functions/debye.py +5 -1
  57. pytcl/mathematical_functions/special_functions/error_functions.py +3 -1
  58. pytcl/mathematical_functions/special_functions/gamma_functions.py +4 -4
  59. pytcl/mathematical_functions/special_functions/hypergeometric.py +6 -4
  60. pytcl/mathematical_functions/transforms/fourier.py +8 -8
  61. pytcl/mathematical_functions/transforms/stft.py +12 -12
  62. pytcl/mathematical_functions/transforms/wavelets.py +9 -9
  63. pytcl/navigation/geodesy.py +3 -3
  64. pytcl/navigation/great_circle.py +5 -5
  65. pytcl/plotting/coordinates.py +7 -7
  66. pytcl/plotting/tracks.py +2 -2
  67. pytcl/static_estimation/maximum_likelihood.py +16 -14
  68. pytcl/static_estimation/robust.py +5 -5
  69. pytcl/terrain/loaders.py +5 -5
  70. pytcl/trackers/hypothesis.py +1 -1
  71. pytcl/trackers/mht.py +9 -9
  72. pytcl/trackers/multi_target.py +1 -1
  73. {nrl_tracker-1.7.0.dist-info → nrl_tracker-1.7.1.dist-info}/LICENSE +0 -0
  74. {nrl_tracker-1.7.0.dist-info → nrl_tracker-1.7.1.dist-info}/WHEEL +0 -0
  75. {nrl_tracker-1.7.0.dist-info → nrl_tracker-1.7.1.dist-info}/top_level.txt +0 -0
@@ -12,7 +12,7 @@ References
12
12
  Wiley, 2001.
13
13
  """
14
14
 
15
- from typing import Callable, NamedTuple, Optional
15
+ from typing import Any, Callable, NamedTuple, Optional
16
16
 
17
17
  import numpy as np
18
18
  from numpy.typing import ArrayLike, NDArray
@@ -75,10 +75,10 @@ class CRBResult(NamedTuple):
75
75
 
76
76
 
77
77
  def fisher_information_numerical(
78
- log_likelihood: Callable[[NDArray], float],
78
+ log_likelihood: Callable[[np.ndarray[Any, Any]], float],
79
79
  theta: ArrayLike,
80
80
  h: float = 1e-5,
81
- ) -> NDArray[np.floating]:
81
+ ) -> np.ndarray[Any, Any]:
82
82
  """
83
83
  Compute Fisher information matrix numerically.
84
84
 
@@ -189,11 +189,13 @@ def fisher_information_gaussian(
189
189
 
190
190
 
191
191
  def fisher_information_exponential_family(
192
- sufficient_stats: Callable[[NDArray, NDArray], NDArray],
192
+ sufficient_stats: Callable[
193
+ [np.ndarray[Any, Any], np.ndarray[Any, Any]], np.ndarray[Any, Any]
194
+ ],
193
195
  theta: ArrayLike,
194
196
  data: ArrayLike,
195
197
  h: float = 1e-5,
196
- ) -> NDArray[np.floating]:
198
+ ) -> np.ndarray[Any, Any]:
197
199
  """
198
200
  Fisher information for exponential family distributions.
199
201
 
@@ -232,10 +234,10 @@ def fisher_information_exponential_family(
232
234
 
233
235
 
234
236
  def observed_fisher_information(
235
- log_likelihood: Callable[[NDArray], float],
237
+ log_likelihood: Callable[[np.ndarray[Any, Any]], float],
236
238
  theta: ArrayLike,
237
239
  h: float = 1e-5,
238
- ) -> NDArray[np.floating]:
240
+ ) -> np.ndarray[Any, Any]:
239
241
  """
240
242
  Compute observed Fisher information (negative Hessian).
241
243
 
@@ -409,10 +411,10 @@ def efficiency(
409
411
 
410
412
 
411
413
  def mle_newton_raphson(
412
- log_likelihood: Callable[[NDArray], float],
413
- score: Callable[[NDArray], NDArray],
414
+ log_likelihood: Callable[[np.ndarray[Any, Any]], float],
415
+ score: Callable[[np.ndarray[Any, Any]], np.ndarray[Any, Any]],
414
416
  theta_init: ArrayLike,
415
- hessian: Optional[Callable[[NDArray], NDArray]] = None,
417
+ hessian: Optional[Callable[[np.ndarray[Any, Any]], np.ndarray[Any, Any]]] = None,
416
418
  max_iter: int = 100,
417
419
  tol: float = 1e-8,
418
420
  h: float = 1e-5,
@@ -460,7 +462,7 @@ def mle_newton_raphson(
460
462
 
461
463
  converged = False
462
464
 
463
- def numerical_hessian(t: NDArray) -> NDArray:
465
+ def numerical_hessian(t: np.ndarray[Any, Any]) -> np.ndarray[Any, Any]:
464
466
  H = np.zeros((n_params, n_params))
465
467
  for i in range(n_params):
466
468
  for j in range(i, n_params):
@@ -532,9 +534,9 @@ def mle_newton_raphson(
532
534
 
533
535
 
534
536
  def mle_scoring(
535
- log_likelihood: Callable[[NDArray], float],
536
- score: Callable[[NDArray], NDArray],
537
- fisher_info: Callable[[NDArray], NDArray],
537
+ log_likelihood: Callable[[np.ndarray[Any, Any]], float],
538
+ score: Callable[[np.ndarray[Any, Any]], np.ndarray[Any, Any]],
539
+ fisher_info: Callable[[np.ndarray[Any, Any]], np.ndarray[Any, Any]],
538
540
  theta_init: ArrayLike,
539
541
  max_iter: int = 100,
540
542
  tol: float = 1e-8,
@@ -12,7 +12,7 @@ References
12
12
  Cartography," Communications of the ACM, 1981.
13
13
  """
14
14
 
15
- from typing import Callable, NamedTuple, Optional
15
+ from typing import Any, Callable, NamedTuple, Optional
16
16
 
17
17
  import numpy as np
18
18
  from numpy.typing import ArrayLike, NDArray
@@ -313,8 +313,8 @@ def tau_scale(
313
313
  def irls(
314
314
  A: ArrayLike,
315
315
  b: ArrayLike,
316
- weight_func: Callable[[NDArray], NDArray] = huber_weight,
317
- scale_func: Callable[[NDArray], float] = mad,
316
+ weight_func: Callable[[np.ndarray[Any, Any]], np.ndarray[Any, Any]] = huber_weight,
317
+ scale_func: Callable[[np.ndarray[Any, Any]], float] = mad,
318
318
  max_iter: int = 50,
319
319
  tol: float = 1e-6,
320
320
  ) -> RobustResult:
@@ -455,7 +455,7 @@ def huber_regression(
455
455
  Gaussian errors and resistance to outliers.
456
456
  """
457
457
 
458
- def weight_func(r: NDArray) -> NDArray:
458
+ def weight_func(r: np.ndarray[Any, Any]) -> np.ndarray[Any, Any]:
459
459
  return huber_weight(r, c)
460
460
 
461
461
  return irls(A, b, weight_func=weight_func, max_iter=max_iter, tol=tol)
@@ -504,7 +504,7 @@ def tukey_regression(
504
504
  Huber for gross outliers.
505
505
  """
506
506
 
507
- def weight_func(r: NDArray) -> NDArray:
507
+ def weight_func(r: np.ndarray[Any, Any]) -> np.ndarray[Any, Any]:
508
508
  return tukey_weight(r, c)
509
509
 
510
510
  return irls(A, b, weight_func=weight_func, max_iter=max_iter, tol=tol)
pytcl/terrain/loaders.py CHANGED
@@ -21,7 +21,7 @@ References
21
21
  import os
22
22
  from functools import lru_cache
23
23
  from pathlib import Path
24
- from typing import Dict, NamedTuple, Optional, Tuple
24
+ from typing import Any, NamedTuple, Optional
25
25
 
26
26
  import numpy as np
27
27
  from numpy.typing import NDArray
@@ -31,7 +31,7 @@ from .dem import DEMGrid
31
31
  # Model parameters
32
32
  _GEBCO_BASE_URL = "https://www.gebco.net/data-products/gridded-bathymetry-data"
33
33
 
34
- GEBCO_PARAMETERS: Dict[str, Dict] = {
34
+ GEBCO_PARAMETERS: dict[str, dict[str, Any]] = {
35
35
  "GEBCO2024": {
36
36
  "resolution_arcsec": 15.0,
37
37
  "n_lat": 43200,
@@ -58,7 +58,7 @@ GEBCO_PARAMETERS: Dict[str, Dict] = {
58
58
  },
59
59
  }
60
60
 
61
- EARTH2014_PARAMETERS: Dict[str, Dict] = {
61
+ EARTH2014_PARAMETERS: dict[str, dict[str, Any]] = {
62
62
  "SUR": {
63
63
  "description": "Physical surface (topography, ice surface, 0 over oceans)",
64
64
  "file_pattern": "Earth2014.SUR2014.1min.geod.bin",
@@ -275,7 +275,7 @@ def parse_gebco_netcdf(
275
275
  lat_max: Optional[float] = None,
276
276
  lon_min: Optional[float] = None,
277
277
  lon_max: Optional[float] = None,
278
- ) -> Tuple[NDArray, float, float, float, float]:
278
+ ) -> tuple[NDArray[np.floating], float, float, float, float]:
279
279
  """Parse GEBCO NetCDF file and extract region.
280
280
 
281
281
  Parameters
@@ -369,7 +369,7 @@ def parse_earth2014_binary(
369
369
  lat_max: Optional[float] = None,
370
370
  lon_min: Optional[float] = None,
371
371
  lon_max: Optional[float] = None,
372
- ) -> Tuple[NDArray, float, float, float, float]:
372
+ ) -> tuple[NDArray[np.floating], float, float, float, float]:
373
373
  """Parse Earth2014 binary file and extract region.
374
374
 
375
375
  Earth2014 files are stored as int16 big-endian binary data,
@@ -155,7 +155,7 @@ def generate_joint_associations(
155
155
  track_idx: int,
156
156
  current: Dict[int, int],
157
157
  used_meas: Set[int],
158
- ):
158
+ ) -> None:
159
159
  """Recursively enumerate associations."""
160
160
  if track_idx == n_tracks:
161
161
  associations.append(current.copy())
pytcl/trackers/mht.py CHANGED
@@ -15,7 +15,7 @@ References
15
15
  IEEE Trans. Automatic Control, 1979.
16
16
  """
17
17
 
18
- from typing import Callable, Dict, List, NamedTuple, Optional, Set
18
+ from typing import Callable, Dict, List, NamedTuple, Optional
19
19
 
20
20
  import numpy as np
21
21
  from numpy.typing import ArrayLike, NDArray
@@ -322,8 +322,8 @@ class MHTTracker:
322
322
  def _predict_tracks(
323
323
  self,
324
324
  tracks: Dict[int, MHTTrack],
325
- F: NDArray,
326
- Q: NDArray,
325
+ F: NDArray[np.floating],
326
+ Q: NDArray[np.floating],
327
327
  ) -> Dict[int, MHTTrack]:
328
328
  """Predict all tracks forward in time."""
329
329
  predicted = {}
@@ -352,8 +352,8 @@ class MHTTracker:
352
352
  def _compute_gating_and_likelihoods(
353
353
  self,
354
354
  tracks: Dict[int, MHTTrack],
355
- Z: NDArray,
356
- ) -> tuple[Set[tuple], Dict[tuple, float]]:
355
+ Z: NDArray[np.floating],
356
+ ) -> tuple[set[tuple[int, int]], dict[tuple[int, int], float]]:
357
357
  """Compute gating matrix and likelihood values."""
358
358
  gated = set()
359
359
  likelihood_matrix = {}
@@ -387,8 +387,8 @@ class MHTTracker:
387
387
  self,
388
388
  association: Dict[int, int],
389
389
  tracks: Dict[int, MHTTrack],
390
- Z: NDArray,
391
- likelihood_matrix: Dict[tuple, float],
390
+ Z: NDArray[np.floating],
391
+ likelihood_matrix: dict[tuple[int, int], float],
392
392
  ) -> float:
393
393
  """Compute likelihood of a joint association."""
394
394
  likelihood = 1.0
@@ -417,7 +417,7 @@ class MHTTracker:
417
417
  def _update_track(
418
418
  self,
419
419
  track: MHTTrack,
420
- measurement: NDArray,
420
+ measurement: NDArray[np.floating],
421
421
  meas_idx: int,
422
422
  ) -> MHTTrack:
423
423
  """Update a track with a measurement."""
@@ -502,7 +502,7 @@ class MHTTracker:
502
502
 
503
503
  def _initiate_track(
504
504
  self,
505
- measurement: NDArray,
505
+ measurement: NDArray[np.floating],
506
506
  meas_idx: int,
507
507
  ) -> MHTTrack:
508
508
  """Initiate a new track from a measurement."""
@@ -225,7 +225,7 @@ class MultiTargetTracker:
225
225
  track.covariance = F @ track.covariance @ F.T + Q
226
226
  track.time = self._time
227
227
 
228
- def _associate(self, Z: NDArray[np.float64]) -> dict:
228
+ def _associate(self, Z: NDArray[np.float64]) -> dict[int, int]:
229
229
  """
230
230
  Associate measurements to tracks using GNN.
231
231