nrl-tracker 0.22.3__py3-none-any.whl → 0.22.4__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.
- {nrl_tracker-0.22.3.dist-info → nrl_tracker-0.22.4.dist-info}/METADATA +1 -1
- {nrl_tracker-0.22.3.dist-info → nrl_tracker-0.22.4.dist-info}/RECORD +69 -69
- pytcl/__init__.py +1 -1
- pytcl/assignment_algorithms/gating.py +3 -3
- pytcl/assignment_algorithms/jpda.py +12 -4
- pytcl/assignment_algorithms/two_dimensional/kbest.py +3 -1
- pytcl/astronomical/ephemerides.py +17 -9
- pytcl/astronomical/lambert.py +14 -4
- pytcl/astronomical/orbital_mechanics.py +3 -1
- pytcl/astronomical/reference_frames.py +3 -1
- pytcl/astronomical/relativity.py +8 -2
- pytcl/atmosphere/models.py +3 -1
- pytcl/clustering/gaussian_mixture.py +8 -4
- pytcl/clustering/hierarchical.py +5 -1
- pytcl/clustering/kmeans.py +3 -1
- pytcl/containers/cluster_set.py +9 -3
- pytcl/containers/measurement_set.py +6 -2
- pytcl/containers/rtree.py +5 -2
- pytcl/coordinate_systems/conversions/geodetic.py +15 -3
- pytcl/coordinate_systems/projections/projections.py +38 -11
- pytcl/coordinate_systems/rotations/rotations.py +3 -1
- pytcl/core/array_utils.py +4 -1
- pytcl/core/constants.py +3 -1
- pytcl/core/validation.py +17 -6
- pytcl/dynamic_estimation/imm.py +9 -3
- pytcl/dynamic_estimation/kalman/square_root.py +6 -2
- pytcl/dynamic_estimation/particle_filters/bootstrap.py +6 -2
- pytcl/dynamic_estimation/smoothers.py +3 -1
- pytcl/dynamic_models/process_noise/polynomial.py +6 -2
- pytcl/gravity/clenshaw.py +6 -2
- pytcl/gravity/egm.py +3 -1
- pytcl/gravity/models.py +3 -1
- pytcl/gravity/spherical_harmonics.py +10 -4
- pytcl/gravity/tides.py +16 -7
- pytcl/magnetism/emm.py +12 -3
- pytcl/magnetism/wmm.py +9 -2
- pytcl/mathematical_functions/basic_matrix/decompositions.py +3 -1
- pytcl/mathematical_functions/combinatorics/combinatorics.py +3 -1
- pytcl/mathematical_functions/geometry/geometry.py +12 -4
- pytcl/mathematical_functions/interpolation/interpolation.py +3 -1
- pytcl/mathematical_functions/signal_processing/detection.py +6 -3
- pytcl/mathematical_functions/signal_processing/filters.py +6 -2
- pytcl/mathematical_functions/signal_processing/matched_filter.py +4 -2
- pytcl/mathematical_functions/special_functions/elliptic.py +3 -1
- pytcl/mathematical_functions/special_functions/gamma_functions.py +3 -1
- pytcl/mathematical_functions/special_functions/lambert_w.py +3 -1
- pytcl/mathematical_functions/statistics/distributions.py +36 -12
- pytcl/mathematical_functions/statistics/estimators.py +3 -1
- pytcl/mathematical_functions/transforms/stft.py +9 -3
- pytcl/mathematical_functions/transforms/wavelets.py +18 -6
- pytcl/navigation/geodesy.py +31 -9
- pytcl/navigation/great_circle.py +12 -4
- pytcl/navigation/ins.py +8 -2
- pytcl/navigation/ins_gnss.py +25 -7
- pytcl/navigation/rhumb.py +10 -3
- pytcl/performance_evaluation/track_metrics.py +3 -1
- pytcl/plotting/coordinates.py +17 -5
- pytcl/plotting/metrics.py +9 -3
- pytcl/plotting/tracks.py +11 -3
- pytcl/static_estimation/least_squares.py +2 -1
- pytcl/static_estimation/maximum_likelihood.py +3 -3
- pytcl/terrain/dem.py +8 -2
- pytcl/terrain/loaders.py +13 -5
- pytcl/terrain/visibility.py +7 -2
- pytcl/trackers/hypothesis.py +7 -2
- pytcl/trackers/mht.py +15 -5
- {nrl_tracker-0.22.3.dist-info → nrl_tracker-0.22.4.dist-info}/LICENSE +0 -0
- {nrl_tracker-0.22.3.dist-info → nrl_tracker-0.22.4.dist-info}/WHEEL +0 -0
- {nrl_tracker-0.22.3.dist-info → nrl_tracker-0.22.4.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: nrl-tracker
|
|
3
|
-
Version: 0.22.
|
|
3
|
+
Version: 0.22.4
|
|
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
|
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
pytcl/__init__.py,sha256=
|
|
1
|
+
pytcl/__init__.py,sha256=uwpLiSYxFSvCeykvejvHVAGffLi6OxFvWNGHWqN3p4w,1894
|
|
2
2
|
pytcl/assignment_algorithms/__init__.py,sha256=f9V-TkEVmiKYYyth4PTpDfJvA7yYV_ys6Zix-QwWIYY,2136
|
|
3
3
|
pytcl/assignment_algorithms/data_association.py,sha256=tsRxWJZk9aAPmE99BKXGouEpFfZrjPjb4HXvgxFUHhU,11405
|
|
4
|
-
pytcl/assignment_algorithms/gating.py,sha256=
|
|
5
|
-
pytcl/assignment_algorithms/jpda.py,sha256
|
|
4
|
+
pytcl/assignment_algorithms/gating.py,sha256=fN_oAOkv7nYYOWE1oPOLrcCn3xEpKdMVlFSbRMAURxY,10815
|
|
5
|
+
pytcl/assignment_algorithms/jpda.py,sha256=Hv55j3J9qVwzlUfWdXdSasodTyB1ZKdgEpo5dBh95O8,19582
|
|
6
6
|
pytcl/assignment_algorithms/three_dimensional/__init__.py,sha256=1Q40OUlUQoo7YKEucwdrSNo3D4A0Zibvkr8z4TpueBg,526
|
|
7
7
|
pytcl/assignment_algorithms/three_dimensional/assignment.py,sha256=9BJhwlYu3JJ0kZ9sRyKKfpdvQdL4WYYHCtLbvaWycBw,19212
|
|
8
8
|
pytcl/assignment_algorithms/two_dimensional/__init__.py,sha256=4Evsn__9hTfI2i8m8Ngl-Zy0Fa2OydKmDKlZlH6jaao,778
|
|
9
9
|
pytcl/assignment_algorithms/two_dimensional/assignment.py,sha256=eh87MBb-uiUSI1MXj4HrreRKB6Z8rxAyDkNQ8-u4SbM,11848
|
|
10
|
-
pytcl/assignment_algorithms/two_dimensional/kbest.py,sha256=
|
|
10
|
+
pytcl/assignment_algorithms/two_dimensional/kbest.py,sha256=yiTToLuP7xWxQlQ8E-fpgXg-5iu0nnXcJXStjUB0nOE,17284
|
|
11
11
|
pytcl/astronomical/__init__.py,sha256=Dtf6hqXyKyFL5VP-sqI7m2QGK6l-rqRGxVIhgDuYHOg,7182
|
|
12
|
-
pytcl/astronomical/ephemerides.py,sha256=
|
|
13
|
-
pytcl/astronomical/lambert.py,sha256=
|
|
14
|
-
pytcl/astronomical/orbital_mechanics.py,sha256=
|
|
15
|
-
pytcl/astronomical/reference_frames.py,sha256=
|
|
16
|
-
pytcl/astronomical/relativity.py,sha256=
|
|
12
|
+
pytcl/astronomical/ephemerides.py,sha256=x2500S0rF1D2h0dMR_2BnZaChbBZTooHLdrevttxlAc,16471
|
|
13
|
+
pytcl/astronomical/lambert.py,sha256=Lc8FT1JmpI9WSXsG2s5vIRkSoBSV7r5hd3o2bGh2Ojo,15607
|
|
14
|
+
pytcl/astronomical/orbital_mechanics.py,sha256=8GssRanwTowCl6PJYqmB_SDnNznLUq5gkPa3j6iEo3U,19965
|
|
15
|
+
pytcl/astronomical/reference_frames.py,sha256=GDak7af6BqOwGnCUxkvFoeqd_H2TMubdjG9lGPCoUB4,15799
|
|
16
|
+
pytcl/astronomical/relativity.py,sha256=YPsXLD-VRh-nqs1laC-wKpRO00fflm4GkyLhojPydbo,15441
|
|
17
17
|
pytcl/astronomical/time_systems.py,sha256=Jg0Zaq60hc4Ts1aQtb5bK4KSZhz-uQse8gYC89Y0-TA,15243
|
|
18
18
|
pytcl/atmosphere/__init__.py,sha256=TTVz4hAM48Xd3jr6GKrR2GAABpx2z0aWvtzb9uIQiHk,737
|
|
19
|
-
pytcl/atmosphere/models.py,sha256=
|
|
19
|
+
pytcl/atmosphere/models.py,sha256=pMLv8D7qoFqLZrlbTHLJJULOdDdhPskJ1m7KVKLV63E,9584
|
|
20
20
|
pytcl/clustering/__init__.py,sha256=bYdhC_XJEt6KUUni9bIPxaddXNEGmIJQvGkA14rK4J8,1697
|
|
21
21
|
pytcl/clustering/dbscan.py,sha256=PS6QlOwHFerbZNEb3zcNhN4oNQpgOOw5y0WskQzyKIo,7364
|
|
22
|
-
pytcl/clustering/gaussian_mixture.py,sha256=
|
|
23
|
-
pytcl/clustering/hierarchical.py,sha256
|
|
24
|
-
pytcl/clustering/kmeans.py,sha256=
|
|
22
|
+
pytcl/clustering/gaussian_mixture.py,sha256=U5U0Z46tZWdTLNdNNNJenoeviwZRAOvexVFYVLt4QMc,22865
|
|
23
|
+
pytcl/clustering/hierarchical.py,sha256=Hw9BFCn5df_ATpJX63R3B31MHz27ztCw9ihMDIlI688,14202
|
|
24
|
+
pytcl/clustering/kmeans.py,sha256=250FQyDol5S_Y4TznNn9cEuE96UDp7wvEkPZJ1DLul8,10697
|
|
25
25
|
pytcl/containers/__init__.py,sha256=-hnqSMKlMugj2RRssx3p_48HWnfqLSrF6BCChsinCOg,1627
|
|
26
|
-
pytcl/containers/cluster_set.py,sha256=
|
|
26
|
+
pytcl/containers/cluster_set.py,sha256=y36D5TNzvCN6xjg6taP2SD_MC-O5iLq9ncBlHsQ5IBs,22723
|
|
27
27
|
pytcl/containers/covertree.py,sha256=1JWqXxoUFLxuMnjwj2qf0iz2uPzdujQYdwJW3l5qsOs,13282
|
|
28
28
|
pytcl/containers/kd_tree.py,sha256=pxRC62RYkqz9zXPz6c1fubmtPPBDLYA5I9AXMAoGanw,16348
|
|
29
|
-
pytcl/containers/measurement_set.py,sha256=
|
|
30
|
-
pytcl/containers/rtree.py,sha256=
|
|
29
|
+
pytcl/containers/measurement_set.py,sha256=87AbdoZIUspn1yJsiMpyQ5LoEVcerUnXefXGGPtFTJg,12654
|
|
30
|
+
pytcl/containers/rtree.py,sha256=gv2EztvPnaAXEa6OoFnOYBY1MfTwjNMYh_BCiIomHJk,15450
|
|
31
31
|
pytcl/containers/track_list.py,sha256=6q9Qgcwm-8H_JqtOCsMssF27av4XaSkhfDl-MWb1ABc,12520
|
|
32
32
|
pytcl/containers/vptree.py,sha256=6fBNHrezkmj7L2nH0-2bONRN92f5cZAhS-5vaI1JZnA,8814
|
|
33
33
|
pytcl/coordinate_systems/__init__.py,sha256=jwYhu_-9AvOeP9WLG9PYtyDwfe0GjxNZ9-xCqiLymW4,3909
|
|
34
34
|
pytcl/coordinate_systems/conversions/__init__.py,sha256=PkNevB78vBw0BkalydJBbQO91AyiMJxKRrgJNt4HsYc,1100
|
|
35
|
-
pytcl/coordinate_systems/conversions/geodetic.py,sha256=
|
|
35
|
+
pytcl/coordinate_systems/conversions/geodetic.py,sha256=qQSnJRt3jg5KiostvzyslPIbfn-1xBluo1r12oavWTQ,15737
|
|
36
36
|
pytcl/coordinate_systems/conversions/spherical.py,sha256=q7k9l5mJbVzVdNj9Gcq4ibFxax8z_mVpJfITRBzx630,10812
|
|
37
37
|
pytcl/coordinate_systems/jacobians/__init__.py,sha256=CRGB8GzvGT_sr4Ynm51S7gSX8grqt1pO1Pq1MWmHPTs,890
|
|
38
38
|
pytcl/coordinate_systems/jacobians/jacobians.py,sha256=1KufIoktm9mXLO34X9KjysdMpu7itGwfssRyAdkTTN8,11703
|
|
39
39
|
pytcl/coordinate_systems/projections/__init__.py,sha256=eWNtezPO62IUWxv7jymenIXsWS1MC66Q12u5KRUnqNE,2503
|
|
40
|
-
pytcl/coordinate_systems/projections/projections.py,sha256=
|
|
40
|
+
pytcl/coordinate_systems/projections/projections.py,sha256=yODS7n1gA4jsCJcU8EaeclHrbUBsZI9O2M_XJs2HOXs,33169
|
|
41
41
|
pytcl/coordinate_systems/rotations/__init__.py,sha256=nqAz4iJd2hEOX_r7Tz4cE524sShyxdbtcQ5m56RrDLg,1047
|
|
42
|
-
pytcl/coordinate_systems/rotations/rotations.py,sha256=
|
|
42
|
+
pytcl/coordinate_systems/rotations/rotations.py,sha256=FAYHkShQcpOlWJjtvLfNvtCx-a56pr-cbpo0QjC5W9U,18227
|
|
43
43
|
pytcl/core/__init__.py,sha256=H5JJPS-43DfF1UG7fSgV-VMTcZFBO8GuzDW1lM_1sm4,1152
|
|
44
|
-
pytcl/core/array_utils.py,sha256=
|
|
45
|
-
pytcl/core/constants.py,sha256=
|
|
46
|
-
pytcl/core/validation.py,sha256=
|
|
44
|
+
pytcl/core/array_utils.py,sha256=SsgEiAoRCWxAVKq1aa5-nPdOi-2AB6XNObu0IaGClUk,13983
|
|
45
|
+
pytcl/core/constants.py,sha256=lZVDK5zsSR02_4b2Nqx9KDtZT9QaYhkZ9wuoODbifd4,8693
|
|
46
|
+
pytcl/core/validation.py,sha256=WRlzMlUihtqc3XZoWOTFK0sBAZVDIwTMGCiWcX5OZVY,13093
|
|
47
47
|
pytcl/dynamic_estimation/__init__.py,sha256=jA5FF6kHYklY5LMOfZaKcCeiPTpVe8vHIMp3ECDOmsc,4582
|
|
48
|
-
pytcl/dynamic_estimation/imm.py,sha256=
|
|
48
|
+
pytcl/dynamic_estimation/imm.py,sha256=IbKmouUiyzaYJbhWty63r3n_xV8thD-wd0qgZP1SxOI,22067
|
|
49
49
|
pytcl/dynamic_estimation/information_filter.py,sha256=x7iQwO_iJT1dCSvDws5LqD3yAtjw9QVGUfMPcXn1IA4,17349
|
|
50
|
-
pytcl/dynamic_estimation/smoothers.py,sha256=
|
|
50
|
+
pytcl/dynamic_estimation/smoothers.py,sha256=x2j-nR--EI5JNZvMywPeDHcrfW8b5PYK0DCU4Rmig_g,18914
|
|
51
51
|
pytcl/dynamic_estimation/batch_estimation/__init__.py,sha256=JQ0s76Enov5a7plA4EnUua4t-7etikQrwr5z4WIjUeo,46
|
|
52
52
|
pytcl/dynamic_estimation/kalman/__init__.py,sha256=yoFLj0n-NRkdZnRVL-BkHBlATk8pfZEVlsY3BhSYgKc,2387
|
|
53
53
|
pytcl/dynamic_estimation/kalman/extended.py,sha256=51uhCqkZmErCx6MBfMq8eIQW8bD7n34zCe4v4dxNiMQ,10384
|
|
54
54
|
pytcl/dynamic_estimation/kalman/linear.py,sha256=1Zgg9gZya0Vxs9im7sPUqLj0Luo463vS-RSa6GCReFI,12248
|
|
55
|
-
pytcl/dynamic_estimation/kalman/square_root.py,sha256=
|
|
55
|
+
pytcl/dynamic_estimation/kalman/square_root.py,sha256=Hw1F4_Zc7IA6Mt1WCkjx1UuLAUmNhM5vPLvueb7oRSA,26931
|
|
56
56
|
pytcl/dynamic_estimation/kalman/unscented.py,sha256=RDK6USkko9lj1K4-WYydh3_8GMZNng_PJVjfc-c_OwM,15427
|
|
57
57
|
pytcl/dynamic_estimation/measurement_update/__init__.py,sha256=8rlyJwVpxf0fZj-AFo1hlewvryZRhUzcy3F8uMe6I8c,48
|
|
58
58
|
pytcl/dynamic_estimation/particle_filters/__init__.py,sha256=-DRF5rVF2749suLlArmkTvVkqeMcV_mIx0eLeTj6wNU,906
|
|
59
|
-
pytcl/dynamic_estimation/particle_filters/bootstrap.py,sha256=
|
|
59
|
+
pytcl/dynamic_estimation/particle_filters/bootstrap.py,sha256=FcF4W_NM5ZqJnw5fq4rq6fLY9X1r4uFJOiAX9a-NGG8,13371
|
|
60
60
|
pytcl/dynamic_models/__init__.py,sha256=Cd8MyyYuB8gMnepkPA-HSwTaKFPThnqoKOhdjVOsXWg,2783
|
|
61
61
|
pytcl/dynamic_models/continuous_time/__init__.py,sha256=dAkfEddLkfMvDalK9v2GRBvaZV1KgqYpFBLOnoiFClw,1023
|
|
62
62
|
pytcl/dynamic_models/continuous_time/dynamics.py,sha256=CDwqn-66eUwXA5xfIjaG6A4EDBqtOyQ3aWarJr9QH4g,12858
|
|
@@ -66,85 +66,85 @@ pytcl/dynamic_models/discrete_time/polynomial.py,sha256=zv5V-AbuaXlIj36n-YkOEyC7
|
|
|
66
66
|
pytcl/dynamic_models/discrete_time/singer.py,sha256=wZS3Nad-YyPZp8Mle8Sf5GgW0-t4TxMRcnbc42HtQnA,3861
|
|
67
67
|
pytcl/dynamic_models/process_noise/__init__.py,sha256=ZRYgV40qmBkPwU3yTbIMvxorr4nVz0_FEP2oCeVjXoM,933
|
|
68
68
|
pytcl/dynamic_models/process_noise/coordinated_turn.py,sha256=w7bHUImLPL5m3KYenfNgAnHPCRtAyYESbsFc6lQKXRg,4768
|
|
69
|
-
pytcl/dynamic_models/process_noise/polynomial.py,sha256=
|
|
69
|
+
pytcl/dynamic_models/process_noise/polynomial.py,sha256=natfpsdN3qM9VzPeXF_nBpsbRI74S1WkkRCaaem6EQo,7620
|
|
70
70
|
pytcl/dynamic_models/process_noise/singer.py,sha256=lsJDT6xOvcS_qQKFtgHX0L7Ukpy4D7HgvPT8Q3I0ibU,3901
|
|
71
71
|
pytcl/gravity/__init__.py,sha256=5xNdQSrrkt7-1-JPOYqR38CqvNJ7qKlPyMK36DGm6-I,3693
|
|
72
|
-
pytcl/gravity/clenshaw.py,sha256=
|
|
73
|
-
pytcl/gravity/egm.py,sha256=
|
|
74
|
-
pytcl/gravity/models.py,sha256=
|
|
75
|
-
pytcl/gravity/spherical_harmonics.py,sha256=
|
|
76
|
-
pytcl/gravity/tides.py,sha256=
|
|
72
|
+
pytcl/gravity/clenshaw.py,sha256=1BdxzU8IfGGd68H_U35soIJkiOHphY35e9mLElhPTOg,15364
|
|
73
|
+
pytcl/gravity/egm.py,sha256=QTRuvCiMjuNQdZF163OGwjxuivpGu2dB6E0zQLbKPP8,18083
|
|
74
|
+
pytcl/gravity/models.py,sha256=rdY3Do4M1eRFO74gu3xy-bBn7tox3zM49wYbfnsIQWw,11159
|
|
75
|
+
pytcl/gravity/spherical_harmonics.py,sha256=uZasz-w2K16sWT6xrNIPyTEP6MSlMQSe_BCWpXhRkWY,14722
|
|
76
|
+
pytcl/gravity/tides.py,sha256=hef_BGewFGD7dJwg0t09Z6tfWLco_avATLuu66rnTpI,27733
|
|
77
77
|
pytcl/magnetism/__init__.py,sha256=hE2BvberFSmimYuuwCYJ0g7ByxJAdj844vZJNkEotws,2502
|
|
78
|
-
pytcl/magnetism/emm.py,sha256=
|
|
78
|
+
pytcl/magnetism/emm.py,sha256=5Jwl99wvdKYtx1-3LBB7x-w5KT-fqLiRg7uBW0Ai_Gw,22292
|
|
79
79
|
pytcl/magnetism/igrf.py,sha256=3g0PsH8IdbwQQS28OR5XWD-g-QxvfUva7jOkKToxndQ,13384
|
|
80
|
-
pytcl/magnetism/wmm.py,sha256=
|
|
80
|
+
pytcl/magnetism/wmm.py,sha256=p0H7Eo02iB6nEMvGyvjsrAWOSKrIye6PGwQtNKfHaNw,15999
|
|
81
81
|
pytcl/mathematical_functions/__init__.py,sha256=zeJ1ffRRl83k2NHn3HTn-fgtFoWNPq6LCALc3xRo4Do,3767
|
|
82
82
|
pytcl/mathematical_functions/basic_matrix/__init__.py,sha256=kZv3kMAEHBdVxhbyMxTyM0s-4XJP1tK6po82UsIE4tc,1318
|
|
83
|
-
pytcl/mathematical_functions/basic_matrix/decompositions.py,sha256=
|
|
83
|
+
pytcl/mathematical_functions/basic_matrix/decompositions.py,sha256=PWJsFDiXM2T78RHdxBJZPFnl8kFbNZQpHrbpw0mhE00,12268
|
|
84
84
|
pytcl/mathematical_functions/basic_matrix/special_matrices.py,sha256=kOozwP2CHAj4qyO7Z9ct6GwDMkmHkk1bQa0e9G98FgA,13499
|
|
85
85
|
pytcl/mathematical_functions/combinatorics/__init__.py,sha256=byuHI0WkxOkQF8egrfjEr-awB2visWDXlGMnDux5IBg,1043
|
|
86
|
-
pytcl/mathematical_functions/combinatorics/combinatorics.py,sha256=
|
|
86
|
+
pytcl/mathematical_functions/combinatorics/combinatorics.py,sha256=3EgkWdBqQ9e6JU34bec9EeCEmB-46tUSXXTAJrckSO4,12314
|
|
87
87
|
pytcl/mathematical_functions/continuous_optimization/__init__.py,sha256=lck60eeCUOsRpEzPHBY3kiLKwNz_fhmYoUGP3lTmTwk,55
|
|
88
88
|
pytcl/mathematical_functions/geometry/__init__.py,sha256=DhCmux9-6zxYRzlhQ9du18kvUL-leiiZwdd3Cmb5WX0,1092
|
|
89
|
-
pytcl/mathematical_functions/geometry/geometry.py,sha256=
|
|
89
|
+
pytcl/mathematical_functions/geometry/geometry.py,sha256=l63wQnhCtJwVHZOJeONX1qyJ5Sedji8etgxwJCFtH8Y,16403
|
|
90
90
|
pytcl/mathematical_functions/interpolation/__init__.py,sha256=lK4Rs0Ds_fzf9q0n6id5epdN0U8V7yD87dS-w1hvN8I,741
|
|
91
|
-
pytcl/mathematical_functions/interpolation/interpolation.py,sha256=
|
|
91
|
+
pytcl/mathematical_functions/interpolation/interpolation.py,sha256=2cXMDgWBjWDGHnK1K_lawFlJL8oPl5AQGf9MNgsESfo,12610
|
|
92
92
|
pytcl/mathematical_functions/numerical_integration/__init__.py,sha256=iXiHzyV_KIhCv7tXErXlN1_fUEACN6yN3CYDHRA7esw,974
|
|
93
93
|
pytcl/mathematical_functions/numerical_integration/quadrature.py,sha256=ZRMKs0vbcgFDe1Sr8sjyEOkALLmJU4zKRJjoPEcXrUc,15670
|
|
94
94
|
pytcl/mathematical_functions/polynomials/__init__.py,sha256=WJWZcoQhnvy5f59-kncMTgD9mCtgwfDgULvDYYHS5ys,43
|
|
95
95
|
pytcl/mathematical_functions/signal_processing/__init__.py,sha256=_SzzBVtxmSvP8FKeogRdNmFo8FOVDDoexVOqd-lE7do,2325
|
|
96
|
-
pytcl/mathematical_functions/signal_processing/detection.py,sha256=
|
|
97
|
-
pytcl/mathematical_functions/signal_processing/filters.py,sha256=
|
|
98
|
-
pytcl/mathematical_functions/signal_processing/matched_filter.py,sha256=
|
|
96
|
+
pytcl/mathematical_functions/signal_processing/detection.py,sha256=9F0xdy3hMat1czSWAQYMExn0kY5DBRpyBneAfjjHUVI,30377
|
|
97
|
+
pytcl/mathematical_functions/signal_processing/filters.py,sha256=8Ojf4h4rfiucBXqUmB1odvHH41Gf3rPwmWCMKb-qzWk,23435
|
|
98
|
+
pytcl/mathematical_functions/signal_processing/matched_filter.py,sha256=AahJZRZk2IIXzRL7www0n8bc0XoKabaLOe8yYNSjuDY,22893
|
|
99
99
|
pytcl/mathematical_functions/special_functions/__init__.py,sha256=AJBCKj32daQxdahUQckW0bWowzOoapxni2eZnVXERdg,3859
|
|
100
100
|
pytcl/mathematical_functions/special_functions/bessel.py,sha256=M0mwLQBaUXEHA8wyKReJ2D66I1v1XR7y-txAipd-WDs,14377
|
|
101
101
|
pytcl/mathematical_functions/special_functions/debye.py,sha256=Nchjwkl1vzSL1L7nQpslb-lvT49LgTfdTIQMeSNn4vQ,6689
|
|
102
|
-
pytcl/mathematical_functions/special_functions/elliptic.py,sha256=
|
|
102
|
+
pytcl/mathematical_functions/special_functions/elliptic.py,sha256=WyzBkrfZufIR5dUmCKGcxp6KNpVDrU89NGLDyRrZOqQ,7418
|
|
103
103
|
pytcl/mathematical_functions/special_functions/error_functions.py,sha256=a3SS8FYAMRv1KdCmebOZL95yjvVt9gZRF2XOjHvQ9M8,6253
|
|
104
|
-
pytcl/mathematical_functions/special_functions/gamma_functions.py,sha256=
|
|
104
|
+
pytcl/mathematical_functions/special_functions/gamma_functions.py,sha256=xXN_9SCokH10HjE8PpaPKHYVK_RZRHRAbZgR2mZYIAA,10191
|
|
105
105
|
pytcl/mathematical_functions/special_functions/hypergeometric.py,sha256=gKn_tXboEst7pVDiW15IbKFAANM4XVqKtDc1dmWL-2A,9768
|
|
106
|
-
pytcl/mathematical_functions/special_functions/lambert_w.py,sha256=
|
|
106
|
+
pytcl/mathematical_functions/special_functions/lambert_w.py,sha256=ivRc4KH5Lwoxb_yijrJEwG0ITa0hhcYF7_gCfVBBNW4,6855
|
|
107
107
|
pytcl/mathematical_functions/special_functions/marcum_q.py,sha256=OZ5QjIB1e_XvRG8A-3dbZ13YXHtdk2EYVEPaqtgVr14,9580
|
|
108
108
|
pytcl/mathematical_functions/statistics/__init__.py,sha256=dfypStgmnFmOrnWcm-3CEvLinONHraFgx9O66_37bqw,1278
|
|
109
|
-
pytcl/mathematical_functions/statistics/distributions.py,sha256=
|
|
110
|
-
pytcl/mathematical_functions/statistics/estimators.py,sha256=
|
|
109
|
+
pytcl/mathematical_functions/statistics/distributions.py,sha256=icfFIIKCEFzkpFHuYGWL197nm8wvS7UPJlr9kd_uEgw,19373
|
|
110
|
+
pytcl/mathematical_functions/statistics/estimators.py,sha256=TLnYXSwk5MzBakZrzDBupbOB3ONmJI7q1-oB2xuSVQM,10831
|
|
111
111
|
pytcl/mathematical_functions/transforms/__init__.py,sha256=SPXSKHjqR6B_8pvgtbtOnEiCpU-u0JF2s7hAlhb0BbI,2343
|
|
112
112
|
pytcl/mathematical_functions/transforms/fourier.py,sha256=QH6OaTzw4kN6M-DuSmwB_5b-wu_4yP5I2CUmNEyLORM,20737
|
|
113
|
-
pytcl/mathematical_functions/transforms/stft.py,sha256=
|
|
114
|
-
pytcl/mathematical_functions/transforms/wavelets.py,sha256=
|
|
113
|
+
pytcl/mathematical_functions/transforms/stft.py,sha256=zQapXl-v69_RDPwMqci83jah17GyAfnr3gx0budv2Cg,18619
|
|
114
|
+
pytcl/mathematical_functions/transforms/wavelets.py,sha256=dm273Z_t13BlEVSlHTaGE7jR1ocugL7lEkcO499U7bY,21656
|
|
115
115
|
pytcl/misc/__init__.py,sha256=SCHf_lQVfdl2gwUluHBiIloTF8HRH8EkgYfbNr7zOug,33
|
|
116
116
|
pytcl/navigation/__init__.py,sha256=k1_x_FnnPrIzGeNu7zejPtPubIhweBgCfwqlZJEMw0I,6042
|
|
117
|
-
pytcl/navigation/geodesy.py,sha256=
|
|
118
|
-
pytcl/navigation/great_circle.py,sha256=
|
|
119
|
-
pytcl/navigation/ins.py,sha256=
|
|
120
|
-
pytcl/navigation/ins_gnss.py,sha256=
|
|
121
|
-
pytcl/navigation/rhumb.py,sha256=
|
|
117
|
+
pytcl/navigation/geodesy.py,sha256=M9XXfBTMCRdaWMV2-ViDSTEt94WZnMtxMeJQ1FAgQHY,17227
|
|
118
|
+
pytcl/navigation/great_circle.py,sha256=TtlkWZbzr-HzSt4ultG_h137ZnX0pJZx_87kr3uvpjI,20923
|
|
119
|
+
pytcl/navigation/ins.py,sha256=OIi8_RjrgEYl0MFpJEFMjIlpgX8DYGTEhdLEvqG-ABU,31151
|
|
120
|
+
pytcl/navigation/ins_gnss.py,sha256=euKF5JGgwmVBsw3jBf7_wa2z1BpZeVbSNmBuwzhGS6c,30157
|
|
121
|
+
pytcl/navigation/rhumb.py,sha256=lr1c3iEXfoOSfIyyXSRWv6He5TlaxEHbJy-dhqM1gRw,18224
|
|
122
122
|
pytcl/performance_evaluation/__init__.py,sha256=tM2pnBfDb2XbnLt4Y5MQ6w6XBwFy_5bf_y0toZmxx88,1859
|
|
123
123
|
pytcl/performance_evaluation/estimation_metrics.py,sha256=X1ZCpp8m6DV14N2wbMvlRwfORRKga8DgKmG3dROyJqA,12351
|
|
124
|
-
pytcl/performance_evaluation/track_metrics.py,sha256=
|
|
124
|
+
pytcl/performance_evaluation/track_metrics.py,sha256=Nd3royJkAelZV-Qggl8i72e7WocCxWomgliArvVAEkc,13342
|
|
125
125
|
pytcl/physical_values/__init__.py,sha256=SGbg6b0d4dWebE3baW4OlJshL00grG5E4wABw6jxl20,44
|
|
126
126
|
pytcl/plotting/__init__.py,sha256=YtYnKYHL5lN6EaT_bwwR3h89NW0HSMToIWHhHBxcidY,3126
|
|
127
|
-
pytcl/plotting/coordinates.py,sha256=
|
|
127
|
+
pytcl/plotting/coordinates.py,sha256=h39H855Qjqtcly62m09demaOFpfMs_8EF_nXhoLBSBs,17198
|
|
128
128
|
pytcl/plotting/ellipses.py,sha256=bcns6dfNK4bwA_QBshscYhbAz_5wegwyqjDzzoUdWsQ,12465
|
|
129
|
-
pytcl/plotting/metrics.py,sha256=
|
|
130
|
-
pytcl/plotting/tracks.py,sha256=
|
|
129
|
+
pytcl/plotting/metrics.py,sha256=zbJr5P2kQg7-rGpGHsN7rC02S0JLOpPUZeoscQem7uQ,18148
|
|
130
|
+
pytcl/plotting/tracks.py,sha256=cqZG71ZHM-wDSzjH4I4kCESORIiZjmGesQtADmAi4gc,23034
|
|
131
131
|
pytcl/scheduling/__init__.py,sha256=jTqMSKcsCrWU_Fh6WaT6BW5WatNHyyEYjFbsv6X18Oc,39
|
|
132
132
|
pytcl/static_estimation/__init__.py,sha256=sSEhqq35jq_MpRLnBtWjKXwGZ9dqIw71iwji-TNwXmc,2222
|
|
133
|
-
pytcl/static_estimation/least_squares.py,sha256=
|
|
134
|
-
pytcl/static_estimation/maximum_likelihood.py,sha256=
|
|
133
|
+
pytcl/static_estimation/least_squares.py,sha256=8ouOyRGC7K-W8fynZMWlc2-KAFojvTbuzcqi5uS_sVA,13432
|
|
134
|
+
pytcl/static_estimation/maximum_likelihood.py,sha256=P6BKMcuzzDu_Qc6mX9KLI-zPWFX_NabbA6AKYjkNBcY,21581
|
|
135
135
|
pytcl/static_estimation/robust.py,sha256=egBLKWmo6d9PzP6LDh0J7ee4j6hYZh8kAb9TR5uC2so,18527
|
|
136
136
|
pytcl/terrain/__init__.py,sha256=e7plNQI5Y_jpZ24r82AgqdX0ChmmyYoeT7HReclnGXc,3228
|
|
137
|
-
pytcl/terrain/dem.py,sha256=
|
|
138
|
-
pytcl/terrain/loaders.py,sha256=
|
|
139
|
-
pytcl/terrain/visibility.py,sha256=
|
|
137
|
+
pytcl/terrain/dem.py,sha256=rg2o0h0ZDrfxvtYhnE2A5tdzRnCmqcihu4w1uNJdH3Y,20814
|
|
138
|
+
pytcl/terrain/loaders.py,sha256=KBs1vdYUYW-0ETIujRv4-WxO-bExZk-FvPLY5l6gyTc,27028
|
|
139
|
+
pytcl/terrain/visibility.py,sha256=nIJr9AVk7C8GCpJV4UDvUjhmAieycWD8BLepAMUBMIQ,22739
|
|
140
140
|
pytcl/trackers/__init__.py,sha256=Gw79xlSIUzdPV8bN1slNWUlGxE3d-NsVmbMygkYVV20,1151
|
|
141
|
-
pytcl/trackers/hypothesis.py,sha256=
|
|
142
|
-
pytcl/trackers/mht.py,sha256=
|
|
141
|
+
pytcl/trackers/hypothesis.py,sha256=RApWfji-f0-a68KnAJela0BvPdIlOY_FV_cYJFmVUoE,17353
|
|
142
|
+
pytcl/trackers/mht.py,sha256=7mwhMmja3ri2wnx7W1wueDGn2r3ArwAxJDPUJ7IZAkQ,20617
|
|
143
143
|
pytcl/trackers/multi_target.py,sha256=hvt89ERhMwpcHcIJeKHnkQSKdE3_LoRiX-gbaGoo300,10516
|
|
144
144
|
pytcl/trackers/single_target.py,sha256=Yy3FwaNTArMWcaod-0HVeiioNV4xLWxNDn_7ZPVqQYs,6562
|
|
145
145
|
pytcl/transponders/__init__.py,sha256=5fL4u3lKCYgPLo5uFeuZbtRZkJPABntuKYGUvVgMMEI,41
|
|
146
|
-
nrl_tracker-0.22.
|
|
147
|
-
nrl_tracker-0.22.
|
|
148
|
-
nrl_tracker-0.22.
|
|
149
|
-
nrl_tracker-0.22.
|
|
150
|
-
nrl_tracker-0.22.
|
|
146
|
+
nrl_tracker-0.22.4.dist-info/LICENSE,sha256=rB5G4WppIIUzMOYr2N6uyYlNJ00hRJqE5tie6BMvYuE,1612
|
|
147
|
+
nrl_tracker-0.22.4.dist-info/METADATA,sha256=zfUsmYNc37YRmgFjm4DZak-rSDMSPsQM3KhO0Syr8sQ,10005
|
|
148
|
+
nrl_tracker-0.22.4.dist-info/WHEEL,sha256=pL8R0wFFS65tNSRnaOVrsw9EOkOqxLrlUPenUYnJKNo,91
|
|
149
|
+
nrl_tracker-0.22.4.dist-info/top_level.txt,sha256=17megxcrTPBWwPZTh6jTkwTKxX7No-ZqRpyvElnnO-s,6
|
|
150
|
+
nrl_tracker-0.22.4.dist-info/RECORD,,
|
pytcl/__init__.py
CHANGED
|
@@ -19,9 +19,9 @@ def _mahalanobis_distance_2d(
|
|
|
19
19
|
S_inv: np.ndarray,
|
|
20
20
|
) -> float:
|
|
21
21
|
"""JIT-compiled Mahalanobis distance for 2D innovations."""
|
|
22
|
-
return innovation[0] * (
|
|
23
|
-
1
|
|
24
|
-
] * (S_inv[1, 0] * innovation[0] + S_inv[1, 1] * innovation[1])
|
|
22
|
+
return innovation[0] * (
|
|
23
|
+
S_inv[0, 0] * innovation[0] + S_inv[0, 1] * innovation[1]
|
|
24
|
+
) + innovation[1] * (S_inv[1, 0] * innovation[0] + S_inv[1, 1] * innovation[1])
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
@njit(cache=True, fastmath=True)
|
|
@@ -94,7 +94,9 @@ def compute_measurement_likelihood(
|
|
|
94
94
|
return 0.0
|
|
95
95
|
|
|
96
96
|
mahal_sq = innovation @ np.linalg.solve(innovation_cov, innovation)
|
|
97
|
-
likelihood =
|
|
97
|
+
likelihood = (
|
|
98
|
+
detection_prob * np.exp(-0.5 * mahal_sq) / np.sqrt((2 * np.pi) ** m * det_S)
|
|
99
|
+
)
|
|
98
100
|
|
|
99
101
|
return likelihood
|
|
100
102
|
|
|
@@ -208,7 +210,9 @@ def jpda_probabilities(
|
|
|
208
210
|
if n_tracks <= 5 and n_meas <= 5:
|
|
209
211
|
beta = _jpda_exact(likelihood_matrix, gated, detection_prob, clutter_density)
|
|
210
212
|
else:
|
|
211
|
-
beta = _jpda_approximate(
|
|
213
|
+
beta = _jpda_approximate(
|
|
214
|
+
likelihood_matrix, gated, detection_prob, clutter_density
|
|
215
|
+
)
|
|
212
216
|
|
|
213
217
|
return beta
|
|
214
218
|
|
|
@@ -254,7 +258,9 @@ def _jpda_exact(
|
|
|
254
258
|
if gated[track_idx, meas_idx] and track_idx not in used_tracks:
|
|
255
259
|
current_assignment.append(track_idx)
|
|
256
260
|
used_tracks.add(track_idx)
|
|
257
|
-
yield from generate_hypotheses(
|
|
261
|
+
yield from generate_hypotheses(
|
|
262
|
+
meas_idx + 1, current_assignment, used_tracks
|
|
263
|
+
)
|
|
258
264
|
used_tracks.remove(track_idx)
|
|
259
265
|
current_assignment.pop()
|
|
260
266
|
|
|
@@ -292,7 +298,9 @@ def _jpda_exact(
|
|
|
292
298
|
hypothesis_probs = [p / total_prob for p in hypothesis_probs]
|
|
293
299
|
|
|
294
300
|
# Compute marginal association probabilities
|
|
295
|
-
for h_idx, (assignment, prob) in enumerate(
|
|
301
|
+
for h_idx, (assignment, prob) in enumerate(
|
|
302
|
+
zip(hypothesis_assignments, hypothesis_probs)
|
|
303
|
+
):
|
|
296
304
|
detected_tracks = set()
|
|
297
305
|
for j, track_idx in enumerate(assignment):
|
|
298
306
|
if track_idx >= 0:
|
|
@@ -335,7 +335,9 @@ def _partition_solution(
|
|
|
335
335
|
|
|
336
336
|
for i in range(start_idx, n_assigned):
|
|
337
337
|
# Require assignments 0..i-1, forbid assignment i
|
|
338
|
-
new_required = required + [
|
|
338
|
+
new_required = required + [
|
|
339
|
+
(row_ind[j], col_ind[j]) for j in range(start_idx, i)
|
|
340
|
+
]
|
|
339
341
|
new_forbidden = forbidden + [(row_ind[i], col_ind[i])]
|
|
340
342
|
|
|
341
343
|
# Solve constrained problem
|
|
@@ -137,14 +137,16 @@ class DEEphemeris:
|
|
|
137
137
|
"""
|
|
138
138
|
if version not in self._VALID_VERSIONS:
|
|
139
139
|
raise ValueError(
|
|
140
|
-
f"Ephemeris version must be one of {self._VALID_VERSIONS}, "
|
|
140
|
+
f"Ephemeris version must be one of {self._VALID_VERSIONS}, "
|
|
141
|
+
f"got '{version}'"
|
|
141
142
|
)
|
|
142
143
|
|
|
143
144
|
try:
|
|
144
145
|
import jplephem
|
|
145
146
|
except ImportError as e:
|
|
146
147
|
raise ImportError(
|
|
147
|
-
"jplephem is required for ephemeris access. "
|
|
148
|
+
"jplephem is required for ephemeris access. "
|
|
149
|
+
"Install with: pip install jplephem"
|
|
148
150
|
) from e
|
|
149
151
|
|
|
150
152
|
self.version = version
|
|
@@ -170,9 +172,7 @@ class DEEphemeris:
|
|
|
170
172
|
|
|
171
173
|
# Try to construct kernel filename
|
|
172
174
|
kernel_name = f"de{self.version[2:]}.bsp"
|
|
173
|
-
kernel_url =
|
|
174
|
-
f"https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/{kernel_name}"
|
|
175
|
-
)
|
|
175
|
+
kernel_url = f"https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/{kernel_name}"
|
|
176
176
|
|
|
177
177
|
# Try to download if not exists
|
|
178
178
|
kernel_path = os.path.expanduser(f"~/.jplephem/{kernel_name}")
|
|
@@ -296,7 +296,9 @@ class DEEphemeris:
|
|
|
296
296
|
|
|
297
297
|
# Get Moon position relative to Earth
|
|
298
298
|
moon_segment = self.kernel[3, 301]
|
|
299
|
-
moon_rel_earth_pos, moon_rel_earth_vel =
|
|
299
|
+
moon_rel_earth_pos, moon_rel_earth_vel = (
|
|
300
|
+
moon_segment.compute_and_differentiate(jd)
|
|
301
|
+
)
|
|
300
302
|
|
|
301
303
|
# Moon position relative to SSB
|
|
302
304
|
position = earth_pos + moon_rel_earth_pos
|
|
@@ -316,7 +318,9 @@ class DEEphemeris:
|
|
|
316
318
|
|
|
317
319
|
def planet_position(
|
|
318
320
|
self,
|
|
319
|
-
planet: Literal[
|
|
321
|
+
planet: Literal[
|
|
322
|
+
"mercury", "venus", "mars", "jupiter", "saturn", "uranus", "neptune"
|
|
323
|
+
],
|
|
320
324
|
jd: float,
|
|
321
325
|
frame: Literal["icrf", "ecliptic"] = "icrf",
|
|
322
326
|
) -> Tuple[np.ndarray, np.ndarray]:
|
|
@@ -373,7 +377,9 @@ class DEEphemeris:
|
|
|
373
377
|
|
|
374
378
|
return position, velocity
|
|
375
379
|
|
|
376
|
-
def barycenter_position(
|
|
380
|
+
def barycenter_position(
|
|
381
|
+
self, body: str, jd: float
|
|
382
|
+
) -> Tuple[np.ndarray, np.ndarray]:
|
|
377
383
|
"""Compute position of any body relative to Solar System Barycenter.
|
|
378
384
|
|
|
379
385
|
Parameters
|
|
@@ -471,7 +477,9 @@ def moon_position(
|
|
|
471
477
|
|
|
472
478
|
|
|
473
479
|
def planet_position(
|
|
474
|
-
planet: Literal[
|
|
480
|
+
planet: Literal[
|
|
481
|
+
"mercury", "venus", "mars", "jupiter", "saturn", "uranus", "neptune"
|
|
482
|
+
],
|
|
475
483
|
jd: float,
|
|
476
484
|
frame: Literal["icrf", "ecliptic"] = "icrf",
|
|
477
485
|
) -> Tuple[np.ndarray, np.ndarray]:
|
pytcl/astronomical/lambert.py
CHANGED
|
@@ -198,7 +198,9 @@ def lambert_universal(
|
|
|
198
198
|
psi = (psi_low + psi_high) / 2
|
|
199
199
|
|
|
200
200
|
else:
|
|
201
|
-
raise ValueError(
|
|
201
|
+
raise ValueError(
|
|
202
|
+
f"Lambert's problem did not converge after {max_iter} iterations"
|
|
203
|
+
)
|
|
202
204
|
|
|
203
205
|
# Compute f, g, f_dot, g_dot
|
|
204
206
|
f = 1 - y / r1_mag
|
|
@@ -286,7 +288,11 @@ def lambert_izzo(
|
|
|
286
288
|
|
|
287
289
|
# Cross product for angular momentum direction
|
|
288
290
|
cross = np.cross(r1, r2)
|
|
289
|
-
h_hat =
|
|
291
|
+
h_hat = (
|
|
292
|
+
cross / np.linalg.norm(cross)
|
|
293
|
+
if np.linalg.norm(cross) > 1e-10
|
|
294
|
+
else np.array([0, 0, 1])
|
|
295
|
+
)
|
|
290
296
|
|
|
291
297
|
# Transfer angle
|
|
292
298
|
cos_dnu = np.dot(r1_hat, r2_hat)
|
|
@@ -329,9 +335,13 @@ def lambert_izzo(
|
|
|
329
335
|
|
|
330
336
|
# Time of flight equation
|
|
331
337
|
if x < 1:
|
|
332
|
-
psi = np.arccos(
|
|
338
|
+
psi = np.arccos(
|
|
339
|
+
x * lambda_param + y * np.sqrt(1 - lambda_param * lambda_param)
|
|
340
|
+
)
|
|
333
341
|
else:
|
|
334
|
-
psi = np.arccosh(
|
|
342
|
+
psi = np.arccosh(
|
|
343
|
+
x * lambda_param + y * np.sqrt(lambda_param * lambda_param - 1)
|
|
344
|
+
)
|
|
335
345
|
|
|
336
346
|
T_x = (
|
|
337
347
|
psi + multi_rev * np.pi - (x - lambda_param * y) * np.sqrt(abs(1 - x * x))
|
|
@@ -176,7 +176,9 @@ def mean_to_hyperbolic_anomaly(
|
|
|
176
176
|
if abs(delta) < tol:
|
|
177
177
|
return H
|
|
178
178
|
|
|
179
|
-
raise ValueError(
|
|
179
|
+
raise ValueError(
|
|
180
|
+
f"Hyperbolic Kepler's equation did not converge after {max_iter} iterations"
|
|
181
|
+
)
|
|
180
182
|
|
|
181
183
|
|
|
182
184
|
def eccentric_to_true_anomaly(E: float, e: float) -> float:
|
|
@@ -292,7 +292,9 @@ def gmst_iau82(jd_ut1: float) -> float:
|
|
|
292
292
|
T_u = (jd_0h - JD_J2000) / 36525.0
|
|
293
293
|
|
|
294
294
|
# GMST at 0h UT1 (seconds)
|
|
295
|
-
gmst_0h_sec =
|
|
295
|
+
gmst_0h_sec = (
|
|
296
|
+
24110.54841 + 8640184.812866 * T_u + 0.093104 * T_u**2 - 6.2e-6 * T_u**3
|
|
297
|
+
)
|
|
296
298
|
|
|
297
299
|
# Add UT1 fraction
|
|
298
300
|
ut1_fraction = (jd_ut1 - jd_0h) * 86400.0
|
pytcl/astronomical/relativity.py
CHANGED
|
@@ -323,7 +323,9 @@ def post_newtonian_acceleration(
|
|
|
323
323
|
return a_newt + a_1pn
|
|
324
324
|
|
|
325
325
|
|
|
326
|
-
def geodetic_precession(
|
|
326
|
+
def geodetic_precession(
|
|
327
|
+
a: float, e: float, inclination: float, gm: float = GM_EARTH
|
|
328
|
+
) -> float:
|
|
327
329
|
"""Compute geodetic (de Sitter) precession rate of orbital plane.
|
|
328
330
|
|
|
329
331
|
The orbital plane of a satellite precesses due to frame-dragging effects
|
|
@@ -363,7 +365,11 @@ def geodetic_precession(a: float, e: float, inclination: float, gm: float = GM_E
|
|
|
363
365
|
|
|
364
366
|
|
|
365
367
|
def lense_thirring_precession(
|
|
366
|
-
a: float,
|
|
368
|
+
a: float,
|
|
369
|
+
e: float,
|
|
370
|
+
inclination: float,
|
|
371
|
+
angular_momentum: float,
|
|
372
|
+
gm: float = GM_EARTH,
|
|
367
373
|
) -> float:
|
|
368
374
|
"""Compute Lense-Thirring (frame-dragging) precession of orbital node.
|
|
369
375
|
|
pytcl/atmosphere/models.py
CHANGED
|
@@ -218,7 +218,9 @@ def isa_atmosphere(
|
|
|
218
218
|
strat_mask = altitude > h_trop
|
|
219
219
|
temperature[strat_mask] = T_trop + temperature_offset
|
|
220
220
|
# Pressure at tropopause
|
|
221
|
-
P_trop = P0 * ((T0 + temperature_offset) / (T_trop + temperature_offset)) ** (
|
|
221
|
+
P_trop = P0 * ((T0 + temperature_offset) / (T_trop + temperature_offset)) ** (
|
|
222
|
+
G0 / (R * L)
|
|
223
|
+
)
|
|
222
224
|
pressure[strat_mask] = P_trop * np.exp(
|
|
223
225
|
-G0 * (altitude[strat_mask] - h_trop) / (R * (T_trop + temperature_offset))
|
|
224
226
|
)
|
|
@@ -297,7 +297,8 @@ def prune_mixture(
|
|
|
297
297
|
total_weight = sum(c.weight for c in surviving)
|
|
298
298
|
if total_weight > 0:
|
|
299
299
|
surviving = [
|
|
300
|
-
GaussianComponent(c.weight / total_weight, c.mean, c.covariance)
|
|
300
|
+
GaussianComponent(c.weight / total_weight, c.mean, c.covariance)
|
|
301
|
+
for c in surviving
|
|
301
302
|
]
|
|
302
303
|
|
|
303
304
|
return surviving
|
|
@@ -391,7 +392,8 @@ def reduce_mixture_runnalls(
|
|
|
391
392
|
total_weight = sum(c.weight for c in working)
|
|
392
393
|
if total_weight > 0:
|
|
393
394
|
working = [
|
|
394
|
-
GaussianComponent(c.weight / total_weight, c.mean, c.covariance)
|
|
395
|
+
GaussianComponent(c.weight / total_weight, c.mean, c.covariance)
|
|
396
|
+
for c in working
|
|
395
397
|
]
|
|
396
398
|
|
|
397
399
|
return ReductionResult(working, n_original, len(working), total_cost)
|
|
@@ -531,7 +533,8 @@ def reduce_mixture_west(
|
|
|
531
533
|
total_weight = sum(c.weight for c in working)
|
|
532
534
|
if total_weight > 0:
|
|
533
535
|
working = [
|
|
534
|
-
GaussianComponent(c.weight / total_weight, c.mean, c.covariance)
|
|
536
|
+
GaussianComponent(c.weight / total_weight, c.mean, c.covariance)
|
|
537
|
+
for c in working
|
|
535
538
|
]
|
|
536
539
|
|
|
537
540
|
return ReductionResult(working, n_original, len(working), total_cost)
|
|
@@ -602,7 +605,8 @@ class GaussianMixture:
|
|
|
602
605
|
total = sum(c.weight for c in self.components)
|
|
603
606
|
if total > 0:
|
|
604
607
|
self.components = [
|
|
605
|
-
GaussianComponent(c.weight / total, c.mean, c.covariance)
|
|
608
|
+
GaussianComponent(c.weight / total, c.mean, c.covariance)
|
|
609
|
+
for c in self.components
|
|
606
610
|
]
|
|
607
611
|
|
|
608
612
|
@property
|
pytcl/clustering/hierarchical.py
CHANGED
|
@@ -152,7 +152,11 @@ def _ward_linkage(
|
|
|
152
152
|
"""Ward's linkage: minimum variance merge."""
|
|
153
153
|
total = size_i + size_j + size_k
|
|
154
154
|
return np.sqrt(
|
|
155
|
-
(
|
|
155
|
+
(
|
|
156
|
+
(size_i + size_k) * dist_i**2
|
|
157
|
+
+ (size_j + size_k) * dist_j**2
|
|
158
|
+
- size_k * dist_ij**2
|
|
159
|
+
)
|
|
156
160
|
/ total
|
|
157
161
|
)
|
|
158
162
|
|
pytcl/clustering/kmeans.py
CHANGED
|
@@ -250,7 +250,9 @@ def kmeans(
|
|
|
250
250
|
raise ValueError(f"n_clusters ({n_clusters}) > n_samples ({n_samples})")
|
|
251
251
|
|
|
252
252
|
# Check if initial centers are provided
|
|
253
|
-
if isinstance(init, np.ndarray) or (
|
|
253
|
+
if isinstance(init, np.ndarray) or (
|
|
254
|
+
isinstance(init, (list, tuple)) and len(init) > 0
|
|
255
|
+
):
|
|
254
256
|
init_centers = np.asarray(init, dtype=np.float64)
|
|
255
257
|
if init_centers.shape != (n_clusters, n_features):
|
|
256
258
|
raise ValueError(
|
pytcl/containers/cluster_set.py
CHANGED
|
@@ -290,7 +290,9 @@ class ClusterSet:
|
|
|
290
290
|
self._clusters = list(clusters)
|
|
291
291
|
|
|
292
292
|
# Build lookups
|
|
293
|
-
self._id_to_idx: Dict[int, int] = {
|
|
293
|
+
self._id_to_idx: Dict[int, int] = {
|
|
294
|
+
c.id: i for i, c in enumerate(self._clusters)
|
|
295
|
+
}
|
|
294
296
|
self._track_to_cluster: Dict[int, int] = {}
|
|
295
297
|
for cluster in self._clusters:
|
|
296
298
|
for track_id in cluster.track_ids:
|
|
@@ -407,7 +409,9 @@ class ClusterSet:
|
|
|
407
409
|
return self.get_cluster(cluster_id)
|
|
408
410
|
return None
|
|
409
411
|
|
|
410
|
-
def clusters_in_region(
|
|
412
|
+
def clusters_in_region(
|
|
413
|
+
self, center: ArrayLike, radius: float
|
|
414
|
+
) -> List[TrackCluster]:
|
|
411
415
|
"""
|
|
412
416
|
Get clusters with centroids within a spatial region.
|
|
413
417
|
|
|
@@ -556,7 +560,9 @@ class ClusterSet:
|
|
|
556
560
|
"""
|
|
557
561
|
result = {}
|
|
558
562
|
for cluster in self._clusters:
|
|
559
|
-
stats = self.cluster_stats(
|
|
563
|
+
stats = self.cluster_stats(
|
|
564
|
+
cluster.id, tracks, state_indices, velocity_indices
|
|
565
|
+
)
|
|
560
566
|
if stats is not None:
|
|
561
567
|
result[cluster.id] = stats
|
|
562
568
|
return result
|
|
@@ -203,7 +203,9 @@ class MeasurementSet:
|
|
|
203
203
|
MeasurementSet
|
|
204
204
|
Measurements at the specified time.
|
|
205
205
|
"""
|
|
206
|
-
measurements = [
|
|
206
|
+
measurements = [
|
|
207
|
+
m for m in self._measurements if abs(m.time - time) <= tolerance
|
|
208
|
+
]
|
|
207
209
|
return MeasurementSet(measurements)
|
|
208
210
|
|
|
209
211
|
def in_time_window(self, start: float, end: float) -> MeasurementSet:
|
|
@@ -344,7 +346,9 @@ class MeasurementSet:
|
|
|
344
346
|
return np.zeros((0, 0))
|
|
345
347
|
return np.array([m.value for m in self._measurements])
|
|
346
348
|
|
|
347
|
-
def values_at_time(
|
|
349
|
+
def values_at_time(
|
|
350
|
+
self, time: float, tolerance: float = 1e-9
|
|
351
|
+
) -> NDArray[np.float64]:
|
|
348
352
|
"""
|
|
349
353
|
Extract measurement values at a specific time.
|
|
350
354
|
|