nrl-tracker 0.21.4__py3-none-any.whl → 0.22.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. {nrl_tracker-0.21.4.dist-info → nrl_tracker-0.22.0.dist-info}/METADATA +2 -2
  2. nrl_tracker-0.22.0.dist-info/RECORD +150 -0
  3. pytcl/__init__.py +9 -11
  4. pytcl/assignment_algorithms/__init__.py +32 -42
  5. pytcl/assignment_algorithms/data_association.py +9 -10
  6. pytcl/assignment_algorithms/gating.py +7 -5
  7. pytcl/assignment_algorithms/jpda.py +10 -14
  8. pytcl/assignment_algorithms/three_dimensional/__init__.py +6 -8
  9. pytcl/assignment_algorithms/three_dimensional/assignment.py +6 -2
  10. pytcl/assignment_algorithms/two_dimensional/__init__.py +9 -13
  11. pytcl/assignment_algorithms/two_dimensional/assignment.py +5 -2
  12. pytcl/assignment_algorithms/two_dimensional/kbest.py +9 -9
  13. pytcl/astronomical/__init__.py +130 -89
  14. pytcl/astronomical/ephemerides.py +524 -0
  15. pytcl/astronomical/lambert.py +6 -15
  16. pytcl/astronomical/orbital_mechanics.py +1 -3
  17. pytcl/astronomical/reference_frames.py +1 -3
  18. pytcl/astronomical/relativity.py +466 -0
  19. pytcl/astronomical/time_systems.py +2 -1
  20. pytcl/atmosphere/__init__.py +12 -14
  21. pytcl/atmosphere/models.py +5 -5
  22. pytcl/clustering/__init__.py +28 -36
  23. pytcl/clustering/dbscan.py +5 -2
  24. pytcl/clustering/gaussian_mixture.py +10 -10
  25. pytcl/clustering/hierarchical.py +7 -7
  26. pytcl/clustering/kmeans.py +7 -5
  27. pytcl/containers/__init__.py +29 -43
  28. pytcl/containers/cluster_set.py +13 -20
  29. pytcl/containers/covertree.py +8 -2
  30. pytcl/containers/kd_tree.py +6 -2
  31. pytcl/containers/measurement_set.py +11 -16
  32. pytcl/containers/rtree.py +8 -7
  33. pytcl/containers/track_list.py +13 -13
  34. pytcl/containers/vptree.py +7 -2
  35. pytcl/coordinate_systems/__init__.py +69 -74
  36. pytcl/coordinate_systems/conversions/__init__.py +20 -24
  37. pytcl/coordinate_systems/conversions/geodetic.py +7 -17
  38. pytcl/coordinate_systems/conversions/spherical.py +4 -2
  39. pytcl/coordinate_systems/jacobians/__init__.py +10 -12
  40. pytcl/coordinate_systems/jacobians/jacobians.py +2 -1
  41. pytcl/coordinate_systems/projections/__init__.py +27 -23
  42. pytcl/coordinate_systems/projections/projections.py +14 -39
  43. pytcl/coordinate_systems/rotations/__init__.py +20 -22
  44. pytcl/coordinate_systems/rotations/rotations.py +3 -4
  45. pytcl/core/__init__.py +16 -22
  46. pytcl/core/array_utils.py +7 -7
  47. pytcl/core/constants.py +1 -3
  48. pytcl/core/validation.py +13 -19
  49. pytcl/dynamic_estimation/__init__.py +77 -86
  50. pytcl/dynamic_estimation/imm.py +10 -15
  51. pytcl/dynamic_estimation/information_filter.py +8 -6
  52. pytcl/dynamic_estimation/kalman/__init__.py +40 -48
  53. pytcl/dynamic_estimation/kalman/extended.py +4 -5
  54. pytcl/dynamic_estimation/kalman/linear.py +7 -3
  55. pytcl/dynamic_estimation/kalman/square_root.py +7 -8
  56. pytcl/dynamic_estimation/kalman/unscented.py +8 -6
  57. pytcl/dynamic_estimation/particle_filters/__init__.py +12 -14
  58. pytcl/dynamic_estimation/particle_filters/bootstrap.py +8 -8
  59. pytcl/dynamic_estimation/smoothers.py +9 -10
  60. pytcl/dynamic_models/__init__.py +37 -41
  61. pytcl/dynamic_models/continuous_time/__init__.py +11 -11
  62. pytcl/dynamic_models/continuous_time/dynamics.py +4 -2
  63. pytcl/dynamic_models/discrete_time/__init__.py +11 -17
  64. pytcl/dynamic_models/process_noise/__init__.py +11 -17
  65. pytcl/dynamic_models/process_noise/polynomial.py +2 -6
  66. pytcl/gravity/__init__.py +55 -65
  67. pytcl/gravity/clenshaw.py +4 -7
  68. pytcl/gravity/egm.py +9 -6
  69. pytcl/gravity/models.py +1 -3
  70. pytcl/gravity/spherical_harmonics.py +6 -11
  71. pytcl/gravity/tides.py +9 -17
  72. pytcl/magnetism/__init__.py +26 -36
  73. pytcl/magnetism/emm.py +7 -13
  74. pytcl/magnetism/igrf.py +5 -6
  75. pytcl/magnetism/wmm.py +4 -10
  76. pytcl/mathematical_functions/__init__.py +69 -87
  77. pytcl/mathematical_functions/basic_matrix/__init__.py +25 -19
  78. pytcl/mathematical_functions/basic_matrix/decompositions.py +6 -5
  79. pytcl/mathematical_functions/basic_matrix/special_matrices.py +2 -1
  80. pytcl/mathematical_functions/combinatorics/__init__.py +18 -14
  81. pytcl/mathematical_functions/combinatorics/combinatorics.py +5 -4
  82. pytcl/mathematical_functions/geometry/__init__.py +15 -15
  83. pytcl/mathematical_functions/geometry/geometry.py +10 -15
  84. pytcl/mathematical_functions/interpolation/__init__.py +11 -13
  85. pytcl/mathematical_functions/interpolation/interpolation.py +8 -5
  86. pytcl/mathematical_functions/numerical_integration/__init__.py +16 -10
  87. pytcl/mathematical_functions/numerical_integration/quadrature.py +6 -2
  88. pytcl/mathematical_functions/signal_processing/__init__.py +42 -30
  89. pytcl/mathematical_functions/signal_processing/detection.py +9 -9
  90. pytcl/mathematical_functions/signal_processing/filters.py +7 -8
  91. pytcl/mathematical_functions/signal_processing/matched_filter.py +8 -7
  92. pytcl/mathematical_functions/special_functions/__init__.py +75 -77
  93. pytcl/mathematical_functions/special_functions/bessel.py +2 -1
  94. pytcl/mathematical_functions/special_functions/debye.py +4 -2
  95. pytcl/mathematical_functions/special_functions/elliptic.py +3 -4
  96. pytcl/mathematical_functions/special_functions/error_functions.py +2 -1
  97. pytcl/mathematical_functions/special_functions/gamma_functions.py +3 -4
  98. pytcl/mathematical_functions/special_functions/hypergeometric.py +2 -1
  99. pytcl/mathematical_functions/special_functions/lambert_w.py +3 -4
  100. pytcl/mathematical_functions/special_functions/marcum_q.py +2 -1
  101. pytcl/mathematical_functions/statistics/__init__.py +27 -31
  102. pytcl/mathematical_functions/statistics/distributions.py +21 -40
  103. pytcl/mathematical_functions/statistics/estimators.py +3 -4
  104. pytcl/mathematical_functions/transforms/__init__.py +45 -51
  105. pytcl/mathematical_functions/transforms/fourier.py +5 -2
  106. pytcl/mathematical_functions/transforms/stft.py +8 -11
  107. pytcl/mathematical_functions/transforms/wavelets.py +13 -20
  108. pytcl/navigation/__init__.py +96 -102
  109. pytcl/navigation/geodesy.py +13 -33
  110. pytcl/navigation/great_circle.py +7 -13
  111. pytcl/navigation/ins.py +12 -16
  112. pytcl/navigation/ins_gnss.py +24 -37
  113. pytcl/navigation/rhumb.py +7 -12
  114. pytcl/performance_evaluation/__init__.py +21 -25
  115. pytcl/performance_evaluation/estimation_metrics.py +3 -1
  116. pytcl/performance_evaluation/track_metrics.py +4 -4
  117. pytcl/plotting/__init__.py +30 -38
  118. pytcl/plotting/coordinates.py +8 -18
  119. pytcl/plotting/ellipses.py +5 -2
  120. pytcl/plotting/metrics.py +5 -10
  121. pytcl/plotting/tracks.py +7 -12
  122. pytcl/static_estimation/__init__.py +37 -41
  123. pytcl/static_estimation/least_squares.py +5 -4
  124. pytcl/static_estimation/maximum_likelihood.py +8 -5
  125. pytcl/static_estimation/robust.py +5 -2
  126. pytcl/terrain/__init__.py +28 -34
  127. pytcl/terrain/dem.py +6 -9
  128. pytcl/terrain/loaders.py +9 -14
  129. pytcl/terrain/visibility.py +4 -8
  130. pytcl/trackers/__init__.py +17 -25
  131. pytcl/trackers/hypothesis.py +8 -8
  132. pytcl/trackers/mht.py +18 -24
  133. pytcl/trackers/multi_target.py +8 -6
  134. pytcl/trackers/single_target.py +5 -2
  135. nrl_tracker-0.21.4.dist-info/RECORD +0 -148
  136. {nrl_tracker-0.21.4.dist-info → nrl_tracker-0.22.0.dist-info}/LICENSE +0 -0
  137. {nrl_tracker-0.21.4.dist-info → nrl_tracker-0.22.0.dist-info}/WHEEL +0 -0
  138. {nrl_tracker-0.21.4.dist-info → nrl_tracker-0.22.0.dist-info}/top_level.txt +0 -0
