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/gravity/__init__.py CHANGED
@@ -19,71 +19,61 @@ Examples
19
19
  >>> print(f"Gravity magnitude: {result.magnitude:.4f} m/s^2")
20
20
  """
21
21
 
22
- from pytcl.gravity.clenshaw import (
23
- clenshaw_gravity,
24
- clenshaw_potential,
25
- clenshaw_sum_order,
26
- clenshaw_sum_order_derivative,
27
- )
28
- from pytcl.gravity.egm import (
29
- EGMCoefficients,
30
- GeoidResult,
31
- GravityDisturbance,
32
- create_test_coefficients,
33
- deflection_of_vertical,
34
- geoid_height,
35
- geoid_heights,
36
- get_data_dir,
37
- gravity_anomaly,
38
- gravity_disturbance,
39
- load_egm_coefficients,
40
- )
41
- from pytcl.gravity.models import (
42
- GRS80,
43
- WGS84,
44
- GravityConstants,
45
- GravityResult,
46
- bouguer_anomaly,
47
- free_air_anomaly,
48
- geoid_height_j2,
49
- gravitational_potential,
50
- gravity_j2,
51
- gravity_wgs84,
52
- normal_gravity,
53
- normal_gravity_somigliana,
54
- )
55
- from pytcl.gravity.spherical_harmonics import (
56
- associated_legendre,
57
- associated_legendre_derivative,
58
- associated_legendre_scaled,
59
- gravity_acceleration,
60
- legendre_scaling_factors,
61
- spherical_harmonic_sum,
62
- )
63
- from pytcl.gravity.tides import (
64
- GRAVIMETRIC_FACTOR,
65
- LOVE_H2,
66
- LOVE_H3,
67
- LOVE_K2,
68
- LOVE_K3,
69
- SHIDA_L2,
70
- SHIDA_L3,
71
- TIDAL_CONSTITUENTS,
72
- OceanTideLoading,
73
- TidalDisplacement,
74
- TidalGravity,
75
- atmospheric_pressure_loading,
76
- fundamental_arguments,
77
- julian_centuries_j2000,
78
- moon_position_approximate,
79
- ocean_tide_loading_displacement,
80
- pole_tide_displacement,
81
- solid_earth_tide_displacement,
82
- solid_earth_tide_gravity,
83
- sun_position_approximate,
84
- tidal_gravity_correction,
85
- total_tidal_displacement,
86
- )
22
+ from pytcl.gravity.clenshaw import clenshaw_gravity
23
+ from pytcl.gravity.clenshaw import clenshaw_potential
24
+ from pytcl.gravity.clenshaw import clenshaw_sum_order
25
+ from pytcl.gravity.clenshaw import clenshaw_sum_order_derivative
26
+ from pytcl.gravity.egm import EGMCoefficients
27
+ from pytcl.gravity.egm import GeoidResult
28
+ from pytcl.gravity.egm import GravityDisturbance
29
+ from pytcl.gravity.egm import create_test_coefficients
30
+ from pytcl.gravity.egm import deflection_of_vertical
31
+ from pytcl.gravity.egm import geoid_height
32
+ from pytcl.gravity.egm import geoid_heights
33
+ from pytcl.gravity.egm import get_data_dir
34
+ from pytcl.gravity.egm import gravity_anomaly
35
+ from pytcl.gravity.egm import gravity_disturbance
36
+ from pytcl.gravity.egm import load_egm_coefficients
37
+ from pytcl.gravity.models import GRS80
38
+ from pytcl.gravity.models import WGS84
39
+ from pytcl.gravity.models import GravityConstants
40
+ from pytcl.gravity.models import GravityResult
41
+ from pytcl.gravity.models import bouguer_anomaly
42
+ from pytcl.gravity.models import free_air_anomaly
43
+ from pytcl.gravity.models import geoid_height_j2
44
+ from pytcl.gravity.models import gravitational_potential
45
+ from pytcl.gravity.models import gravity_j2
46
+ from pytcl.gravity.models import gravity_wgs84
47
+ from pytcl.gravity.models import normal_gravity
48
+ from pytcl.gravity.models import normal_gravity_somigliana
49
+ from pytcl.gravity.spherical_harmonics import associated_legendre
50
+ from pytcl.gravity.spherical_harmonics import associated_legendre_derivative
51
+ from pytcl.gravity.spherical_harmonics import associated_legendre_scaled
52
+ from pytcl.gravity.spherical_harmonics import gravity_acceleration
53
+ from pytcl.gravity.spherical_harmonics import legendre_scaling_factors
54
+ from pytcl.gravity.spherical_harmonics import spherical_harmonic_sum
55
+ from pytcl.gravity.tides import GRAVIMETRIC_FACTOR
56
+ from pytcl.gravity.tides import LOVE_H2
57
+ from pytcl.gravity.tides import LOVE_H3
58
+ from pytcl.gravity.tides import LOVE_K2
59
+ from pytcl.gravity.tides import LOVE_K3
60
+ from pytcl.gravity.tides import SHIDA_L2
61
+ from pytcl.gravity.tides import SHIDA_L3
62
+ from pytcl.gravity.tides import TIDAL_CONSTITUENTS
63
+ from pytcl.gravity.tides import OceanTideLoading
64
+ from pytcl.gravity.tides import TidalDisplacement
65
+ from pytcl.gravity.tides import TidalGravity
66
+ from pytcl.gravity.tides import atmospheric_pressure_loading
67
+ from pytcl.gravity.tides import fundamental_arguments
68
+ from pytcl.gravity.tides import julian_centuries_j2000
69
+ from pytcl.gravity.tides import moon_position_approximate
70
+ from pytcl.gravity.tides import ocean_tide_loading_displacement
71
+ from pytcl.gravity.tides import pole_tide_displacement
72
+ from pytcl.gravity.tides import solid_earth_tide_displacement
73
+ from pytcl.gravity.tides import solid_earth_tide_gravity
74
+ from pytcl.gravity.tides import sun_position_approximate
75
+ from pytcl.gravity.tides import tidal_gravity_correction
76
+ from pytcl.gravity.tides import total_tidal_displacement
87
77
 
88
78
  __all__ = [
89
79
  # Spherical harmonics
pytcl/gravity/clenshaw.py CHANGED
@@ -19,7 +19,8 @@ References
19
19
  Journal of Geodesy 82.4-5 (2008): 223-229.
20
20
  """
