satkit 0.8.5__tar.gz → 0.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. {satkit-0.8.5 → satkit-0.9.0}/CHANGES.md +13 -1
  2. {satkit-0.8.5 → satkit-0.9.0}/Cargo.toml +3 -2
  3. {satkit-0.8.5 → satkit-0.9.0}/PKG-INFO +29 -24
  4. {satkit-0.8.5 → satkit-0.9.0}/README.md +25 -23
  5. {satkit-0.8.5 → satkit-0.9.0}/pyproject.toml +6 -4
  6. satkit-0.9.0/python/docs/source/TLE.md +118 -0
  7. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/examples/Eclipse.ipynb +17 -17
  8. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/examples/High Precision Propagation.ipynb +4 -4
  9. satkit-0.9.0/python/docs/source/examples/Orbital Mean-Element Message.ipynb +147 -0
  10. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/examples/Plots.ipynb +9 -9
  11. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/index.md +3 -2
  12. {satkit-0.8.5 → satkit-0.9.0}/python/requirements.txt +2 -1
  13. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/_version.py +2 -2
  14. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/satkit.pyi +67 -26
  15. {satkit-0.8.5 → satkit-0.9.0}/python/satkit.egg-info/PKG-INFO +29 -24
  16. {satkit-0.8.5 → satkit-0.9.0}/python/satkit.egg-info/SOURCES.txt +2 -0
  17. {satkit-0.8.5 → satkit-0.9.0}/python/satkit.egg-info/requires.txt +4 -0
  18. {satkit-0.8.5 → satkit-0.9.0}/python/test/test.py +54 -5
  19. {satkit-0.8.5 → satkit-0.9.0}/src/lib.rs +5 -0
  20. {satkit-0.8.5 → satkit-0.9.0}/src/ode/rk_adaptive.rs +17 -17
  21. {satkit-0.8.5 → satkit-0.9.0}/src/ode/types.rs +2 -2
  22. satkit-0.9.0/src/omm/mod.rs +353 -0
  23. {satkit-0.8.5 → satkit-0.9.0}/src/orbitprop/precomputed.rs +16 -16
  24. {satkit-0.8.5 → satkit-0.9.0}/src/orbitprop/propagator.rs +32 -32
  25. {satkit-0.8.5 → satkit-0.9.0}/src/orbitprop/settings.rs +12 -12
  26. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pyinstant.rs +24 -1
  27. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pypropagate.rs +33 -33
  28. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pypropresult.rs +16 -16
  29. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pypropsettings.rs +2 -2
  30. satkit-0.9.0/src/pybindings/pysgp4.rs +498 -0
  31. satkit-0.9.0/src/sgp4/mod.rs +82 -0
  32. {satkit-0.8.5 → satkit-0.9.0}/src/sgp4/sgp4_impl.rs +68 -70
  33. {satkit-0.8.5 → satkit-0.9.0}/src/tle/fitting.rs +5 -4
  34. {satkit-0.8.5 → satkit-0.9.0}/src/tle/mod.rs +40 -6
  35. satkit-0.8.5/python/docs/source/TLE.md +0 -61
  36. satkit-0.8.5/src/pybindings/pysgp4.rs +0 -277
  37. satkit-0.8.5/src/sgp4/mod.rs +0 -44
  38. {satkit-0.8.5 → satkit-0.9.0}/.github/workflows/build.yml +0 -0
  39. {satkit-0.8.5 → satkit-0.9.0}/.github/workflows/wheels.yml +0 -0
  40. {satkit-0.8.5 → satkit-0.9.0}/.gitignore +0 -0
  41. {satkit-0.8.5 → satkit-0.9.0}/.readthedocs.yaml +0 -0
  42. {satkit-0.8.5 → satkit-0.9.0}/CONTRIBUTING.md +0 -0
  43. {satkit-0.8.5 → satkit-0.9.0}/LICENSE +0 -0
  44. {satkit-0.8.5 → satkit-0.9.0}/MANIFEST.in +0 -0
  45. {satkit-0.8.5 → satkit-0.9.0}/build.rs +0 -0
  46. {satkit-0.8.5 → satkit-0.9.0}/extern/nrlmsise/DOCUMENTATION +0 -0
  47. {satkit-0.8.5 → satkit-0.9.0}/extern/nrlmsise/nrlmsise-00.c +0 -0
  48. {satkit-0.8.5 → satkit-0.9.0}/extern/nrlmsise/nrlmsise-00.h +0 -0
  49. {satkit-0.8.5 → satkit-0.9.0}/extern/nrlmsise/nrlmsise-00_data.c +0 -0
  50. {satkit-0.8.5 → satkit-0.9.0}/python/Pipfile +0 -0
  51. {satkit-0.8.5 → satkit-0.9.0}/python/docs/Makefile +0 -0
  52. {satkit-0.8.5 → satkit-0.9.0}/python/docs/jsdoc_config.json +0 -0
  53. {satkit-0.8.5 → satkit-0.9.0}/python/docs/jsdoc_plugin.js +0 -0
  54. {satkit-0.8.5 → satkit-0.9.0}/python/docs/make.bat +0 -0
  55. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/_static/density_vs_solar_cycle.svg +0 -0
  56. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/_static/force_vs_altitude.svg +0 -0
  57. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/_static/theme_mods.css +0 -0
  58. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/consts.md +0 -0
  59. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/density.md +0 -0
  60. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/earthgravity.md +0 -0
  61. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/frametransform.md +0 -0
  62. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/itrfcoord.md +0 -0
  63. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/jplephem.md +0 -0
  64. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/kepler.md +0 -0
  65. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/quaternion.md +0 -0
  66. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/satprop.md +0 -0
  67. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/satstate.md +0 -0
  68. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/time.md +0 -0
  69. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/tle.md +0 -0
  70. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/api/utils.md +0 -0
  71. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/conf.py +0 -0
  72. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/datafiles.md +0 -0
  73. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/density.md +0 -0
  74. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/examples/ITRF Coordinates.ipynb +0 -0
  75. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/examples/Satellite Ground Contacts.ipynb +0 -0
  76. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/examples/TLE Fitting.ipynb +0 -0
  77. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/examples/Two-Line Element Set.ipynb +0 -0
  78. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/examples/riseset.ipynb +0 -0
  79. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/frametransform.md +0 -0
  80. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/install.md +0 -0
  81. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/itrfcoord.md +0 -0
  82. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/quaternion.md +0 -0
  83. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/references.md +0 -0
  84. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/satprop.md +0 -0
  85. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/satstate.md +0 -0
  86. {satkit-0.8.5 → satkit-0.9.0}/python/docs/source/time.md +0 -0
  87. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/__init__.py +0 -0
  88. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/__init__.pyi +0 -0
  89. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/density.pyi +0 -0
  90. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/frametransform.pyi +0 -0
  91. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/jplephem.pyi +0 -0
  92. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/moon.pyi +0 -0
  93. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/planets.pyi +0 -0
  94. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/py.typed +0 -0
  95. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/sun.pyi +0 -0
  96. {satkit-0.8.5 → satkit-0.9.0}/python/satkit/utils.pyi +0 -0
  97. {satkit-0.8.5 → satkit-0.9.0}/python/satkit.egg-info/dependency_links.txt +0 -0
  98. {satkit-0.8.5 → satkit-0.9.0}/python/satkit.egg-info/top_level.txt +0 -0
  99. {satkit-0.8.5 → satkit-0.9.0}/python/test/download_data.py +0 -0
  100. {satkit-0.8.5 → satkit-0.9.0}/python/test/download_from_json.py +0 -0
  101. {satkit-0.8.5 → satkit-0.9.0}/python/test/download_testvecs.py +0 -0
  102. {satkit-0.8.5 → satkit-0.9.0}/python/test/sp3file.py +0 -0
  103. {satkit-0.8.5 → satkit-0.9.0}/setup.cfg +0 -0
  104. {satkit-0.8.5 → satkit-0.9.0}/src/consts.rs +0 -0
  105. {satkit-0.8.5 → satkit-0.9.0}/src/earth_orientation_params.rs +0 -0
  106. {satkit-0.8.5 → satkit-0.9.0}/src/earthgravity.rs +0 -0
  107. {satkit-0.8.5 → satkit-0.9.0}/src/filters/mod.rs +0 -0
  108. {satkit-0.8.5 → satkit-0.9.0}/src/filters/ukf.rs +0 -0
  109. {satkit-0.8.5 → satkit-0.9.0}/src/frames.rs +0 -0
  110. {satkit-0.8.5 → satkit-0.9.0}/src/frametransform/ierstable.rs +0 -0
  111. {satkit-0.8.5 → satkit-0.9.0}/src/frametransform/mod.rs +0 -0
  112. {satkit-0.8.5 → satkit-0.9.0}/src/frametransform/qcirs2gcrs.rs +0 -0
  113. {satkit-0.8.5 → satkit-0.9.0}/src/itrfcoord.rs +0 -0
  114. {satkit-0.8.5 → satkit-0.9.0}/src/jplephem.rs +0 -0
  115. {satkit-0.8.5 → satkit-0.9.0}/src/kepler.rs +0 -0
  116. {satkit-0.8.5 → satkit-0.9.0}/src/lpephem/mod.rs +0 -0
  117. {satkit-0.8.5 → satkit-0.9.0}/src/lpephem/moon.rs +0 -0
  118. {satkit-0.8.5 → satkit-0.9.0}/src/lpephem/planets.rs +0 -0
  119. {satkit-0.8.5 → satkit-0.9.0}/src/lpephem/sun.rs +0 -0
  120. {satkit-0.8.5 → satkit-0.9.0}/src/mathtypes.rs +0 -0
  121. {satkit-0.8.5 → satkit-0.9.0}/src/nrlmsise.rs +0 -0
  122. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/mod.rs +0 -0
  123. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkf45.rs +0 -0
  124. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkts54.rs +0 -0
  125. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkv65.rs +0 -0
  126. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkv65_table.rs +0 -0
  127. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkv87.rs +0 -0
  128. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkv87_table.rs +0 -0
  129. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkv98.rs +0 -0
  130. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkv98_efficient.rs +0 -0
  131. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkv98_efficient_table.rs +0 -0
  132. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkv98_nointerp.rs +0 -0
  133. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkv98_nointerp_table.rs +0 -0
  134. {satkit-0.8.5 → satkit-0.9.0}/src/ode/adaptive_solvers/rkv98_table.rs +0 -0
  135. {satkit-0.8.5 → satkit-0.9.0}/src/ode/mod.rs +0 -0
  136. {satkit-0.8.5 → satkit-0.9.0}/src/ode/nalgebra_bindings.rs +0 -0
  137. {satkit-0.8.5 → satkit-0.9.0}/src/ode/ode_tests.rs +0 -0
  138. {satkit-0.8.5 → satkit-0.9.0}/src/ode/rk_adaptive_settings.rs +0 -0
  139. {satkit-0.8.5 → satkit-0.9.0}/src/ode/rk_explicit.rs +0 -0
  140. {satkit-0.8.5 → satkit-0.9.0}/src/orbitprop/drag.rs +0 -0
  141. {satkit-0.8.5 → satkit-0.9.0}/src/orbitprop/mod.rs +0 -0
  142. {satkit-0.8.5 → satkit-0.9.0}/src/orbitprop/point_gravity.rs +0 -0
  143. {satkit-0.8.5 → satkit-0.9.0}/src/orbitprop/satproperties.rs +0 -0
  144. {satkit-0.8.5 → satkit-0.9.0}/src/orbitprop/satstate.rs +0 -0
  145. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/mod.rs +0 -0
  146. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/mod_utils.rs +0 -0
  147. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pyconsts.rs +0 -0
  148. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pydensity.rs +0 -0
  149. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pyduration.rs +0 -0
  150. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pyframes.rs +0 -0
  151. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pyframetransform.rs +0 -0
  152. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pygravity.rs +0 -0
  153. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pyitrfcoord.rs +0 -0
  154. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pyjplephem.rs +0 -0
  155. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pykepler.rs +0 -0
  156. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pylpephem_moon.rs +0 -0
  157. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pylpephem_planets.rs +0 -0
  158. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pylpephem_sun.rs +0 -0
  159. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pympsuccess.rs +0 -0
  160. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pynrlmsise.rs +0 -0
  161. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pyquaternion.rs +0 -0
  162. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pysatproperties.rs +0 -0
  163. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pysatstate.rs +0 -0
  164. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pysolarsystem.rs +0 -0
  165. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pytle.rs +0 -0
  166. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pyukf.rs +0 -0
  167. {satkit-0.8.5 → satkit-0.9.0}/src/pybindings/pyutils.rs +0 -0
  168. {satkit-0.8.5 → satkit-0.9.0}/src/sgp4/dpper.rs +0 -0
  169. {satkit-0.8.5 → satkit-0.9.0}/src/sgp4/dscom.rs +0 -0
  170. {satkit-0.8.5 → satkit-0.9.0}/src/sgp4/dsinit.rs +0 -0
  171. {satkit-0.8.5 → satkit-0.9.0}/src/sgp4/dspace.rs +0 -0
  172. {satkit-0.8.5 → satkit-0.9.0}/src/sgp4/getgravconst.rs +0 -0
  173. {satkit-0.8.5 → satkit-0.9.0}/src/sgp4/initl.rs +0 -0
  174. {satkit-0.8.5 → satkit-0.9.0}/src/sgp4/satrec.rs +0 -0
  175. {satkit-0.8.5 → satkit-0.9.0}/src/sgp4/sgp4_lowlevel.rs +0 -0
  176. {satkit-0.8.5 → satkit-0.9.0}/src/sgp4/sgp4init.rs +0 -0
  177. {satkit-0.8.5 → satkit-0.9.0}/src/solarsystem.rs +0 -0
  178. {satkit-0.8.5 → satkit-0.9.0}/src/spaceweather.rs +0 -0
  179. {satkit-0.8.5 → satkit-0.9.0}/src/time/duration.rs +0 -0
  180. {satkit-0.8.5 → satkit-0.9.0}/src/time/instant.rs +0 -0
  181. {satkit-0.8.5 → satkit-0.9.0}/src/time/instant_err.rs +0 -0
  182. {satkit-0.8.5 → satkit-0.9.0}/src/time/instant_ops.rs +0 -0
  183. {satkit-0.8.5 → satkit-0.9.0}/src/time/instantparse.rs +0 -0
  184. {satkit-0.8.5 → satkit-0.9.0}/src/time/mod.rs +0 -0
  185. {satkit-0.8.5 → satkit-0.9.0}/src/time/tests.rs +0 -0
  186. {satkit-0.8.5 → satkit-0.9.0}/src/time/timescale.rs +0 -0
  187. {satkit-0.8.5 → satkit-0.9.0}/src/time/weekday.rs +0 -0
  188. {satkit-0.8.5 → satkit-0.9.0}/src/utils/datadir.rs +0 -0
  189. {satkit-0.8.5 → satkit-0.9.0}/src/utils/download.rs +0 -0
  190. {satkit-0.8.5 → satkit-0.9.0}/src/utils/mod.rs +0 -0
  191. {satkit-0.8.5 → satkit-0.9.0}/src/utils/pypackage.rs +0 -0
  192. {satkit-0.8.5 → satkit-0.9.0}/src/utils/test.rs +0 -0
  193. {satkit-0.8.5 → satkit-0.9.0}/src/utils/update_data.rs +0 -0