pytcl/terrain/__init__.py CHANGED
@@ -52,44 +52,38 @@ Examples
52
52
  """
53
53
 
54
54
  # DEM interface
55
- from pytcl.terrain.dem import (
56
- DEMGrid,
57
- DEMMetadata,
58
- DEMPoint,
59
- TerrainGradient,
60
- create_flat_dem,
61
- create_synthetic_terrain,
62
- get_elevation_profile,
63
- interpolate_dem,
64
- merge_dems,
65
- )
55
+ from pytcl.terrain.dem import DEMGrid
56
+ from pytcl.terrain.dem import DEMMetadata
57
+ from pytcl.terrain.dem import DEMPoint
58
+ from pytcl.terrain.dem import TerrainGradient
59
+ from pytcl.terrain.dem import create_flat_dem
60
+ from pytcl.terrain.dem import create_synthetic_terrain
61
+ from pytcl.terrain.dem import get_elevation_profile
62
+ from pytcl.terrain.dem import interpolate_dem
63
+ from pytcl.terrain.dem import merge_dems
66
64
 
67
65
  # Data loaders
68
- from pytcl.terrain.loaders import (
69
- EARTH2014_PARAMETERS,
70
- GEBCO_PARAMETERS,
71
- Earth2014Metadata,
72
- GEBCOMetadata,
73
- create_test_earth2014_dem,
74
- create_test_gebco_dem,
75
- get_data_dir,
76
- get_earth2014_metadata,
77
- get_gebco_metadata,
78
- load_earth2014,
79
- load_gebco,
80
- )
66
+ from pytcl.terrain.loaders import EARTH2014_PARAMETERS
67
+ from pytcl.terrain.loaders import GEBCO_PARAMETERS
68
+ from pytcl.terrain.loaders import Earth2014Metadata
69
+ from pytcl.terrain.loaders import GEBCOMetadata
70
+ from pytcl.terrain.loaders import create_test_earth2014_dem
71
+ from pytcl.terrain.loaders import create_test_gebco_dem
72
+ from pytcl.terrain.loaders import get_data_dir
73
+ from pytcl.terrain.loaders import get_earth2014_metadata
74
+ from pytcl.terrain.loaders import get_gebco_metadata
75
+ from pytcl.terrain.loaders import load_earth2014
76
+ from pytcl.terrain.loaders import load_gebco
81
77
 
82
78
  # Visibility functions
83
- from pytcl.terrain.visibility import (
84
- HorizonPoint,
85
- LOSResult,
86
- ViewshedResult,
87
- compute_horizon,
88
- line_of_sight,
89
- radar_coverage_map,
90
- terrain_masking_angle,
91
- viewshed,
92
- )
79
+ from pytcl.terrain.visibility import HorizonPoint
80
+ from pytcl.terrain.visibility import LOSResult
81
+ from pytcl.terrain.visibility import ViewshedResult
82
+ from pytcl.terrain.visibility import compute_horizon
83
+ from pytcl.terrain.visibility import line_of_sight
84
+ from pytcl.terrain.visibility import radar_coverage_map
85
+ from pytcl.terrain.visibility import terrain_masking_angle
86
+ from pytcl.terrain.visibility import viewshed
93
87
 
94
88
  __all__ = [
95
89
  # DEM data structures
pytcl/terrain/dem.py CHANGED
@@ -25,7 +25,10 @@ References
25
25
  198.3 (2014): 1544-1555.
26
26
  """
27
27
 
28
- from typing import List, NamedTuple, Optional, Tuple
28
+ from typing import List
29
+ from typing import NamedTuple
30
+ from typing import Optional
31
+ from typing import Tuple
29
32
 
30
33
  import numpy as np
31
34
  from numpy.typing import NDArray
@@ -193,9 +196,7 @@ class DEMGrid:
193
196
 
194
197
  def _in_bounds(self, lat: float, lon: float) -> bool:
195
198
  """Check if coordinates are within DEM bounds."""
196
- return (
197
- self.lat_min <= lat <= self.lat_max and self.lon_min <= lon <= self.lon_max
198
- )
199
+ return self.lat_min <= lat <= self.lat_max and self.lon_min <= lon <= self.lon_max
199
200
 
200
201
  def _get_indices(self, lat: float, lon: float) -> Tuple[int, int, float, float]:
201
202
  """Get grid indices and fractional parts for interpolation.
@@ -275,11 +276,7 @@ class DEMGrid:
275
276
  z00 = self.data[i, j]
276
277
  z01 = self.data[i, j + 1] if j + 1 < self.n_lon else z00
277
278
  z10 = self.data[i + 1, j] if i + 1 < self.n_lat else z00
278
- z11 = (
279
- self.data[i + 1, j + 1]
280
- if (i + 1 < self.n_lat and j + 1 < self.n_lon)
281
- else z00
282
- )
279
+ z11 = self.data[i + 1, j + 1] if (i + 1 < self.n_lat and j + 1 < self.n_lon) else z00
283
280
 
284
281
  # Check for nodata
285
282
  values = [z00, z01, z10, z11]
pytcl/terrain/loaders.py CHANGED
@@ -21,7 +21,10 @@ 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 Dict
25
+ from typing import NamedTuple
26
+ from typing import Optional
27
+ from typing import Tuple
25
28
 
26
29
  import numpy as np
27
30
  from numpy.typing import NDArray
@@ -308,8 +311,7 @@ def parse_gebco_netcdf(
308
311
  import netCDF4 as nc
309
312
  except ImportError:
310
313
  raise ImportError(
311
- "netCDF4 is required for loading GEBCO files.\n"
312
- "Install with: pip install netCDF4"
314
+ "netCDF4 is required for loading GEBCO files.\n" "Install with: pip install netCDF4"
313
315
  )
314
316
 
315
317
  # Set defaults for global extent
@@ -432,13 +434,9 @@ def parse_earth2014_binary(
432
434
 
433
435
  # Compute row/column indices
434
436
  i_start = max(0, int(np.floor((np.radians(lat_min_deg) - lat_start) / d_lat)))
435
- i_end = min(
436
- EARTH2014_N_LAT, int(np.ceil((np.radians(lat_max_deg) - lat_start) / d_lat)) + 1
437
- )
437
+ i_end = min(EARTH2014_N_LAT, int(np.ceil((np.radians(lat_max_deg) - lat_start) / d_lat)) + 1)
438
438
  j_start = max(0, int(np.floor((np.radians(lon_min_deg) - lon_start) / d_lon)))
439
- j_end = min(
440
- EARTH2014_N_LON, int(np.ceil((np.radians(lon_max_deg) - lon_start) / d_lon)) + 1
441
- )
439
+ j_end = min(EARTH2014_N_LON, int(np.ceil((np.radians(lon_max_deg) - lon_start) / d_lon)) + 1)
442
440
 
443
441
  # Read binary data
444
442
  # File is stored as int16 big-endian, rows from south to north
@@ -455,9 +453,7 @@ def parse_earth2014_binary(
455
453
  f.seek(row_offset + col_offset)
456
454
 
457
455
  # Read row segment
458
- row_data = np.frombuffer(
459
- f.read(n_cols * 2), dtype=">i2"
460
- ) # big-endian int16
456
+ row_data = np.frombuffer(f.read(n_cols * 2), dtype=">i2") # big-endian int16
461
457
  data[i, :] = row_data.astype(np.float64)
462
458
 
463
459
  # Compute actual bounds
@@ -578,8 +574,7 @@ def load_gebco(
578
574
  """
579
575
  if version not in GEBCO_PARAMETERS:
580
576
  raise ValueError(
581
- f"Unknown GEBCO version: {version}. "
582
- f"Valid versions: {list(GEBCO_PARAMETERS.keys())}"
577
+ f"Unknown GEBCO version: {version}. " f"Valid versions: {list(GEBCO_PARAMETERS.keys())}"
583
578
  )
584
579
 
585
580
  return _load_gebco_cached(version, lat_min, lat_max, lon_min, lon_max)
@@ -23,7 +23,8 @@ References
23
23
  on terrains: a survey." Environment and Planning B 30.5 (2003): 709-728.
24
24
  """
25
25
 
26
- from typing import List, NamedTuple
26
+ from typing import List
27
+ from typing import NamedTuple
27
28
 
28
29
  import numpy as np
29
30
  from numpy.typing import NDArray
@@ -184,10 +185,7 @@ def line_of_sight(
184
185
  # Compute distances from observer
185
186
  dlat = sample_lats - obs_lat
186
187
  dlon = sample_lons - obs_lon
187
- a = (
188
- np.sin(dlat / 2) ** 2
189
- + np.cos(obs_lat) * np.cos(sample_lats) * np.sin(dlon / 2) ** 2
190
- )
188
+ a = np.sin(dlat / 2) ** 2 + np.cos(obs_lat) * np.cos(sample_lats) * np.sin(dlon / 2) ** 2
191
189
  c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a))
192
190
  distances = earth_radius * c
193
191
 
@@ -250,9 +248,7 @@ def line_of_sight(
250
248
  else:
251
249
  grazing_angle = -np.pi / 2
252
250
 
253
- return LOSResult(
254
- visible, grazing_angle, obstacle_distance, obstacle_elevation, min_clearance
255
- )
251
+ return LOSResult(visible, grazing_angle, obstacle_distance, obstacle_elevation, min_clearance)
256
252
 
257
253
 
258
254
  def viewshed(
@@ -5,31 +5,23 @@ This module provides complete tracker implementations that combine
5
5
  filtering, data association, and track management.
6
6
  """
7
7
 
8
- from pytcl.trackers.hypothesis import (
9
- Hypothesis,
10
- HypothesisAssignment,
11
- HypothesisTree,
12
- MHTTrack,
13
- MHTTrackStatus,
14
- compute_association_likelihood,
15
- generate_joint_associations,
16
- n_scan_prune,
17
- prune_hypotheses_by_probability,
18
- )
19
- from pytcl.trackers.mht import (
20
- MHTConfig,
21
- MHTResult,
22
- MHTTracker,
23
- )
24
- from pytcl.trackers.multi_target import (
25
- MultiTargetTracker,
26
- Track,
27
- TrackStatus,
28
- )
29
- from pytcl.trackers.single_target import (
30
- SingleTargetTracker,
31
- TrackState,
32
- )
8
+ from pytcl.trackers.hypothesis import Hypothesis
9
+ from pytcl.trackers.hypothesis import HypothesisAssignment
10
+ from pytcl.trackers.hypothesis import HypothesisTree
11
+ from pytcl.trackers.hypothesis import MHTTrack
12
+ from pytcl.trackers.hypothesis import MHTTrackStatus
13
+ from pytcl.trackers.hypothesis import compute_association_likelihood
14
+ from pytcl.trackers.hypothesis import generate_joint_associations
15
+ from pytcl.trackers.hypothesis import n_scan_prune
16
+ from pytcl.trackers.hypothesis import prune_hypotheses_by_probability
17
+ from pytcl.trackers.mht import MHTConfig
18
+ from pytcl.trackers.mht import MHTResult
19
+ from pytcl.trackers.mht import MHTTracker
20
+ from pytcl.trackers.multi_target import MultiTargetTracker
21
+ from pytcl.trackers.multi_target import Track
22
+ from pytcl.trackers.multi_target import TrackStatus
23
+ from pytcl.trackers.single_target import SingleTargetTracker
24
+ from pytcl.trackers.single_target import TrackState
33
25
 