21
21
 
22
- from typing import Optional, Tuple
22
+ from typing import Optional
23
+ from typing import Tuple
23
24
 
24
25
  import numpy as np
25
26
  from numpy.typing import NDArray
@@ -407,9 +408,7 @@ def clenshaw_potential(
407
408
  V = 0.0
408
409
 
409
410
  for m in range(n_max + 1):
410
- sum_C, sum_S = clenshaw_sum_order(
411
- m, cos_theta, sin_theta, C_scaled, S_scaled, n_max
412
- )
411
+ sum_C, sum_S = clenshaw_sum_order(m, cos_theta, sin_theta, C_scaled, S_scaled, n_max)
413
412
 
414
413
  cos_m_lon = np.cos(m * lon)
415
414
  sin_m_lon = np.sin(m * lon)
@@ -498,9 +497,7 @@ def clenshaw_gravity(
498
497
 
499
498
  for m in range(n_max + 1):
500
499
  # Value sum
501
- sum_C, sum_S = clenshaw_sum_order(
502
- m, cos_theta, sin_theta, C_scaled, S_scaled, n_max
503
- )
500
+ sum_C, sum_S = clenshaw_sum_order(m, cos_theta, sin_theta, C_scaled, S_scaled, n_max)
504
501
 
505
502
  # Radial derivative sum
506
503
  sum_C_r, sum_S_r = clenshaw_sum_order(
pytcl/gravity/egm.py CHANGED
@@ -24,13 +24,18 @@ References
24
24
  import os
25
25
  from functools import lru_cache
26
26
  from pathlib import Path
27
- from typing import Dict, NamedTuple, Optional, Tuple
27
+ from typing import Dict
28
+ from typing import NamedTuple
29
+ from typing import Optional
30
+ from typing import Tuple
28
31
 
29
32
  import numpy as np
30
33
  from numpy.typing import NDArray
31
34
 
32
- from .clenshaw import clenshaw_gravity, clenshaw_potential
33
- from .models import WGS84, normal_gravity_somigliana
35
+ from .clenshaw import clenshaw_gravity
36
+ from .clenshaw import clenshaw_potential
37
+ from .models import WGS84
38
+ from .models import normal_gravity_somigliana
34
39
 
35
40
 
36
41
  class EGMCoefficients(NamedTuple):
@@ -491,9 +496,7 @@ def geoid_heights(
491
496
  # Compute for each point
492
497
  heights = np.zeros(len(lats))
493
498
  for i in range(len(lats)):
494
- heights[i] = geoid_height(
495
- lats[i], lons[i], model, n_max, coefficients=coefficients
496
- )
499
+ heights[i] = geoid_height(lats[i], lons[i], model, n_max, coefficients=coefficients)
497
500
 
498
501
  return heights
499
502
 
pytcl/gravity/models.py CHANGED
@@ -190,9 +190,7 @@ def normal_gravity(
190
190
  sin2_lat = np.sin(lat) ** 2
191
191
 
192
192
  # Height correction
193
- gamma = gamma_0 * (
194
- 1 - 2 / a * (1 + f + m - 2 * f * sin2_lat) * h + 3 / (a * a) * h * h
195
- )
193
+ gamma = gamma_0 * (1 - 2 / a * (1 + f + m - 2 * f * sin2_lat) * h + 3 / (a * a) * h * h)
196
194
 
197
195
  return gamma
198
196
 
@@ -11,7 +11,8 @@ References
11
11
  .. [2] O. Montenbruck and E. Gill, "Satellite Orbits," Springer, 2000.
12
12
  """
13
13
 
14
- from typing import Optional, Tuple
14
+ from typing import Optional
15
+ from typing import Tuple
15
16
 
16
17
  import numpy as np
17
18
  from numpy.typing import NDArray
@@ -94,9 +95,7 @@ def associated_legendre(
94
95
  b_nm = np.sqrt(((n - 1) ** 2 - m * m) / (4 * (n - 1) ** 2 - 1))
95
96
  P[n, m] = a_nm * (x * P[n - 1, m] - b_nm * P[n - 2, m])
96
97
  else:
97
- P[n, m] = (
98
- (2 * n - 1) * x * P[n - 1, m] - (n + m - 1) * P[n - 2, m]
99
- ) / (n - m)
98
+ P[n, m] = ((2 * n - 1) * x * P[n - 1, m] - (n + m - 1) * P[n - 2, m]) / (n - m)
100
99
 
101
100
  return P
102
101
 
@@ -157,8 +156,7 @@ def associated_legendre_derivative(
157
156
  factor = np.sqrt((n - m) * (n + m + 1))
158
157
  if m + 1 <= m_max and n >= m + 1:
159
158
  dP[n, m] = (
160
- n * x / u2 * P[n, m]
161
- - factor / np.sqrt(u2) * P[n, m + 1]
159
+ n * x / u2 * P[n, m] - factor / np.sqrt(u2) * P[n, m + 1]
162
160
  if m + 1 <= n
163
161
  else n * x / u2 * P[n, m]
164
162
  )
@@ -166,9 +164,7 @@ def associated_legendre_derivative(
166
164
  dP[n, m] = n * x / u2 * P[n, m]
167
165
  else:
168
166
  # Unnormalized form
169
- dP[n, m] = (
170
- (n * x * P[n, m] - (n + m) * P[n - 1, m]) / u2 if n > 0 else 0
171
- )
167
+ dP[n, m] = (n * x * P[n, m] - (n + m) * P[n - 1, m]) / u2 if n > 0 else 0
172
168
 
173
169
  return dP
174
170
 
@@ -488,8 +484,7 @@ def associated_legendre_scaled(
488
484
  s_ratio_2 = scale[n] / scale[n - 2]
489
485
 
490
486
  P_scaled[n, m] = a_nm * (
491
- x * P_scaled[n - 1, m] * s_ratio_1
492
- - b_nm * P_scaled[n - 2, m] * s_ratio_2
487
+ x * P_scaled[n - 1, m] * s_ratio_1 - b_nm * P_scaled[n - 2, m] * s_ratio_2
493
488
  )
494
489
 
495
490
  return P_scaled, scale_exp
pytcl/gravity/tides.py CHANGED
@@ -20,7 +20,8 @@ References
20
20
  displacements," JGR, 102, B9, 20469-20477, 1997.
21
21
  """
22
22
 
23
- from typing import NamedTuple, Tuple
23
+ from typing import NamedTuple
24
+ from typing import Tuple
24
25
 
25
26
  import numpy as np
26
27
  from numpy.typing import NDArray
@@ -179,36 +180,31 @@ def fundamental_arguments(T: float) -> Tuple[float, float, float, float, float]:
179
180
  # Mean anomaly of the Moon (l)
180
181
  l_moon = (
181
182
  134.96340251
182
- + (1717915923.2178 * T + 31.8792 * T**2 + 0.051635 * T**3 - 0.00024470 * T**4)
183
- / 3600.0
183
+ + (1717915923.2178 * T + 31.8792 * T**2 + 0.051635 * T**3 - 0.00024470 * T**4) / 3600.0
184
184
  ) * deg2rad
185
185
 
186
186
  # Mean anomaly of the Sun (l')
187
187
  l_sun = (
188
188
  357.52910918
189
- + (129596581.0481 * T - 0.5532 * T**2 + 0.000136 * T**3 - 0.00001149 * T**4)
190
- / 3600.0
189
+ + (129596581.0481 * T - 0.5532 * T**2 + 0.000136 * T**3 - 0.00001149 * T**4) / 3600.0
191
190
  ) * deg2rad
192
191
 
193
192
  # Mean argument of latitude of the Moon (F)
194
193
  F = (
195
194
  93.27209062
196
- + (1739527262.8478 * T - 12.7512 * T**2 - 0.001037 * T**3 + 0.00000417 * T**4)
197
- / 3600.0
195
+ + (1739527262.8478 * T - 12.7512 * T**2 - 0.001037 * T**3 + 0.00000417 * T**4) / 3600.0
198
196
  ) * deg2rad
199
197
 
200
198
  # Mean elongation of the Moon from the Sun (D)
201
199
  D = (
202
200
  297.85019547
203
- + (1602961601.2090 * T - 6.3706 * T**2 + 0.006593 * T**3 - 0.00003169 * T**4)
204
- / 3600.0
201
+ + (1602961601.2090 * T - 6.3706 * T**2 + 0.006593 * T**3 - 0.00003169 * T**4) / 3600.0
205
202
  ) * deg2rad
206
203
 
207
204
  # Mean longitude of the ascending node of the Moon (Omega)
208
205
  Omega = (
209
206
  125.04455501
210
- + (-6962890.5431 * T + 7.4722 * T**2 + 0.007702 * T**3 - 0.00005939 * T**4)
211
- / 3600.0
207
+ + (-6962890.5431 * T + 7.4722 * T**2 + 0.007702 * T**3 - 0.00005939 * T**4) / 3600.0
212
208
  ) * deg2rad
213
209
 
214
210
  return (
@@ -279,9 +275,7 @@ def moon_position_approximate(mjd: float) -> Tuple[float, float, float]:
279
275
 
280
276
  # Distance perturbations (km)
281
277
  r_pert = (
282
- -20.905355 * np.cos(M_prime)
283
- - 3.699111 * np.cos(2 * D - M_prime)
284
- - 2.955968 * np.cos(2 * D)
278
+ -20.905355 * np.cos(M_prime) - 3.699111 * np.cos(2 * D - M_prime) - 2.955968 * np.cos(2 * D)
285
279
  ) * 1000 # Convert to km
286
280
 
287
281
  # Final position
@@ -586,9 +580,7 @@ def solid_earth_tide_gravity(
586
580
  delta_g_north = 0.0
587
581
  delta_g_east = 0.0
588
582
 
589
- return TidalGravity(
590
- delta_g=delta_g, delta_g_north=delta_g_north, delta_g_east=delta_g_east
591
- )
583
+ return TidalGravity(delta_g=delta_g, delta_g_north=delta_g_north, delta_g_east=delta_g_east)
592
584
 
593
585
 
594
586
  def ocean_tide_loading_displacement(
@@ -25,44 +25,34 @@ Examples
25
25
  >>> coef = create_emm_test_coefficients(n_max=36)
26
26
  """
27
27
 
28
- from pytcl.magnetism.emm import (
29
- EMM_PARAMETERS,
30
- HighResCoefficients,
31
- )
28
+ from pytcl.magnetism.emm import EMM_PARAMETERS
29
+ from pytcl.magnetism.emm import HighResCoefficients
32
30
  from pytcl.magnetism.emm import create_test_coefficients as create_emm_test_coefficients
33
- from pytcl.magnetism.emm import (
34
- emm,
35
- emm_declination,
36
- emm_inclination,
37
- emm_intensity,
38
- )
31
+ from pytcl.magnetism.emm import emm
32
+ from pytcl.magnetism.emm import emm_declination
33
+ from pytcl.magnetism.emm import emm_inclination
34
+ from pytcl.magnetism.emm import emm_intensity
39
35
  from pytcl.magnetism.emm import get_data_dir as get_emm_data_dir
40
- from pytcl.magnetism.emm import (
41
- load_emm_coefficients,
42
- wmmhr,
43
- )
44
- from pytcl.magnetism.igrf import (
45
- IGRF13,
46
- IGRFModel,
47
- create_igrf13_coefficients,
48
- dipole_axis,
49
- dipole_moment,
50
- igrf,
51
- igrf_declination,
52
- igrf_inclination,
53
- magnetic_north_pole,
54
- )
55
- from pytcl.magnetism.wmm import (
56
- WMM2020,
57
- MagneticCoefficients,
58
- MagneticResult,
59
- create_wmm2020_coefficients,
60
- magnetic_declination,
61
- magnetic_field_intensity,
62
- magnetic_field_spherical,
63
- magnetic_inclination,
64
- wmm,
65
- )
36
+ from pytcl.magnetism.emm import load_emm_coefficients
37
+ from pytcl.magnetism.emm import wmmhr
38
+ from pytcl.magnetism.igrf import IGRF13
39
+ from pytcl.magnetism.igrf import IGRFModel
40
+ from pytcl.magnetism.igrf import create_igrf13_coefficients
41
+ from pytcl.magnetism.igrf import dipole_axis
42
+ from pytcl.magnetism.igrf import dipole_moment
43
+ from pytcl.magnetism.igrf import igrf
44
+ from pytcl.magnetism.igrf import igrf_declination
45
+ from pytcl.magnetism.igrf import igrf_inclination
46
+ from pytcl.magnetism.igrf import magnetic_north_pole
47
+ from pytcl.magnetism.wmm import WMM2020
48
+ from pytcl.magnetism.wmm import MagneticCoefficients
49
+ from pytcl.magnetism.wmm import MagneticResult
50
+ from pytcl.magnetism.wmm import create_wmm2020_coefficients
51
+ from pytcl.magnetism.wmm import magnetic_declination
52
+ from pytcl.magnetism.wmm import magnetic_field_intensity
53
+ from pytcl.magnetism.wmm import magnetic_field_spherical
54
+ from pytcl.magnetism.wmm import magnetic_inclination
55
+ from pytcl.magnetism.wmm import wmm
66
56
 
67
57
  __all__ = [
68
58
  # Types and constants
pytcl/magnetism/emm.py CHANGED
@@ -24,7 +24,10 @@ References
24
24
  import os
25
25
  from functools import lru_cache
26
26
  from pathlib import Path
27
- from typing import Dict, NamedTuple, Optional, Tuple
27
+ from typing import Dict
28
+ from typing import NamedTuple
29
+ from typing import Optional
30
+ from typing import Tuple
28
31
 
29
32
  import numpy as np
30
33
  from numpy.typing import NDArray
@@ -531,8 +534,7 @@ def _high_res_field_spherical(
531
534
  factor = np.sqrt((n - m) * (n + m + 1))
532
535
  if m + 1 <= n:
533
536
  dP[n, m] = (
534
- n * cos_theta / sin_theta * P[n, m]
535
- - factor * P[n, m + 1] / sin_theta
537
+ n * cos_theta / sin_theta * P[n, m] - factor * P[n, m + 1] / sin_theta
536
538
  if m + 1 <= n_max_eval
537
539
  else n * cos_theta / sin_theta * P[n, m]
538
540
  )
@@ -559,13 +561,7 @@ def _high_res_field_spherical(
559
561
  B_theta += -r_power * dP[n, m] * (gnm * cos_m_lon + hnm * sin_m_lon)
560
562
 
561
563
  if abs(sin_theta) > 1e-10:
562
- B_phi += (
563
- r_power
564
- * m
565
- * P[n, m]
566
- / sin_theta
567
- * (gnm * sin_m_lon - hnm * cos_m_lon)
568
- )
564
+ B_phi += r_power * m * P[n, m] / sin_theta * (gnm * sin_m_lon - hnm * cos_m_lon)
569
565
 
570
566
  return B_r, B_theta, B_phi
571
567
 
@@ -624,9 +620,7 @@ def emm(
624
620
  r = a + h
625
621
 
626
622
  # Compute field in spherical coordinates
627
- B_r, B_theta, B_phi = _high_res_field_spherical(
628
- lat_gc, lon, r, year, coefficients, n_max
629
- )
623
+ B_r, B_theta, B_phi = _high_res_field_spherical(lat_gc, lon, r, year, coefficients, n_max)
630
624
 
631
625
  # Convert to geodetic coordinates
632
626
  X = -B_theta # North
pytcl/magnetism/igrf.py CHANGED
@@ -12,15 +12,14 @@ References
12
12
  .. [2] https://www.ngdc.noaa.gov/IAGA/vmod/igrf.html
13
13
  """
14
14
 
15
- from typing import NamedTuple, Optional
15
+ from typing import NamedTuple
16
+ from typing import Optional
16
17
 
17
18
  import numpy as np
18
19
 
19
- from pytcl.magnetism.wmm import (
20
- MagneticCoefficients,
21
- MagneticResult,
22
- magnetic_field_spherical,
23
- )
20
+ from pytcl.magnetism.wmm import MagneticCoefficients
21
+ from pytcl.magnetism.wmm import MagneticResult
22
+ from pytcl.magnetism.wmm import magnetic_field_spherical
24
23
 
25
24
 
26
25
  class IGRFModel(NamedTuple):
pytcl/magnetism/wmm.py CHANGED
@@ -12,7 +12,8 @@ References
12
12
  .. [2] https://www.ngdc.noaa.gov/geomag/WMM/
13
13
  """
14
14
 
15
- from typing import NamedTuple, Tuple
15
+ from typing import NamedTuple
16
+ from typing import Tuple
16
17
 
17
18
  import numpy as np
18
19
  from numpy.typing import NDArray
@@ -468,8 +469,7 @@ def magnetic_field_spherical(
468
469
  factor = np.sqrt((n - m) * (n + m + 1))
469
470
  if m + 1 <= n:
470
471
  dP[n, m] = (
471
- n * cos_theta / sin_theta * P[n, m]
472
- - factor * P[n, m + 1] / sin_theta
472
+ n * cos_theta / sin_theta * P[n, m] - factor * P[n, m + 1] / sin_theta
473
473
  if m + 1 <= n_max
474
474
  else n * cos_theta / sin_theta * P[n, m]
475
475
  )
@@ -499,13 +499,7 @@ def magnetic_field_spherical(
499
499
  B_theta += -r_power * dP[n, m] * (gnm * cos_m_lon + hnm * sin_m_lon)
500
500
 
501
501
  if abs(sin_theta) > 1e-10:
502
- B_phi += (
503
- r_power
504
- * m
505
- * P[n, m]
506
- / sin_theta
507
- * (gnm * sin_m_lon - hnm * cos_m_lon)
508
- )
502
+ B_phi += r_power * m * P[n, m] / sin_theta * (gnm * sin_m_lon - hnm * cos_m_lon)
509
503
 
510
504
  return B_r, B_theta, B_phi
511
505