@@ -1,9 +1,10 @@
1
1
  # Changelog
2
2
 
3
+
3
4
  ## 0.5.5 - 2025-01-27
4
5
 
5
6
  ### Low-Precision Ephemeris
6
- - Coefficients for low-precision planetary ephemerides did not match paper or JPL website referenced in documentation. Not sure where original numbers came from. Some plantes (e.g., Mercury) matched. Others (e.g., Mars) did not, although numbers for Mars did match a google search. Very strange ... regardless, update so they match. Coefficients for years 1800 to 2050 AD are correct and remain unchanged.
7
+ - Coefficients for low-precision planetary ephemerides did not match paper or JPL website referenced in documentation. Not sure where original nu mbers came from. Some plantes (e.g., Mercury) matched. Others (e.g., Mars) did not, although numbers for Mars did match a google search. Very strange ... regardless, update so they match. Coefficients for years 1800 to 2050 AD are correct and remain unchanged.
7
8
  - Add Pluto as a planet for low-precision ephemerides (it is included in reference paper, but not JPL website)
8
9
 
9
10
  ### Two-Line Element Sets
@@ -143,3 +144,14 @@
143
144
  - Add "x", "y", "z", "w" property getters to quaternion in python
144
145
  - Add pickle serialize/deserialize tests in python testing