34
26
  __all__ = [
35
27
  # Single target
@@ -13,7 +13,12 @@ References
13
13
  """
14
14
 
15
15
  from enum import Enum
16
- from typing import Dict, List, NamedTuple, Optional, Set, Tuple
16
+ from typing import Dict
17
+ from typing import List
18
+ from typing import NamedTuple
19
+ from typing import Optional
20
+ from typing import Set
21
+ from typing import Tuple
17
22
 
18
23
  import numpy as np
19
24
  from numpy.typing import NDArray
@@ -294,10 +299,7 @@ def n_scan_prune(
294
299
  hyp_tracks_at_cutoff.add(track_id)
295
300
 
296
301
  # Keep if tracks match (or if no tracks at cutoff)
297
- if (
298
- hyp_tracks_at_cutoff == best_tracks_at_cutoff
299
- or len(best_tracks_at_cutoff) == 0
300
- ):
302
+ if hyp_tracks_at_cutoff == best_tracks_at_cutoff or len(best_tracks_at_cutoff) == 0:
301
303
  pruned.append(hyp)
302
304
 
303
305
  # Renormalize probabilities
@@ -515,9 +517,7 @@ class HypothesisTree:
515
517
  new_hypotheses = []
516
518
 
517
519
  for hyp in self.hypotheses:
518
- for assoc_idx, (assoc, likelihood) in enumerate(
519
- zip(associations, likelihoods)
520
- ):
520
+ for assoc_idx, (assoc, likelihood) in enumerate(zip(associations, likelihoods)):
521
521
  # Compute new hypothesis probability
522
522
  new_prob = hyp.probability * likelihood
523
523
 
pytcl/trackers/mht.py CHANGED
@@ -15,20 +15,24 @@ 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
19
+ from typing import Dict
20
+ from typing import List
21
+ from typing import NamedTuple
22
+ from typing import Optional
23
+ from typing import Set
19
24
 
20
25
  import numpy as np
21
- from numpy.typing import ArrayLike, NDArray
26
+ from numpy.typing import ArrayLike
27
+ from numpy.typing import NDArray
22
28
  from scipy.stats import chi2
23
29
 
24
30
  from pytcl.assignment_algorithms.gating import mahalanobis_distance
25
- from pytcl.trackers.hypothesis import (
26
- Hypothesis,
27
- HypothesisTree,
28
- MHTTrack,
29
- MHTTrackStatus,
30
- generate_joint_associations,
31
- )
31
+ from pytcl.trackers.hypothesis import Hypothesis
32
+ from pytcl.trackers.hypothesis import HypothesisTree
33
+ from pytcl.trackers.hypothesis import MHTTrack
34
+ from pytcl.trackers.hypothesis import MHTTrackStatus
35
+ from pytcl.trackers.hypothesis import generate_joint_associations
32
36
 
33
37
 
34
38
  class MHTConfig(NamedTuple):
@@ -223,9 +227,7 @@ class MHTTracker:
223
227
  predicted_tracks = self._predict_tracks(current_tracks, F, Q)
224
228
 
225
229
  # Compute gating and likelihoods
226
- gated, likelihood_matrix = self._compute_gating_and_likelihoods(
227
- predicted_tracks, Z
228
- )
230
+ gated, likelihood_matrix = self._compute_gating_and_likelihoods(predicted_tracks, Z)
229
231
 
230
232
  # Generate associations for each hypothesis
231
233
  track_id_list = list(predicted_tracks.keys())
@@ -270,9 +272,7 @@ class MHTTracker:
270
272
 
271
273
  # Update tracks based on associations
272
274
  new_tracks_per_assoc: Dict[int, List[MHTTrack]] = {}
273
- updated_tracks: Dict[int, Dict[int, MHTTrack]] = (
274
- {}
275
- ) # assoc_idx -> track_id -> track
275
+ updated_tracks: Dict[int, Dict[int, MHTTrack]] = {} # assoc_idx -> track_id -> track
276
276
 
277
277
  for assoc_idx, assoc in enumerate(associations):
278
278
  updated_tracks[assoc_idx] = {}
@@ -295,9 +295,7 @@ class MHTTracker:
295
295
  updated_tracks[assoc_idx][track_id] = upd_track
296
296
 
297
297
  # Handle unassigned measurements -> new tracks
298
- assigned_meas = set(
299
- meas_idx for meas_idx in assoc.values() if meas_idx >= 0
300
- )
298
+ assigned_meas = set(meas_idx for meas_idx in assoc.values() if meas_idx >= 0)
301
299
  for j in range(n_meas):
302
300
  if j not in assigned_meas:
303
301
  new_track = self._initiate_track(Z[j], j)
@@ -408,9 +406,7 @@ class MHTTracker:
408
406
 
409
407
  # Clutter and new track terms for unassigned measurements
410
408
  n_unassigned = len(Z) - len(used_meas)
411
- likelihood *= (
412
- self.config.clutter_density + self.config.new_track_weight
413
- ) ** n_unassigned
409
+ likelihood *= (self.config.clutter_density + self.config.new_track_weight) ** n_unassigned
414
410
 
415
411
  return likelihood
416
412
 
@@ -534,9 +530,7 @@ class MHTTracker:
534
530
  new_hypotheses = []
535
531
 
536
532
  for hyp in self.hypothesis_tree.hypotheses:
537
- for assoc_idx, (assoc, likelihood) in enumerate(
538
- zip(associations, likelihoods)
539
- ):
533
+ for assoc_idx, (assoc, likelihood) in enumerate(zip(associations, likelihoods)):
540
534
  # Compute new hypothesis probability
541
535
  new_prob = hyp.probability * likelihood
542
536
 
@@ -6,15 +6,17 @@ and Kalman filtering with track management (initiation, maintenance, deletion).
6
6
  """
7
7
 
8
8
  from enum import Enum
9
- from typing import Callable, List, NamedTuple, Optional
9
+ from typing import Callable
10
+ from typing import List
11
+ from typing import NamedTuple
12
+ from typing import Optional
10
13
 
11
14
  import numpy as np
12
- from numpy.typing import ArrayLike, NDArray
15
+ from numpy.typing import ArrayLike
16
+ from numpy.typing import NDArray
13
17
 
14
- from pytcl.assignment_algorithms import (
15
- chi2_gate_threshold,
16
- gnn_association,
17
- )
18
+ from pytcl.assignment_algorithms import chi2_gate_threshold
19
+ from pytcl.assignment_algorithms import gnn_association
18
20
 
19
21
 
20
22
  class TrackStatus(Enum):
@@ -4,10 +4,13 @@ Single-target tracker implementation.
4
4
  This module provides a simple single-target tracker using Kalman filtering.
5
5
  """
6
6
 
7
- from typing import Callable, NamedTuple, Optional
7
+ from typing import Callable
8
+ from typing import NamedTuple
9
+ from typing import Optional
8
10
 
9
11
  import numpy as np
10
- from numpy.typing import ArrayLike, NDArray
12
+ from numpy.typing import ArrayLike
13
+ from numpy.typing import NDArray
11
14
 
12
15
 
13
16
  class TrackState(NamedTuple):
@@ -1,148 +0,0 @@
1
- pytcl/__init__.py,sha256=gskiDd7_BZ-aWQ3h_uxnX6oGP3ylOmb69Mws0xLnEAQ,1894
2
- pytcl/assignment_algorithms/__init__.py,sha256=f9V-TkEVmiKYYyth4PTpDfJvA7yYV_ys6Zix-QwWIYY,2136
3
- pytcl/assignment_algorithms/data_association.py,sha256=X6Kww9-J2WLxU1790w7dRvAFdM90RSXHvs7IF26zweQ,11427
4
- pytcl/assignment_algorithms/gating.py,sha256=fN_oAOkv7nYYOWE1oPOLrcCn3xEpKdMVlFSbRMAURxY,10815
5
- pytcl/assignment_algorithms/jpda.py,sha256=Hv55j3J9qVwzlUfWdXdSasodTyB1ZKdgEpo5dBh95O8,19582
6
- pytcl/assignment_algorithms/three_dimensional/__init__.py,sha256=1Q40OUlUQoo7YKEucwdrSNo3D4A0Zibvkr8z4TpueBg,526
7
- pytcl/assignment_algorithms/three_dimensional/assignment.py,sha256=9BJhwlYu3JJ0kZ9sRyKKfpdvQdL4WYYHCtLbvaWycBw,19212
8
- pytcl/assignment_algorithms/two_dimensional/__init__.py,sha256=4Evsn__9hTfI2i8m8Ngl-Zy0Fa2OydKmDKlZlH6jaao,778
9
- pytcl/assignment_algorithms/two_dimensional/assignment.py,sha256=eh87MBb-uiUSI1MXj4HrreRKB6Z8rxAyDkNQ8-u4SbM,11848
10
- pytcl/assignment_algorithms/two_dimensional/kbest.py,sha256=yiTToLuP7xWxQlQ8E-fpgXg-5iu0nnXcJXStjUB0nOE,17284
11
- pytcl/astronomical/__init__.py,sha256=SKELDaDhxpvCo1dMswBQYOQr_Th3ShuzZTzxZMdhE-U,5650
12
- pytcl/astronomical/lambert.py,sha256=Lc8FT1JmpI9WSXsG2s5vIRkSoBSV7r5hd3o2bGh2Ojo,15607
13
- pytcl/astronomical/orbital_mechanics.py,sha256=8GssRanwTowCl6PJYqmB_SDnNznLUq5gkPa3j6iEo3U,19965
14
- pytcl/astronomical/reference_frames.py,sha256=GDak7af6BqOwGnCUxkvFoeqd_H2TMubdjG9lGPCoUB4,15799
15
- pytcl/astronomical/time_systems.py,sha256=Jg0Zaq60hc4Ts1aQtb5bK4KSZhz-uQse8gYC89Y0-TA,15243
16
- pytcl/atmosphere/__init__.py,sha256=QAYgJYzgs0kreRV8fByii4p477LCxBDfrXB_cL7SYkM,706
17
- pytcl/atmosphere/models.py,sha256=pMLv8D7qoFqLZrlbTHLJJULOdDdhPskJ1m7KVKLV63E,9584
18
- pytcl/clustering/__init__.py,sha256=bYdhC_XJEt6KUUni9bIPxaddXNEGmIJQvGkA14rK4J8,1697
19
- pytcl/clustering/dbscan.py,sha256=PS6QlOwHFerbZNEb3zcNhN4oNQpgOOw5y0WskQzyKIo,7364
20
- pytcl/clustering/gaussian_mixture.py,sha256=U5U0Z46tZWdTLNdNNNJenoeviwZRAOvexVFYVLt4QMc,22865
21
- pytcl/clustering/hierarchical.py,sha256=Hw9BFCn5df_ATpJX63R3B31MHz27ztCw9ihMDIlI688,14202
22
- pytcl/clustering/kmeans.py,sha256=250FQyDol5S_Y4TznNn9cEuE96UDp7wvEkPZJ1DLul8,10697
23
- pytcl/containers/__init__.py,sha256=t8oRtusBrh6G2dEk2PcofmxrpLPQ9nOJwH19GyKnNcc,1699
24
- pytcl/containers/cluster_set.py,sha256=_lZ39PNHTL7fUEZAwBF2ICK6v0GjZKpeUOg0knEdPzo,22760
25
- pytcl/containers/covertree.py,sha256=1JWqXxoUFLxuMnjwj2qf0iz2uPzdujQYdwJW3l5qsOs,13282
26
- pytcl/containers/kd_tree.py,sha256=pxRC62RYkqz9zXPz6c1fubmtPPBDLYA5I9AXMAoGanw,16348
27
- pytcl/containers/measurement_set.py,sha256=Kr29mlJOCyGMYhMnE89f-W72aunlv4p04QAdfCZcm-0,12687
28
- pytcl/containers/rtree.py,sha256=gv2EztvPnaAXEa6OoFnOYBY1MfTwjNMYh_BCiIomHJk,15450
29
- pytcl/containers/track_list.py,sha256=6q9Qgcwm-8H_JqtOCsMssF27av4XaSkhfDl-MWb1ABc,12520
30
- pytcl/containers/vptree.py,sha256=6fBNHrezkmj7L2nH0-2bONRN92f5cZAhS-5vaI1JZnA,8814
31
- pytcl/coordinate_systems/__init__.py,sha256=jwYhu_-9AvOeP9WLG9PYtyDwfe0GjxNZ9-xCqiLymW4,3909
32
- pytcl/coordinate_systems/conversions/__init__.py,sha256=PkNevB78vBw0BkalydJBbQO91AyiMJxKRrgJNt4HsYc,1100
33
- pytcl/coordinate_systems/conversions/geodetic.py,sha256=qQSnJRt3jg5KiostvzyslPIbfn-1xBluo1r12oavWTQ,15737
34
- pytcl/coordinate_systems/conversions/spherical.py,sha256=q7k9l5mJbVzVdNj9Gcq4ibFxax8z_mVpJfITRBzx630,10812
35
- pytcl/coordinate_systems/jacobians/__init__.py,sha256=CRGB8GzvGT_sr4Ynm51S7gSX8grqt1pO1Pq1MWmHPTs,890
36
- pytcl/coordinate_systems/jacobians/jacobians.py,sha256=1KufIoktm9mXLO34X9KjysdMpu7itGwfssRyAdkTTN8,11703
37
- pytcl/coordinate_systems/projections/__init__.py,sha256=-IaYuCO9EU3ytik2KqIbFLP2YZScdaLsNJOXZJev6s0,2438
38
- pytcl/coordinate_systems/projections/projections.py,sha256=yODS7n1gA4jsCJcU8EaeclHrbUBsZI9O2M_XJs2HOXs,33169
39
- pytcl/coordinate_systems/rotations/__init__.py,sha256=nqAz4iJd2hEOX_r7Tz4cE524sShyxdbtcQ5m56RrDLg,1047
40
- pytcl/coordinate_systems/rotations/rotations.py,sha256=FAYHkShQcpOlWJjtvLfNvtCx-a56pr-cbpo0QjC5W9U,18227
41
- pytcl/core/__init__.py,sha256=H5JJPS-43DfF1UG7fSgV-VMTcZFBO8GuzDW1lM_1sm4,1152
42
- pytcl/core/array_utils.py,sha256=SsgEiAoRCWxAVKq1aa5-nPdOi-2AB6XNObu0IaGClUk,13983
43
- pytcl/core/constants.py,sha256=lZVDK5zsSR02_4b2Nqx9KDtZT9QaYhkZ9wuoODbifd4,8693
44
- pytcl/core/validation.py,sha256=WRlzMlUihtqc3XZoWOTFK0sBAZVDIwTMGCiWcX5OZVY,13093
45
- pytcl/dynamic_estimation/__init__.py,sha256=jA5FF6kHYklY5LMOfZaKcCeiPTpVe8vHIMp3ECDOmsc,4582
46
- pytcl/dynamic_estimation/imm.py,sha256=t4dlutWeCLtAMl-ylNbxMUC3gbRBF_sXI3bX4PAk-OQ,22080
47
- pytcl/dynamic_estimation/information_filter.py,sha256=x7iQwO_iJT1dCSvDws5LqD3yAtjw9QVGUfMPcXn1IA4,17349
48
- pytcl/dynamic_estimation/smoothers.py,sha256=qC_g0YG0U4L_7rGBpcZzYcb11A--Hc8tb0fxWXIJdxM,18931
49
- pytcl/dynamic_estimation/batch_estimation/__init__.py,sha256=JQ0s76Enov5a7plA4EnUua4t-7etikQrwr5z4WIjUeo,46
50
- pytcl/dynamic_estimation/kalman/__init__.py,sha256=yoFLj0n-NRkdZnRVL-BkHBlATk8pfZEVlsY3BhSYgKc,2387
51
- pytcl/dynamic_estimation/kalman/extended.py,sha256=_deQTnUGOp_BlhP-FDEY0LOjgUMN32FQn0V12unCM4A,10397
52
- pytcl/dynamic_estimation/kalman/linear.py,sha256=1Zgg9gZya0Vxs9im7sPUqLj0Luo463vS-RSa6GCReFI,12248
53
- pytcl/dynamic_estimation/kalman/square_root.py,sha256=Hw1F4_Zc7IA6Mt1WCkjx1UuLAUmNhM5vPLvueb7oRSA,26931
54
- pytcl/dynamic_estimation/kalman/unscented.py,sha256=VmYE8LuM1nWpFTmD39iXdEZ3m41IsurCCbXJ19-ERFs,15440
55
- pytcl/dynamic_estimation/measurement_update/__init__.py,sha256=8rlyJwVpxf0fZj-AFo1hlewvryZRhUzcy3F8uMe6I8c,48
56
- pytcl/dynamic_estimation/particle_filters/__init__.py,sha256=-DRF5rVF2749suLlArmkTvVkqeMcV_mIx0eLeTj6wNU,906
57
- pytcl/dynamic_estimation/particle_filters/bootstrap.py,sha256=FcF4W_NM5ZqJnw5fq4rq6fLY9X1r4uFJOiAX9a-NGG8,13371
58
- pytcl/dynamic_models/__init__.py,sha256=Cd8MyyYuB8gMnepkPA-HSwTaKFPThnqoKOhdjVOsXWg,2783
59
- pytcl/dynamic_models/continuous_time/__init__.py,sha256=dAkfEddLkfMvDalK9v2GRBvaZV1KgqYpFBLOnoiFClw,1023
60
- pytcl/dynamic_models/continuous_time/dynamics.py,sha256=CDwqn-66eUwXA5xfIjaG6A4EDBqtOyQ3aWarJr9QH4g,12858
61
- pytcl/dynamic_models/discrete_time/__init__.py,sha256=pJ-VWMPkIdOcARM3CXlpYZcdUS5jWmqC6z2DXTd-b7c,966
62
- pytcl/dynamic_models/discrete_time/coordinated_turn.py,sha256=jrSGCKiAdXaFIJBLzRyAv0xxxpOHOBnAtDHyu7VYsm8,7206
63
- pytcl/dynamic_models/discrete_time/polynomial.py,sha256=zv5V-AbuaXlIj36n-YkOEyC74jV2vczxpCW09P0kmi0,5529
64
- pytcl/dynamic_models/discrete_time/singer.py,sha256=wZS3Nad-YyPZp8Mle8Sf5GgW0-t4TxMRcnbc42HtQnA,3861
65
- pytcl/dynamic_models/process_noise/__init__.py,sha256=3KVpLzGaNaR36DloPG5R1yaZWcR5QpdUJp2hwh5KFnk,950
66
- pytcl/dynamic_models/process_noise/coordinated_turn.py,sha256=w7bHUImLPL5m3KYenfNgAnHPCRtAyYESbsFc6lQKXRg,4768
67
- pytcl/dynamic_models/process_noise/polynomial.py,sha256=natfpsdN3qM9VzPeXF_nBpsbRI74S1WkkRCaaem6EQo,7620
68
- pytcl/dynamic_models/process_noise/singer.py,sha256=lsJDT6xOvcS_qQKFtgHX0L7Ukpy4D7HgvPT8Q3I0ibU,3901
69
- pytcl/gravity/__init__.py,sha256=5xNdQSrrkt7-1-JPOYqR38CqvNJ7qKlPyMK36DGm6-I,3693
70
- pytcl/gravity/clenshaw.py,sha256=1BdxzU8IfGGd68H_U35soIJkiOHphY35e9mLElhPTOg,15364
71
- pytcl/gravity/egm.py,sha256=QTRuvCiMjuNQdZF163OGwjxuivpGu2dB6E0zQLbKPP8,18083
72
- pytcl/gravity/models.py,sha256=rdY3Do4M1eRFO74gu3xy-bBn7tox3zM49wYbfnsIQWw,11159
73
- pytcl/gravity/spherical_harmonics.py,sha256=uZasz-w2K16sWT6xrNIPyTEP6MSlMQSe_BCWpXhRkWY,14722
74
- pytcl/gravity/tides.py,sha256=hef_BGewFGD7dJwg0t09Z6tfWLco_avATLuu66rnTpI,27733
75
- pytcl/magnetism/__init__.py,sha256=FNggjh99tEybKM2RxuX_EJlgu3U3CrREBadXOvRguGA,2549
76
- pytcl/magnetism/emm.py,sha256=5Jwl99wvdKYtx1-3LBB7x-w5KT-fqLiRg7uBW0Ai_Gw,22292
77
- pytcl/magnetism/igrf.py,sha256=3g0PsH8IdbwQQS28OR5XWD-g-QxvfUva7jOkKToxndQ,13384
78
- pytcl/magnetism/wmm.py,sha256=p0H7Eo02iB6nEMvGyvjsrAWOSKrIye6PGwQtNKfHaNw,15999
79
- pytcl/mathematical_functions/__init__.py,sha256=zeJ1ffRRl83k2NHn3HTn-fgtFoWNPq6LCALc3xRo4Do,3767
80
- pytcl/mathematical_functions/basic_matrix/__init__.py,sha256=kZv3kMAEHBdVxhbyMxTyM0s-4XJP1tK6po82UsIE4tc,1318
81
- pytcl/mathematical_functions/basic_matrix/decompositions.py,sha256=PWJsFDiXM2T78RHdxBJZPFnl8kFbNZQpHrbpw0mhE00,12268
82
- pytcl/mathematical_functions/basic_matrix/special_matrices.py,sha256=kOozwP2CHAj4qyO7Z9ct6GwDMkmHkk1bQa0e9G98FgA,13499
83
- pytcl/mathematical_functions/combinatorics/__init__.py,sha256=byuHI0WkxOkQF8egrfjEr-awB2visWDXlGMnDux5IBg,1043
84
- pytcl/mathematical_functions/combinatorics/combinatorics.py,sha256=3EgkWdBqQ9e6JU34bec9EeCEmB-46tUSXXTAJrckSO4,12314
85
- pytcl/mathematical_functions/continuous_optimization/__init__.py,sha256=lck60eeCUOsRpEzPHBY3kiLKwNz_fhmYoUGP3lTmTwk,55
86
- pytcl/mathematical_functions/geometry/__init__.py,sha256=DhCmux9-6zxYRzlhQ9du18kvUL-leiiZwdd3Cmb5WX0,1092
87
- pytcl/mathematical_functions/geometry/geometry.py,sha256=l63wQnhCtJwVHZOJeONX1qyJ5Sedji8etgxwJCFtH8Y,16403
88
- pytcl/mathematical_functions/interpolation/__init__.py,sha256=HDhP7ZsgUrXFBNJ_eCZEdp5gizWJ-BxvkQSCMnvBg3A,677
89
- pytcl/mathematical_functions/interpolation/interpolation.py,sha256=2cXMDgWBjWDGHnK1K_lawFlJL8oPl5AQGf9MNgsESfo,12610
90
- pytcl/mathematical_functions/numerical_integration/__init__.py,sha256=iXiHzyV_KIhCv7tXErXlN1_fUEACN6yN3CYDHRA7esw,974
91
- pytcl/mathematical_functions/numerical_integration/quadrature.py,sha256=ZRMKs0vbcgFDe1Sr8sjyEOkALLmJU4zKRJjoPEcXrUc,15670
92
- pytcl/mathematical_functions/polynomials/__init__.py,sha256=WJWZcoQhnvy5f59-kncMTgD9mCtgwfDgULvDYYHS5ys,43
93
- pytcl/mathematical_functions/signal_processing/__init__.py,sha256=_SzzBVtxmSvP8FKeogRdNmFo8FOVDDoexVOqd-lE7do,2325
94
- pytcl/mathematical_functions/signal_processing/detection.py,sha256=9F0xdy3hMat1czSWAQYMExn0kY5DBRpyBneAfjjHUVI,30377
95
- pytcl/mathematical_functions/signal_processing/filters.py,sha256=8Ojf4h4rfiucBXqUmB1odvHH41Gf3rPwmWCMKb-qzWk,23435
96
- pytcl/mathematical_functions/signal_processing/matched_filter.py,sha256=AahJZRZk2IIXzRL7www0n8bc0XoKabaLOe8yYNSjuDY,22893
97
- pytcl/mathematical_functions/special_functions/__init__.py,sha256=qDPGfee1i1NkVi9LXJKnsWXL3CWHkPQINrkwqLqB8YU,3796
98
- pytcl/mathematical_functions/special_functions/bessel.py,sha256=M0mwLQBaUXEHA8wyKReJ2D66I1v1XR7y-txAipd-WDs,14377
99
- pytcl/mathematical_functions/special_functions/debye.py,sha256=Nchjwkl1vzSL1L7nQpslb-lvT49LgTfdTIQMeSNn4vQ,6689
100
- pytcl/mathematical_functions/special_functions/elliptic.py,sha256=WyzBkrfZufIR5dUmCKGcxp6KNpVDrU89NGLDyRrZOqQ,7418
101
- pytcl/mathematical_functions/special_functions/error_functions.py,sha256=a3SS8FYAMRv1KdCmebOZL95yjvVt9gZRF2XOjHvQ9M8,6253
102
- pytcl/mathematical_functions/special_functions/gamma_functions.py,sha256=xXN_9SCokH10HjE8PpaPKHYVK_RZRHRAbZgR2mZYIAA,10191
103
- pytcl/mathematical_functions/special_functions/hypergeometric.py,sha256=gKn_tXboEst7pVDiW15IbKFAANM4XVqKtDc1dmWL-2A,9768
104
- pytcl/mathematical_functions/special_functions/lambert_w.py,sha256=ivRc4KH5Lwoxb_yijrJEwG0ITa0hhcYF7_gCfVBBNW4,6855
105
- pytcl/mathematical_functions/special_functions/marcum_q.py,sha256=OZ5QjIB1e_XvRG8A-3dbZ13YXHtdk2EYVEPaqtgVr14,9580
106
- pytcl/mathematical_functions/statistics/__init__.py,sha256=dfypStgmnFmOrnWcm-3CEvLinONHraFgx9O66_37bqw,1278
107
- pytcl/mathematical_functions/statistics/distributions.py,sha256=icfFIIKCEFzkpFHuYGWL197nm8wvS7UPJlr9kd_uEgw,19373
108
- pytcl/mathematical_functions/statistics/estimators.py,sha256=TLnYXSwk5MzBakZrzDBupbOB3ONmJI7q1-oB2xuSVQM,10831
109
- pytcl/mathematical_functions/transforms/__init__.py,sha256=SPXSKHjqR6B_8pvgtbtOnEiCpU-u0JF2s7hAlhb0BbI,2343
110
- pytcl/mathematical_functions/transforms/fourier.py,sha256=QH6OaTzw4kN6M-DuSmwB_5b-wu_4yP5I2CUmNEyLORM,20737
111
- pytcl/mathematical_functions/transforms/stft.py,sha256=zQapXl-v69_RDPwMqci83jah17GyAfnr3gx0budv2Cg,18619
112
- pytcl/mathematical_functions/transforms/wavelets.py,sha256=dm273Z_t13BlEVSlHTaGE7jR1ocugL7lEkcO499U7bY,21656
113
- pytcl/misc/__init__.py,sha256=SCHf_lQVfdl2gwUluHBiIloTF8HRH8EkgYfbNr7zOug,33
114
- pytcl/navigation/__init__.py,sha256=9tUhEgPVugA8nmZ9rvOaAntCd7rDPgW2RBLHqaDAXSc,5864
115
- pytcl/navigation/geodesy.py,sha256=M9XXfBTMCRdaWMV2-ViDSTEt94WZnMtxMeJQ1FAgQHY,17227
116
- pytcl/navigation/great_circle.py,sha256=TtlkWZbzr-HzSt4ultG_h137ZnX0pJZx_87kr3uvpjI,20923
117
- pytcl/navigation/ins.py,sha256=V3ZA4z8y5E6PBCd1FhifR5VaCU7DRAn2fb7W0LilByo,31168
118
- pytcl/navigation/ins_gnss.py,sha256=euKF5JGgwmVBsw3jBf7_wa2z1BpZeVbSNmBuwzhGS6c,30157
119
- pytcl/navigation/rhumb.py,sha256=lr1c3iEXfoOSfIyyXSRWv6He5TlaxEHbJy-dhqM1gRw,18224
120
- pytcl/performance_evaluation/__init__.py,sha256=tM2pnBfDb2XbnLt4Y5MQ6w6XBwFy_5bf_y0toZmxx88,1859
121
- pytcl/performance_evaluation/estimation_metrics.py,sha256=X1ZCpp8m6DV14N2wbMvlRwfORRKga8DgKmG3dROyJqA,12351
122
- pytcl/performance_evaluation/track_metrics.py,sha256=Nd3royJkAelZV-Qggl8i72e7WocCxWomgliArvVAEkc,13342
123
- pytcl/physical_values/__init__.py,sha256=SGbg6b0d4dWebE3baW4OlJshL00grG5E4wABw6jxl20,44
124
- pytcl/plotting/__init__.py,sha256=YtYnKYHL5lN6EaT_bwwR3h89NW0HSMToIWHhHBxcidY,3126
125
- pytcl/plotting/coordinates.py,sha256=h39H855Qjqtcly62m09demaOFpfMs_8EF_nXhoLBSBs,17198
126
- pytcl/plotting/ellipses.py,sha256=bcns6dfNK4bwA_QBshscYhbAz_5wegwyqjDzzoUdWsQ,12465
127
- pytcl/plotting/metrics.py,sha256=zbJr5P2kQg7-rGpGHsN7rC02S0JLOpPUZeoscQem7uQ,18148
128
- pytcl/plotting/tracks.py,sha256=cqZG71ZHM-wDSzjH4I4kCESORIiZjmGesQtADmAi4gc,23034
129
- pytcl/scheduling/__init__.py,sha256=jTqMSKcsCrWU_Fh6WaT6BW5WatNHyyEYjFbsv6X18Oc,39
130
- pytcl/static_estimation/__init__.py,sha256=sSEhqq35jq_MpRLnBtWjKXwGZ9dqIw71iwji-TNwXmc,2222
131
- pytcl/static_estimation/least_squares.py,sha256=8ouOyRGC7K-W8fynZMWlc2-KAFojvTbuzcqi5uS_sVA,13432
132
- pytcl/static_estimation/maximum_likelihood.py,sha256=P6BKMcuzzDu_Qc6mX9KLI-zPWFX_NabbA6AKYjkNBcY,21581
133
- pytcl/static_estimation/robust.py,sha256=egBLKWmo6d9PzP6LDh0J7ee4j6hYZh8kAb9TR5uC2so,18527
134
- pytcl/terrain/__init__.py,sha256=e7plNQI5Y_jpZ24r82AgqdX0ChmmyYoeT7HReclnGXc,3228
135
- pytcl/terrain/dem.py,sha256=rg2o0h0ZDrfxvtYhnE2A5tdzRnCmqcihu4w1uNJdH3Y,20814
136
- pytcl/terrain/loaders.py,sha256=KBs1vdYUYW-0ETIujRv4-WxO-bExZk-FvPLY5l6gyTc,27028
137
- pytcl/terrain/visibility.py,sha256=nIJr9AVk7C8GCpJV4UDvUjhmAieycWD8BLepAMUBMIQ,22739
138
- pytcl/trackers/__init__.py,sha256=8-KpFtxS0n83B-dq4x0X4V1TQGHZnNSzdujAJUGcjxc,1198
139
- pytcl/trackers/hypothesis.py,sha256=RApWfji-f0-a68KnAJela0BvPdIlOY_FV_cYJFmVUoE,17353
140
- pytcl/trackers/mht.py,sha256=7mwhMmja3ri2wnx7W1wueDGn2r3ArwAxJDPUJ7IZAkQ,20617
141
- pytcl/trackers/multi_target.py,sha256=7ZL8V25TO_rEMtQm2eYkScesDQHC9qXZVHLHyVbxy3M,10529
142
- pytcl/trackers/single_target.py,sha256=Yy3FwaNTArMWcaod-0HVeiioNV4xLWxNDn_7ZPVqQYs,6562
143
- pytcl/transponders/__init__.py,sha256=5fL4u3lKCYgPLo5uFeuZbtRZkJPABntuKYGUvVgMMEI,41
144
- nrl_tracker-0.21.4.dist-info/LICENSE,sha256=rB5G4WppIIUzMOYr2N6uyYlNJ00hRJqE5tie6BMvYuE,1612
145
- nrl_tracker-0.21.4.dist-info/METADATA,sha256=kfdnUMvBqNlpI3skCRZZQIQF8gYBLHSGcgSZ5gGwDXw,10005
146
- nrl_tracker-0.21.4.dist-info/WHEEL,sha256=pL8R0wFFS65tNSRnaOVrsw9EOkOqxLrlUPenUYnJKNo,91
147
- nrl_tracker-0.21.4.dist-info/top_level.txt,sha256=17megxcrTPBWwPZTh6jTkwTKxX7No-ZqRpyvElnnO-s,6
148
- nrl_tracker-0.21.4.dist-info/RECORD,,