145
146
  - allow for duration division by float and by other duration in python
147
+
148
+ -----------------
149
+
150
+
151
+ ## Rust 0.9.0, Python 0.9.0
152
+ - Support Orbital Mean-Element Messages (OMM) in JSON format
153
+ - Add OMM documentation, tests, and python example
154
+ - Structured output of SGP4 propagator in rust
155
+ - add "as_datetime" function in python for satkit.time (for consistent nomenclature)
156
+ - Rename time-interval boundary nomenclature from `start/stop` to `begin/end` across Rust + Python APIs (including propagation functions and related settings/results).
157
+
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "satkit"
3
- version = "0.8.3"
3
+ version = "0.9.0"
4
4
  edition = "2021"
5
5
  description = "Satellite Toolkit"
6
6
  readme = "README.md"
@@ -12,7 +12,7 @@ keywords = ["satellite", "orbit", "ephemeris", "tle", "astrodynamics"]
12
12
  categories = ["aerospace", "algorithms", "mathematics", "science"]
13
13
 
14
14
 
15
- # See more keys and their definitions at
15
+ # See more keys and their definitions at
16
16
  # https://doc.rust-lang.org/cargo/reference/manifest.html
17
17
  [lib]
18
18
  name = "satkit"
@@ -34,6 +34,7 @@ ureq = "3.1.2"
34
34
  json = "0.12.4"
35
35
  process_path = "0.1.4"
36
36
  serde = { version = "1.0", features = ["derive"] }
37
+ serde_json = "1.0"
37
38
  serde-pickle = "1.2.0"
38
39
  itertools = "0.14.0"
39
40
  anyhow = "1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: satkit
3
- Version: 0.8.5
3
+ Version: 0.9.0
4
4
  Summary: Satellite Orbital Dynamics Toolkit
5
5
  Author-email: Steven Michael <ssmichael@gmail.com>
6
6
  Maintainer-email: Steven Michael <ssmichael@gmail.com>
@@ -40,6 +40,9 @@ Description-Content-Type: text/markdown
40
40
  License-File: LICENSE
41
41
  Requires-Dist: numpy>=1.0.0
42
42
  Requires-Dist: satkit-data>=0.7.0
43
+ Provides-Extra: test
44
+ Requires-Dist: pytest; extra == "test"
45
+ Requires-Dist: xmltodict; extra == "test"
43
46
  Dynamic: license-file
44
47
 
45
48
  # Satellite Toolkit (satkit)
@@ -48,7 +51,7 @@ Dynamic: license-file
48
51
 
49
52
  Satkit provides robust, high-performance satellite orbital mechanics calculations with a clean, intuitive API. Built from the ground up in Rust for maximum performance and memory safety, it offers complete Python bindings for all functionality, making advanced orbital mechanics accessible to both systems programmers and data scientists.
50
53
 
51
- -----
54
+ -----
52
55
 
53
56
  ![Build Passing?](https://github.com/ssmichael1/satkit/actions/workflows/build.yml/badge.svg)
54
57
  ![Wheel Passing?](https://github.com/ssmichael1/satkit/actions/workflows/wheels.yml/badge.svg)
@@ -62,7 +65,7 @@ Satkit provides robust, high-performance satellite orbital mechanics calculation
62
65
  ![PyPI - Status](https://img.shields.io/pypi/status/satkit)
63
66
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/satkit)
64
67
  ![Read the Docs](https://img.shields.io/readthedocs/satellite-toolkit)
65
-
68
+
66
69
  ------
67
70
 
68
71
  ## Language Bindings
@@ -84,7 +87,7 @@ High-precision conversions between multiple reference frames with full support f
84
87
  - **CIRF** - Celestial Intermediate Reference Frame (IAU-2006 intermediate)
85
88
  - **TIRF** - Terrestrial Intermediate Reference Frame (Earth-rotation intermediate)
86
89
  - **Geodetic** - Latitude, longitude, altitude with WGS-84 ellipsoid
87
-
90
+
88
91
  ### Orbit Propagation
89
92
  Multiple propagation methods optimized for different accuracy and performance requirements:
90
93
  - **Numerical Integration**: High-precision propagation using adaptive Runge-Kutta 9(8) methods with dense output
@@ -95,27 +98,29 @@ Multiple propagation methods optimized for different accuracy and performance re
95
98
  - Full AFSPC and improved mode support
96
99
  - TLE fitting from high-precision states with drag estimation
97
100
  - Batch processing for multiple satellites
101
+ - Support TLE and Orbital Mean-Element Messages
98
102
  - **Keplerian**: Fast analytical two-body propagation for preliminary analysis
99
-
100
- ### Force Models
103
+
104
+ ### Numerical Integration Force Models
101
105
  Comprehensive perturbation modeling for high-fidelity orbit propagation:
102
106
  - **Earth Gravity**: Spherical harmonic models up to degree/order 360
103
107
  - Multiple models: JGM2, JGM3, EGM96, ITU GRACE16
104
108
  - Efficient computation with configurable truncation order
105
109
  - Gravity gradient support for state transition matrix
106
110
  - **Third-Body Gravity**: Solar and lunar perturbations using JPL ephemerides
107
- - **Atmospheric Drag**: NRLMSISE-00 density model with space weather integration
111
+ - **Atmospheric Drag**:
112
+ - NRLMSISE-00 density model with space weather integration
108
113
  - Automatic space weather data updates (F10.7, Ap index)
109
114
  - Configurable ballistic coefficients
110
115
  - **Solar Radiation Pressure**: Cannon-ball model with shadow function
111
-
112
- ### Ephemerides
116
+
117
+ ### Solar System Ephemerides
113
118
  Access to high-precision solar system body positions:
114
119
  - **JPL DE440/DE441**: State-of-the-art planetary ephemerides
115
120
  - Chebyshev polynomial interpolation for accuracy
116
121
  - Support for all major planets, sun, moon, and solar system barycenter
117
122
  - **Low-Precision Models**: Fast analytical models for sun and moon when high precision isn't required
118
-
123
+
119
124
  ### Time Systems
120
125
  Comprehensive support for all standard astronomical time scales:
121
126
  - **UTC** - Coordinated Universal Time with leap second handling
@@ -125,7 +130,7 @@ Comprehensive support for all standard astronomical time scales:
125
130
  - **UT1** - Universal Time with Earth orientation corrections
126
131
  - **GPS** - GPS Time
127
132
  - Automatic conversion between all time scales with microsecond precision
128
-
133
+
129
134
  ### Geodetic Utilities
130
135
  - **Geodesic Calculations**: Accurate distance and azimuth between ground locations using Vincenty's formulae
131
136
  - **Coordinate Conversions**: ITRF ↔ Geodetic ↔ East-North-Up ↔ North-East-Down
@@ -178,12 +183,12 @@ The library requires external data files for various calculations. These are aut
178
183
  - DE440/DE441 planetary ephemerides (~100 MB)
179
184
  - Provides positions of sun, moon, planets, and solar system barycenter
180
185
  - Valid for years 1550-2650 CE
181
-
186
+
182
187
  - **Gravity Models** ([ICGEM](http://icgem.gfz-potsdam.de/home))
183
188
  - JGM2, JGM3, EGM96, ITU GRACE16 spherical harmonic coefficients
184
189
  - International Centre for Global Earth Models standardized format
185
190
  - Up to degree/order 360 for high-fidelity propagation
186
-
191
+
187
192
  - **IERS Nutation Tables** ([IERS Conventions](https://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.html))
188
193
  - IAU-2006 nutation series coefficients
189
194
  - Required for GCRF ↔ ITRF transformations
@@ -196,7 +201,7 @@ The library requires external data files for various calculations. These are aut
196
201
  - Ap geomagnetic index
197
202
  - Critical for atmospheric density modeling and drag calculations
198
203
  - Updated daily by NOAA Space Weather Prediction Center
199
-
204
+
200
205
  - **Earth Orientation Parameters** ([Celestrak](https://celestrak.org/SpaceData/))
201
206
  - Polar motion (x, y)
202
207
  - UT1-UTC time difference
@@ -218,15 +223,15 @@ The library includes comprehensive test suites ensuring correctness of calculati
218
223
  - **JPL Ephemerides**: Validated against JPL-provided test vectors for Chebyshev polynomial interpolation
219
224
  - Over 10,000 test cases covering all planets and time ranges
220
225
  - Accuracy verified to within JPL's published tolerances (sub-meter precision)
221
-
226
+
222
227
  - **SGP4**: Verified using official test vectors from the original C++ distribution
223
228
  - All test cases from Vallado's SGP4 implementation
224
229
  - Includes edge cases and error conditions
225
-
230
+
226
231
  - **Coordinate Transformations**: Cross-validated against multiple reference implementations
227
232
  - SOFA library comparisons for IAU-2006 transformations
228
233
  - Vallado test cases for GCRF ↔ ITRF conversions
229
-
234
+
230
235
  - **Numerical Propagation**: Validated against high-precision commercial tools
231
236
  - Orbit fits to GPS SP3 ephemerides
232
237
  - Multi-day propagations with sub-meter accuracy
@@ -266,7 +271,7 @@ pip install satkit
266
271
 
267
272
  Pre-built binary wheels are available for:
268
273
  - **Windows**: AMD64
269
- - **macOS**: Intel (x86_64) and Apple Silicon (ARM64)
274
+ - **macOS**: Intel (x86_64) and Apple Silicon (ARM64)
270
275
  - **Linux**: x86_64 and ARM64 (aarch64)
271
276
  - **Python versions**: 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
272
277
 
@@ -336,9 +341,9 @@ settings.gravity_order = 8
336
341
 
337
342
  # Propagate for 1 day
338
343
  result = sk.propagate(
339
- state0,
340
- time0,
341
- stop=time0 + sk.duration.from_days(1),
344
+ state0,
345
+ time0,
346
+ end=time0 + sk.duration.from_days(1),
342
347
  propsettings=settings
343
348
  )
344
349
 
@@ -375,13 +380,13 @@ use satkit::{Instant, SolarSystem, jplephem};
375
380
  fn main() -> Result<(), Box<dyn std::error::Error>> {
376
381
  // Create time instant
377
382
  let time = Instant::from_datetime(2024, 1, 1, 0, 0, 0.0)?;
378
-
383
+
379
384
  // Get Moon position and velocity in GCRF
380
385
  let (pos, vel) = jplephem::geocentric_state(SolarSystem::Moon, &time)?;
381
-
386
+
382
387
  println!("Moon position: {:?}", pos);
383
388
  println!("Moon velocity: {:?}", vel);
384
-
389
+
385
390
  Ok(())
386
391
  }
387
392
  ```
@@ -4,7 +4,7 @@
4
4
 
5
5
  Satkit provides robust, high-performance satellite orbital mechanics calculations with a clean, intuitive API. Built from the ground up in Rust for maximum performance and memory safety, it offers complete Python bindings for all functionality, making advanced orbital mechanics accessible to both systems programmers and data scientists.
6
6
 
7
- -----
7
+ -----
8
8
 
9
9
  ![Build Passing?](https://github.com/ssmichael1/satkit/actions/workflows/build.yml/badge.svg)
10
10
  ![Wheel Passing?](https://github.com/ssmichael1/satkit/actions/workflows/wheels.yml/badge.svg)
@@ -18,7 +18,7 @@ Satkit provides robust, high-performance satellite orbital mechanics calculation
18
18
  ![PyPI - Status](https://img.shields.io/pypi/status/satkit)
19
19
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/satkit)
20
20
  ![Read the Docs](https://img.shields.io/readthedocs/satellite-toolkit)
21
-
21
+
22
22
  ------
23
23
 
24
24
  ## Language Bindings
@@ -40,7 +40,7 @@ High-precision conversions between multiple reference frames with full support f
40
40
  - **CIRF** - Celestial Intermediate Reference Frame (IAU-2006 intermediate)
41
41
  - **TIRF** - Terrestrial Intermediate Reference Frame (Earth-rotation intermediate)
42
42
  - **Geodetic** - Latitude, longitude, altitude with WGS-84 ellipsoid
43
-
43
+
44
44
  ### Orbit Propagation
45
45
  Multiple propagation methods optimized for different accuracy and performance requirements:
46
46
  - **Numerical Integration**: High-precision propagation using adaptive Runge-Kutta 9(8) methods with dense output
@@ -51,27 +51,29 @@ Multiple propagation methods optimized for different accuracy and performance re
51
51
  - Full AFSPC and improved mode support
52
52
  - TLE fitting from high-precision states with drag estimation
53
53
  - Batch processing for multiple satellites
54
+ - Support TLE and Orbital Mean-Element Messages
54
55
  - **Keplerian**: Fast analytical two-body propagation for preliminary analysis
55
-
56
- ### Force Models
56
+
57
+ ### Numerical Integration Force Models
57
58
  Comprehensive perturbation modeling for high-fidelity orbit propagation:
58
59
  - **Earth Gravity**: Spherical harmonic models up to degree/order 360
59
60
  - Multiple models: JGM2, JGM3, EGM96, ITU GRACE16
60
61
  - Efficient computation with configurable truncation order
61
62
  - Gravity gradient support for state transition matrix
62
63
  - **Third-Body Gravity**: Solar and lunar perturbations using JPL ephemerides
63
- - **Atmospheric Drag**: NRLMSISE-00 density model with space weather integration
64
+ - **Atmospheric Drag**:
65
+ - NRLMSISE-00 density model with space weather integration
64
66
  - Automatic space weather data updates (F10.7, Ap index)
65
67
  - Configurable ballistic coefficients
66
68
  - **Solar Radiation Pressure**: Cannon-ball model with shadow function
67
-
68
- ### Ephemerides
69
+
70
+ ### Solar System Ephemerides
69
71
  Access to high-precision solar system body positions:
70
72
  - **JPL DE440/DE441**: State-of-the-art planetary ephemerides
71
73
  - Chebyshev polynomial interpolation for accuracy
72
74
  - Support for all major planets, sun, moon, and solar system barycenter
73
75
  - **Low-Precision Models**: Fast analytical models for sun and moon when high precision isn't required
74
-
76
+
75
77
  ### Time Systems
76
78
  Comprehensive support for all standard astronomical time scales:
77
79
  - **UTC** - Coordinated Universal Time with leap second handling
@@ -81,7 +83,7 @@ Comprehensive support for all standard astronomical time scales:
81
83
  - **UT1** - Universal Time with Earth orientation corrections
82
84
  - **GPS** - GPS Time
83
85
  - Automatic conversion between all time scales with microsecond precision
84
-
86
+
85
87
  ### Geodetic Utilities
86
88
  - **Geodesic Calculations**: Accurate distance and azimuth between ground locations using Vincenty's formulae
87
89
  - **Coordinate Conversions**: ITRF ↔ Geodetic ↔ East-North-Up ↔ North-East-Down
@@ -134,12 +136,12 @@ The library requires external data files for various calculations. These are aut
134
136
  - DE440/DE441 planetary ephemerides (~100 MB)
135
137
  - Provides positions of sun, moon, planets, and solar system barycenter
136
138
  - Valid for years 1550-2650 CE
137
-
139
+
138
140
  - **Gravity Models** ([ICGEM](http://icgem.gfz-potsdam.de/home))
139
141
  - JGM2, JGM3, EGM96, ITU GRACE16 spherical harmonic coefficients
140
142
  - International Centre for Global Earth Models standardized format
141
143
  - Up to degree/order 360 for high-fidelity propagation
142
-
144
+
143
145
  - **IERS Nutation Tables** ([IERS Conventions](https://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.html))
144
146
  - IAU-2006 nutation series coefficients
145
147
  - Required for GCRF ↔ ITRF transformations
@@ -152,7 +154,7 @@ The library requires external data files for various calculations. These are aut
152
154
  - Ap geomagnetic index
153
155
  - Critical for atmospheric density modeling and drag calculations
154
156
  - Updated daily by NOAA Space Weather Prediction Center
155
-
157
+
156
158
  - **Earth Orientation Parameters** ([Celestrak](https://celestrak.org/SpaceData/))
157
159
  - Polar motion (x, y)
158
160
  - UT1-UTC time difference
@@ -174,15 +176,15 @@ The library includes comprehensive test suites ensuring correctness of calculati
174
176
  - **JPL Ephemerides**: Validated against JPL-provided test vectors for Chebyshev polynomial interpolation
175
177
  - Over 10,000 test cases covering all planets and time ranges
176
178
  - Accuracy verified to within JPL's published tolerances (sub-meter precision)
177
-
179
+
178
180
  - **SGP4**: Verified using official test vectors from the original C++ distribution
179
181
  - All test cases from Vallado's SGP4 implementation
180
182
  - Includes edge cases and error conditions
181
-
183
+
182
184
  - **Coordinate Transformations**: Cross-validated against multiple reference implementations
183
185
  - SOFA library comparisons for IAU-2006 transformations
184
186
  - Vallado test cases for GCRF ↔ ITRF conversions
185
-
187
+
186
188
  - **Numerical Propagation**: Validated against high-precision commercial tools
187
189
  - Orbit fits to GPS SP3 ephemerides
188
190
  - Multi-day propagations with sub-meter accuracy
@@ -222,7 +224,7 @@ pip install satkit
222
224
 
223
225
  Pre-built binary wheels are available for:
224
226
  - **Windows**: AMD64
225
- - **macOS**: Intel (x86_64) and Apple Silicon (ARM64)
227
+ - **macOS**: Intel (x86_64) and Apple Silicon (ARM64)
226
228
  - **Linux**: x86_64 and ARM64 (aarch64)
227
229
  - **Python versions**: 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
228
230
 
@@ -292,9 +294,9 @@ settings.gravity_order = 8
292
294
 
293
295
  # Propagate for 1 day
294
296
  result = sk.propagate(
295
- state0,
296
- time0,
297
- stop=time0 + sk.duration.from_days(1),
297
+ state0,
298
+ time0,
299
+ end=time0 + sk.duration.from_days(1),
298
300
  propsettings=settings
299
301
  )
300
302
 
@@ -331,13 +333,13 @@ use satkit::{Instant, SolarSystem, jplephem};
331
333
  fn main() -> Result<(), Box<dyn std::error::Error>> {
332
334
  // Create time instant
333
335
  let time = Instant::from_datetime(2024, 1, 1, 0, 0, 0.0)?;
334
-
336
+
335
337
  // Get Moon position and velocity in GCRF
336
338
  let (pos, vel) = jplephem::geocentric_state(SolarSystem::Moon, &time)?;
337
-
339
+
338
340
  println!("Moon position: {:?}", pos);
339
341
  println!("Moon velocity: {:?}", vel);
340
-
342
+
341
343
  Ok(())
342
344
  }
343
345
  ```
@@ -9,7 +9,7 @@ requires-python = ">= 3.8"
9
9
  authors = [{ name = "Steven Michael", email = "ssmichael@gmail.com" }]
10
10
  maintainers = [{ name = "Steven Michael", email = "ssmichael@gmail.com" }]
11
11
  readme = "README.md"
12
- version = "0.8.5"
12
+ version = "0.9.0"
13
13
  license = { file = "LICENSE" }
14
14
  description = "Satellite Orbital Dynamics Toolkit"
15
15
  keywords = [
@@ -37,6 +37,8 @@ classifiers = [
37
37
  "Programming Language :: Python :: 3.13",
38
38
  "Programming Language :: Python :: 3.14",
39
39
  ]
40
+ [project.optional-dependencies]
41
+ test = ["pytest", "xmltodict"]
40
42
 
41
43
 
42
44
  [tool.setuptools.packages.find]
@@ -69,7 +71,7 @@ before-build = [
69
71
  ]
70
72
  environment = { PATH = "$PATH:$HOME/.cargo/bin", MACOSX_DEPLOYMENT_TARGET = "10.12" }
71
73
  # Skip trying to test arm64 builds on Intel Macs
72
- test-requires = "pytest"
74
+ test-requires = "pytest xmltodict"
73
75
  test-command = [
74
76
  "SATKIT_DATA={package}/astro-data SATKIT_TESTVEC_ROOT={package}/satkit-testvecs pytest {project}/python/test/test.py",
75
77
  ]
@@ -83,7 +85,7 @@ before-build = [
83
85
  "curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y",
84
86
  "rustup show",
85
87
  ]
86
- test-requires = "pytest"
88
+ test-requires = "pytest xmltodict"
87
89
  test-command = [
88
90
  "SATKIT_DATA={package}/astro-data SATKIT_TESTVEC_ROOT={package}/satkit-testvecs pytest {project}/python/test/test.py",
89
91
  ]
@@ -98,7 +100,7 @@ before-build = [
98
100
  "rustup override set stable-x86_64-pc-windows-msvc",
99
101
  "rustup show",
100
102
  ]
101
- test-requires = "pytest"
103
+ test-requires = "pytest xmltodict"
102
104
  before-test = [
103
105
  "set SATKIT_DATA={package}\\astro-data",
104
106
  "set SATKIT_TESTVEC_ROOT={package}\\satkit-testvecs",
@@ -0,0 +1,118 @@
1
+ # SGP4, Two-Line Element Sets (TLEs), and Orbital Mean-Element Messages (OMMs)
2
+
3
+ ## Satellite Catalog
4
+
5
+ The United States maintains a public catalog of Earth-orbiting objects, including active satellites, rocket bodies, and debris.
6
+
7
+ There are multiple places to access the catalog, including:
8
+ * <https://www.celestrak.org/>
9
+ * <https://www.space-track.org/>
10
+
11
+ ## SGP4
12
+
13
+ **SGP4 (Simplified General Perturbations No. 4)** is an analytical orbital propagation model created in the **1960s–1970s by NORAD** to efficiently predict the motion of **Earth-orbiting satellites** from **Two-Line Element (TLE)** data.
14
+
15
+ It was developed to support U.S. space surveillance as a fast, closed-form alternative to numerical integration, modeling Earth’s oblateness (J2–J4), atmospheric drag via the TLE *B\** term, and key secular and periodic perturbations.
16
+
17
+ Today, SGP4 is the standard propagator for TLEs published by organizations like NORAD and CelesTrak, and is widely used for satellite tracking, visualization, conjunction screening, and mission planning—though its accuracy is fundamentally limited by TLE quality and simplifying assumptions.
18
+
19
+ ## Ephemeris Representation
20
+
21
+ ### TLE
22
+ A **Two-Line Element Set (TLE)** is a compact, legacy format (originally constrained by punch-card era line lengths) for describing satellite orbits. Despite its age, it remains widely used because it is easy to publish and often provides sufficient accuracy for many applications.
23
+
24
+ In addition to the familiar (mean) Keplerian elements, TLEs include parameters related to perturbations (e.g., atmospheric drag via $B^*$, and derivatives of mean motion).
25
+
26
+ TLEs are designed to be used with **SGP4**, an analytic model that produces orbital state vectors (position and velocity) from the augmented mean elements in the TLE. The perturbations modeled include Earth oblateness (which produces precession) and drag.
27
+
28
+ TLEs are often preceded by an additional “line 0” containing the satellite name. For an overview, see <https://en.wikipedia.org/wiki/Two-line_element_set>.
29
+
30
+ ### Orbital Mean-Element Messages
31
+ **Orbital Mean-Element Messages (OMMs)** are a more modern way of representing mean-element ephemerides. They are described by a CCSDS standard (<https://ccsds.org/Pubs/502x0b3e1.pdf>), although real-world sources may not adhere to the standard perfectly.
32
+
33
+ OMMs are commonly published as:
34
+ * JSON
35
+ * XML
36
+ * KVN (key–value notation)
37
+
38
+ The satkit Python interface does not load OMM files directly. Instead, it expects you to provide the decoded OMM as a Python `dict` (for example, parsed from JSON or XML). The interface supports OMM dictionary layouts produced by CelesTrak and Space-Track.
39
+
40
+
41
+
42
+
43
+ ## Example Usage
44
+
45
+ ### SGP4 state computation from TLE
46
+
47
+ ```python
48
+ import satkit as sk
49
+
50
+ # The two-line element set
51
+ # Let's pick a random Starlink satellite
52
+ # The lines below were downloaded from https://www.celestrak.org
53
+ tle_lines = [
54
+ '0 STARLINK-30477',
55
+ '1 57912U 23146X 24099.49439401 .00006757 00000+0 51475-3 0 9997',
56
+ '2 57912 43.0018 157.5807 0001420 272.5369 87.5310 15.02537576 31746'
57
+ ]
58
+
59
+ # Create a TLE object
60
+ starlink30477 = sk.TLE.from_lines(tle_lines)
61
+
62
+ # We want the orbital state at April 9 2024, 12:00pm UTC
63
+ thetime = sk.time(2024, 4, 9, 12, 0, 0)
64
+
65
+ # The state is output in the "TEME" frame, which is an approximate inertial
66
+ # frame that does not include precession or nutation
67
+ # pTEME is geocentric position in meters
68
+ # vTEME is geocentric velocity in meters / second
69
+ # for now we will ignore the velocity
70
+ pTEME, _vTEME = sk.sgp4(starlink30477, thetime)
71
+
72
+ # Suppose we want currrent latitude, longitude, and altitude of satellite:
73
+ # we need to rotate into an Earth-fixed frame, the ITRF
74
+ # We use a "quaternion" to represent the rotation. Quaternion rotations
75
+ # in the satkit toolbox can be represented as multiplications of a 3-vector
76
+ pITRF = sk.frametransform.qteme2itrf(thetime) * pTEME
77
+
78
+ # Now lets make a "ITRFCoord" object to extract geodetic coordinates
79
+ coord = sk.itrfcoord(pITRF)
80
+
81
+ # Get the latitude, longitude, and
82
+ # altitude (height above ellipsoid, or hae) of the satellite
83
+ print(coord)
84
+
85
+ # this should produce:
86
+ # ITRFCoord(lat: 29.3890 deg, lon: 170.8051 deg, hae: 560.11 km)
87
+
88
+ ```
89
+
90
+ ### SGP4 State Computation from OMM representation of International Space Station (ISS)
91
+
92
+ ```python
93
+
94
+ import satkit as sk
95
+ import requests
96
+ import json
97
+
98
+ # Query the current ephemeris for the International Space Station (ISS)
99
+ # from celestrak.org
100
+ url = 'https://celestrak.org/NORAD/elements/gp.php?CATNR=25544&FORMAT=json'
101
+ with requests.get(url) as response:
102
+ omm = response.json()
103
+
104
+ # Get a representative time from the output
105
+ epoch = sk.time(omm[0]['EPOCH'])
106
+ # create a list of times .. once every 10 minutes
107
+ time_array = [epoch + sk.duration(minutes=i*10) for i in range(6)]
108
+
109
+ # TEME (inertial) output from SGP4
110
+ pTEME, _vTEME = sk.sgp4(omm[0], time_array)
111
+
112
+ # Rotate to Earth-fixed
113
+ pITRF = [sk.frametransform.qteme2itrf(t) * p for t, p in zip(time_array, pTEME)]
114
+
115
+ # Geodetic coordinates of space station at given times
116
+ coord = [sk.itrfcoord(x) for x in pITRF]
117
+
118
+ ```
@@ -44,7 +44,7 @@
44
44
  "# Project the moon to the surface of the Earth along the Sun vector\n",
45
45
  "# This is projecting onto the surface of a sphere. However, the Earth is actually\n",
46
46
  "# an oblate spheroid. We can account for this by scaling the z axis by the flattening\n",
47
- "# of the Earth. \n",
47
+ "# of the Earth.\n",
48
48
  "scalefac = 1.0 / (1.0 - sk.consts.wgs84_f)\n",
49
49
  "moon_itrf_scaled = moon_itrf\n",
50
50
  "moon_itrf_scaled[:,2] = moon_itrf_scaled[:,2] * scalefac\n",
@@ -56,7 +56,7 @@
56
56
  "# via the law of Cosines and the quadratic equation\n",
57
57
  "lcostheta = np.sum(sun_itrf_scaled_hat * moon_itrf_scaled, axis=1)\n",
58
58
  "sqrtterm = lcostheta**2 - np.sum(moon_itrf_scaled**2, axis=1) + sk.consts.earth_radius**2\n",
59
- "# Valid indices (where the projection hits the earth) are where the term under \n",
59
+ "# Valid indices (where the projection hits the earth) are where the term under\n",
60
60
  "# the square root is positive\n",
61
61
  "vidx = np.argwhere(sqrtterm > 0).flatten()\n",
62
62
  "\n",
@@ -171,13 +171,13 @@
171
171
  "\n",
172
172
  " if len(eidx) > 0:\n",
173
173
  " data[\"total\"] = {\n",
174
- " \"start\": timearr[eidx[0][0]].datetime(), # type: ignore\n",
175
- " \"stop\": timearr[eidx[-1][0]].datetime(), # type: ignore\n",
174
+ " \"begin\": timearr[eidx[0][0]].datetime(), # type: ignore\n",
175
+ " \"end\": timearr[eidx[-1][0]].datetime(), # type: ignore\n",
176
176
  " \"duration_seconds\": (timearr[eidx[-1][0]] - timearr[eidx[0][0]]).seconds, # type: ignore\n",
177
177
  " }\n",
178
178
  " data[\"partial\"] = {\n",
179
- " \"start\": timearr[pidx[0][0]].datetime(),\n",
180
- " \"stop\": timearr[pidx[-1][0]].datetime(),\n",
179
+ " \"begin\": timearr[pidx[0][0]].datetime(),\n",
180
+ " \"end\": timearr[pidx[-1][0]].datetime(),\n",
181
181
  " \"duration_seconds\": (timearr[pidx[-1][0]] - timearr[pidx[0][0]]).seconds, # type: ignore\n",
182
182
  " \"peak\": None,\n",
183
183
  " \"minangle_deg\": None,\n",
@@ -208,10 +208,10 @@
208
208
  " max_frac_diam_occluded = 1 - (sun_extent_rad + mintheta - moon_extent_rad) / (\n",
209
209
  " 2 * sun_extent_rad\n",
210
210
  " )\n",
211
- " \n",
211
+ "\n",
212
212
  " data[\"partial\"] = {\n",
213
- " \"start\": timearr[pidx[0][0]].datetime(), # type: ignore\n",
214
- " \"stop\": timearr[pidx[-1][0]].datetime(), # type: ignore\n",
213
+ " \"begin\": timearr[pidx[0][0]].datetime(), # type: ignore\n",
214
+ " \"end\": timearr[pidx[-1][0]].datetime(), # type: ignore\n",
215
215
  " \"peak\": timearr[idx].datetime(), # type: ignore\n",
216
216
  " \"duration_seconds\": (timearr[pidx[-1][0]] - timearr[pidx[0][0]]).seconds, # type: ignore\n",
217
217
  " \"minangle_deg\": np.min(theta) * 180.0 / m.pi,\n",
@@ -266,11 +266,11 @@
266
266
  " [\n",
267
267
  " {\n",
268
268
  " \"Location\": loc[\"name\"],\n",
269
- " \"Total Eclipse Start\": loc[\"stats\"][\"total\"][\"start\"] if loc[\"stats\"][\"total\"] else None,\n",
270
- " \"Total Eclipse Stop\": loc[\"stats\"][\"total\"][\"stop\"] if loc[\"stats\"][\"total\"] else None,\n",
269
+ " \"Total Eclipse Begin\": loc[\"stats\"][\"total\"][\"begin\"] if loc[\"stats\"][\"total\"] else None,\n",
270
+ " \"Total Eclipse End\": loc[\"stats\"][\"total\"][\"end\"] if loc[\"stats\"][\"total\"] else None,\n",
271
271
  " \"Total Eclipse Duration (s)\": loc[\"stats\"][\"total\"][\"duration_seconds\"] if loc[\"stats\"][\"total\"] else None,\n",
272
- " \"Partial Eclipse Start\": loc[\"stats\"][\"partial\"][\"start\"] if loc[\"stats\"][\"partial\"] else None,\n",
273
- " \"Partial Eclipse Stop\": loc[\"stats\"][\"partial\"][\"stop\"] if loc[\"stats\"][\"partial\"] else None,\n",
272
+ " \"Partial Eclipse Begin\": loc[\"stats\"][\"partial\"][\"begin\"] if loc[\"stats\"][\"partial\"] else None,\n",
273
+ " \"Partial Eclipse End\": loc[\"stats\"][\"partial\"][\"end\"] if loc[\"stats\"][\"partial\"] else None,\n",
274
274
  " \"Partial Eclipse Peak\": loc[\"stats\"][\"partial\"][\"peak\"] if loc[\"stats\"][\"partial\"] else None,\n",
275
275
  " \"Partial Eclipse Duration (s)\": loc[\"stats\"][\"partial\"][\"duration_seconds\"] if loc[\"stats\"][\"partial\"] else None,\n",
276
276
  " \"Min Seperation (deg)\": loc[\"stats\"][\"partial\"][\"minangle_deg\"] if loc[\"stats\"][\"partial\"] else None,\n",
@@ -280,10 +280,10 @@
280
280
  " for loc in locations\n",
281
281
  " ]\n",
282
282
  ")\n",
283
- "df.style.format({\"Total Eclipse Start\": lambda x: x.strftime(\"%H:%M:%S\") if not pd.isnull(x) else 'N/A',\n",
284
- " \"Total Eclipse Stop\": lambda x: x.strftime(\"%H:%M:%S\") if not pd.isnull(x) else 'N/A',\n",
285
- " \"Partial Eclipse Start\": lambda x: x.strftime(\"%H:%M:%S\") if not pd.isnull(x) else 'N/A',\n",
286
- " \"Partial Eclipse Stop\": lambda x: x.strftime(\"%H:%M:%S\") if not pd.isnull(x) else 'N/A',\n",
283
+ "df.style.format({\"Total Eclipse Begin\": lambda x: x.strftime(\"%H:%M:%S\") if not pd.isnull(x) else 'N/A',\n",
284
+ " \"Total Eclipse End\": lambda x: x.strftime(\"%H:%M:%S\") if not pd.isnull(x) else 'N/A',\n",
285
+ " \"Partial Eclipse Begin\": lambda x: x.strftime(\"%H:%M:%S\") if not pd.isnull(x) else 'N/A',\n",
286
+ " \"Partial Eclipse End\": lambda x: x.strftime(\"%H:%M:%S\") if not pd.isnull(x) else 'N/A',\n",
287
287
  " \"Partial Eclipse Peak\": lambda x: x.strftime(\"%H:%M:%S\") if not pd.isnull(x) else 'N/A',\n",
288
288
  " \"Total Eclipse Duration (s)\": lambda x: f\"{x:.0f}\" if not pd.isnull(x) else 'N/A',\n",
289
289
  " \"Partial Eclipse Duration (s)\": lambda x: f\"{x:.0f}\" if not pd.isnull(x) else 'N/A',\n",
@@ -136,8 +136,8 @@
136
136
  "\n",
137
137
  " res = sk.propagate(\n",
138
138
  " np.concatenate((pgcrf[0, :], v[0:3])),\n",
139
- " start=tstart,\n",
140
- " stop=tend,\n",
139
+ " begin=tstart,\n",
140
+ " end=tend,\n",
141
141
  " propsettings=settings,\n",
142
142
  " satproperties=satprops,\n",
143
143
  " )\n",
@@ -157,8 +157,8 @@
157
157
  "satprops = sk.satproperties_static(craoverm = r.x[3])\n",
158
158
  "res = sk.propagate(\n",
159
159
  " np.concatenate((pgcrf[0, :], r.x[0:3])),\n",
160
- " start=timearr[0],\n",
161
- " stop=timearr[-1],\n",
160
+ " begin=timearr[0],\n",
161
+ " end=timearr[-1],\n",
162
162
  " propsettings=settings,\n",
163
163
  " satproperties=satprops,\n",
164
164
  ")\n",