astrox-python 1.0.0__tar.gz → 1.2.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 (353) hide show
  1. {astrox_python-1.0.0 → astrox_python-1.2.0}/.gitignore +4 -0
  2. {astrox_python-1.0.0 → astrox_python-1.2.0}/PKG-INFO +1 -1
  3. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/celestial.py +60 -4
  4. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/orbits.py +38 -6
  5. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/propagator.py +31 -0
  6. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/how_to/compute_lambert_transfer.md +10 -3
  7. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/how_to/propagate_an_orbit.md +3 -1
  8. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/how_to/compute_lambert_transfer.md +11 -3
  9. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/how_to/propagate_an_orbit.md +3 -1
  10. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/celestial/README.md +36 -15
  11. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/orbits/README.md +18 -2
  12. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/propagator/README.md +40 -1
  13. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/celestial/README.md +36 -15
  14. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/orbits/README.md +18 -2
  15. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/propagator/README.md +40 -1
  16. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/test-principles.md +2 -0
  17. astrox_python-1.2.0/docs/validation/celestial.md +70 -0
  18. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/libration.md +1 -1
  19. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/orbits.md +5 -3
  20. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/propagator.md +26 -0
  21. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/README.md +3 -1
  22. astrox_python-1.2.0/examples/01_propagation/two_body_rv.py +38 -0
  23. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/02_orbits/lambert_delta_v.py +14 -0
  24. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/11_celestial/celestial_queries.py +9 -3
  25. {astrox_python-1.0.0 → astrox_python-1.2.0}/pyproject.toml +2 -2
  26. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/celestial/test_celestial.py +144 -0
  27. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/orbits/test_conversions.py +95 -4
  28. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/propagator/test_public_contract.py +1 -0
  29. astrox_python-1.2.0/tests/sdk/propagator/test_two_body_rv.py +138 -0
  30. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/README.md +15 -0
  31. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/celestial/test_cb_axes_rotation_invariants.py +54 -2
  32. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/celestial/test_ephemeris_skyfield.py +59 -6
  33. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/celestial/test_lambert_transfer_lamberthub.py +262 -14
  34. astrox_python-1.2.0/tests/validation/cross_validation/celestial/test_mpc_target_elements.py +307 -0
  35. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/libration/test_e2m2e_qualification.py +2 -14
  36. astrox_python-1.2.0/tests/validation/cross_validation/orbits/test_lambert_path_points.py +172 -0
  37. astrox_python-1.2.0/tests/validation/cross_validation/propagator/test_two_body_rv_brahe.py +228 -0
  38. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/astrogator/test_run_mcs.py +4 -1
  39. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/celestial/celestial.snap.json +18 -3
  40. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/celestial/test_celestial.py +11 -3
  41. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/orbits/conversions.snap.json +28 -1
  42. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/orbits/test_conversions.py +16 -0
  43. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/test_two_body.py +22 -1
  44. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/two_body.snap.json +32 -1
  45. {astrox_python-1.0.0 → astrox_python-1.2.0}/uv.lock +35 -24
  46. astrox_python-1.0.0/docs/validation/celestial.md +0 -59
  47. {astrox_python-1.0.0 → astrox_python-1.2.0}/LICENSE +0 -0
  48. {astrox_python-1.0.0 → astrox_python-1.2.0}/README.md +0 -0
  49. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/__init__.py +0 -0
  50. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/_http.py +0 -0
  51. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/access.py +0 -0
  52. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/astrogator/__init__.py +0 -0
  53. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/astrogator/_api.py +0 -0
  54. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/astrogator/_models.py +0 -0
  55. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/astrogator/_results.py +0 -0
  56. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/cat.py +0 -0
  57. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/catalog.py +0 -0
  58. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/components/__init__.py +0 -0
  59. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/components/_axes.py +0 -0
  60. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/components/_common.py +0 -0
  61. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/components/_constraints.py +0 -0
  62. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/components/_objects.py +0 -0
  63. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/components/_positions.py +0 -0
  64. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/components/_rotations.py +0 -0
  65. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/components/_sensors.py +0 -0
  66. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/components/_vgt.py +0 -0
  67. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/conjunction.py +0 -0
  68. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/coverage/__init__.py +0 -0
  69. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/coverage/_core.py +0 -0
  70. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/coverage/_fom.py +0 -0
  71. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/coverage/coverage_time.py +0 -0
  72. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/coverage/number_of_assets.py +0 -0
  73. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/coverage/response_time.py +0 -0
  74. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/coverage/revisit_time.py +0 -0
  75. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/coverage/simple_coverage.py +0 -0
  76. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/exceptions.py +0 -0
  77. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/libration.py +0 -0
  78. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/lighting.py +0 -0
  79. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/rocket.py +0 -0
  80. {astrox_python-1.0.0 → astrox_python-1.2.0}/astrox/terrain.py +0 -0
  81. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/CONTRIBUTING.md +0 -0
  82. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/README.md +0 -0
  83. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/automated-workflows.md +0 -0
  84. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/docs-principles.md +0 -0
  85. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/getting_started.md +0 -0
  86. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/how_to/README.md +0 -0
  87. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/how_to/build_an_hpop_configuration.md +0 -0
  88. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/how_to/compute_access_intervals.md +0 -0
  89. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/how_to/compute_lighting_conditions.md +0 -0
  90. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/how_to/convert_between_orbit_representations.md +0 -0
  91. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/how_to/generate_a_crtbp_periodic_orbit.md +0 -0
  92. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/how_to/run_an_astrogator_mcs.md +0 -0
  93. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/how_to/screen_close_approaches.md +0 -0
  94. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/README.md +0 -0
  95. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/getting_started.md +0 -0
  96. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/how_to/README.md +0 -0
  97. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/how_to/build_an_hpop_configuration.md +0 -0
  98. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/how_to/compute_access_intervals.md +0 -0
  99. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/how_to/compute_lighting_conditions.md +0 -0
  100. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/how_to/convert_between_orbit_representations.md +0 -0
  101. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/how_to/generate_a_crtbp_periodic_orbit.md +0 -0
  102. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/how_to/run_an_astrogator_mcs.md +0 -0
  103. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/how_to/screen_close_approaches.md +0 -0
  104. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/README.md +0 -0
  105. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/access/README.md +0 -0
  106. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/astrogator/README.md +0 -0
  107. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/cat/README.md +0 -0
  108. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/catalog/README.md +0 -0
  109. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/components/README.md +0 -0
  110. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/conjunction/README.md +0 -0
  111. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/coverage/README.md +0 -0
  112. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/libration/README.md +0 -0
  113. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/lighting/README.md +0 -0
  114. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/rocket/README.md +0 -0
  115. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/i18n/en/manual/terrain/README.md +0 -0
  116. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/README.md +0 -0
  117. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/access/README.md +0 -0
  118. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/astrogator/README.md +0 -0
  119. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/cat/README.md +0 -0
  120. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/catalog/README.md +0 -0
  121. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/components/README.md +0 -0
  122. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/conjunction/README.md +0 -0
  123. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/coverage/README.md +0 -0
  124. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/libration/README.md +0 -0
  125. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/lighting/README.md +0 -0
  126. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/rocket/README.md +0 -0
  127. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/manual/terrain/README.md +0 -0
  128. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/sdk-principles.md +0 -0
  129. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/README.md +0 -0
  130. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/access.md +0 -0
  131. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/astrogator.md +0 -0
  132. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/cat.md +0 -0
  133. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/catalog.md +0 -0
  134. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/conjunction.md +0 -0
  135. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/coverage.md +0 -0
  136. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/lighting.md +0 -0
  137. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/rocket.md +0 -0
  138. {astrox_python-1.0.0 → astrox_python-1.2.0}/docs/validation/terrain.md +0 -0
  139. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/ballistic_apogee_alt.py +0 -0
  140. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/ballistic_delta_v.py +0 -0
  141. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/ballistic_min_ecc.py +0 -0
  142. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/ballistic_time_of_flight.py +0 -0
  143. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/batch_propagators.py +0 -0
  144. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/hpop.py +0 -0
  145. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/j2_classical.py +0 -0
  146. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/propagator_reference.py +0 -0
  147. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/sgp4_tle.py +0 -0
  148. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/simple_ascent.py +0 -0
  149. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/01_propagation/two_body_classical.py +0 -0
  150. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/02_orbits/README.md +0 -0
  151. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/02_orbits/conversions.py +0 -0
  152. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/02_orbits/orbit_system.py +0 -0
  153. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/02_orbits/wizards.py +0 -0
  154. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/03_lighting/README.md +0 -0
  155. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/03_lighting/lighting.py +0 -0
  156. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/04_access/README.md +0 -0
  157. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/04_access/chain.py +0 -0
  158. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/04_access/compute.py +0 -0
  159. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/04_access/constraints.py +0 -0
  160. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/04_access/custom_axes.py +0 -0
  161. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/04_access/sensor_pointing.py +0 -0
  162. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/05_rocket/README.md +0 -0
  163. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/05_rocket/landing_zone.py +0 -0
  164. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/06_coverage/README.md +0 -0
  165. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/06_coverage/compute.py +0 -0
  166. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/06_coverage/fom.py +0 -0
  167. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/06_coverage/grid_points.py +0 -0
  168. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/06_coverage/reports.py +0 -0
  169. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/07_astrogator/run_mcs.py +0 -0
  170. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/08_conjunction/README.md +0 -0
  171. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/08_conjunction/close_approaches.py +0 -0
  172. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/09_cat/README.md +0 -0
  173. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/09_cat/cat_workflows.py +0 -0
  174. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/10_catalog/README.md +0 -0
  175. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/10_catalog/catalog_queries.py +0 -0
  176. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/11_celestial/README.md +0 -0
  177. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/12_terrain/README.md +0 -0
  178. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/12_terrain/terrain_masks.py +0 -0
  179. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/13_libration/README.md +0 -0
  180. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/13_libration/libration_dynamics.py +0 -0
  181. {astrox_python-1.0.0 → astrox_python-1.2.0}/examples/manifest.toml +0 -0
  182. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/README.md +0 -0
  183. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/conftest.py +0 -0
  184. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/access/helpers.py +0 -0
  185. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/access/test_chain.py +0 -0
  186. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/access/test_compute.py +0 -0
  187. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/access/test_values.py +0 -0
  188. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/astrogator/test_api.py +0 -0
  189. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/astrogator/test_models.py +0 -0
  190. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/astrogator/test_results.py +0 -0
  191. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/cat/test_cat.py +0 -0
  192. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/catalog/test_catalog.py +0 -0
  193. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/client/test_client.py +0 -0
  194. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/components/test_components.py +0 -0
  195. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/conjunction/test_conjunction.py +0 -0
  196. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/coverage/test_coverage.py +0 -0
  197. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/coverage/test_coverage_fom.py +0 -0
  198. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/helpers.py +0 -0
  199. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/libration/test_libration.py +0 -0
  200. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/lighting/test_lighting.py +0 -0
  201. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/orbits/helpers.py +0 -0
  202. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/orbits/test_keplerian.py +0 -0
  203. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/orbits/test_orbit_system.py +0 -0
  204. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/orbits/test_tle.py +0 -0
  205. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/orbits/test_wizards.py +0 -0
  206. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/propagator/helpers.py +0 -0
  207. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/propagator/test_ballistic.py +0 -0
  208. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/propagator/test_hpop.py +0 -0
  209. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/propagator/test_j2_two_body.py +0 -0
  210. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/propagator/test_multi.py +0 -0
  211. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/propagator/test_sgp4_simple_ascent.py +0 -0
  212. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/rocket/__init__.py +0 -0
  213. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/rocket/test_rocket.py +0 -0
  214. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/sdk/terrain/test_terrain.py +0 -0
  215. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_external/gmat/README.md +0 -0
  216. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_external/gmat/hpop_driver.py +0 -0
  217. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_external/gmat/test_hpop_driver.py +0 -0
  218. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_support/__init__.py +0 -0
  219. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_support/contracts.py +0 -0
  220. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_support/external_tools.py +0 -0
  221. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_support/gmat.py +0 -0
  222. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_support/orekit.py +0 -0
  223. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_support/skyfield.py +0 -0
  224. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_support/test_contracts.py +0 -0
  225. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_support/test_external_tools.py +0 -0
  226. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_support/test_gmat.py +0 -0
  227. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/_support/test_skyfield.py +0 -0
  228. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/__init__.py +0 -0
  229. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/README.md +0 -0
  230. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/__init__.py +0 -0
  231. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/_aer.py +0 -0
  232. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/_cases.py +0 -0
  233. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/_constraints.py +0 -0
  234. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/_exclusion.py +0 -0
  235. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/_geometry.py +0 -0
  236. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/_mixed_model.py +0 -0
  237. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/_orientation.py +0 -0
  238. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_axes_orientation_geometry.py +0 -0
  239. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_chain_sgp4_skyfield.py +0 -0
  240. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_composite_czml_axes_geometry.py +0 -0
  241. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_compute_constraints_skyfield.py +0 -0
  242. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_compute_exclusion_constraints_invariants.py +0 -0
  243. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_compute_ground_sgp4_skyfield.py +0 -0
  244. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_compute_j2_two_body_geometry.py +0 -0
  245. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_compute_sgp4_j2_geometry.py +0 -0
  246. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_compute_site_hpop_geometry.py +0 -0
  247. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_compute_site_j2_geometry.py +0 -0
  248. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_compute_site_two_body_geometry.py +0 -0
  249. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_sensor_pointing_geometry.py +0 -0
  250. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/access/test_vgt_orientation_resolution.py +0 -0
  251. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/astrogator/__init__.py +0 -0
  252. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/astrogator/test_branch_semantics.py +0 -0
  253. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/astrogator/test_initial_state_conversions.py +0 -0
  254. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/astrogator/test_maneuver_invariants.py +0 -0
  255. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/astrogator/test_run_mcs_two_body_brahe.py +0 -0
  256. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/astrogator/test_scalar_invariants.py +0 -0
  257. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/astrogator/test_sequence_czml_brahe.py +0 -0
  258. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/astrogator/test_target_sequence_local.py +0 -0
  259. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/cat/test_cat_skyfield.py +0 -0
  260. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/conjunction/test_close_approaches_skyfield.py +0 -0
  261. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/_fom_helpers.py +0 -0
  262. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_exclusion_grid_constraints_skyfield.py +0 -0
  263. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_fom_at_time_boundaries_invariants.py +0 -0
  264. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_fom_edge_cases_invariants.py +0 -0
  265. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_fom_grid_options_invariants.py +0 -0
  266. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_fom_interval_invariants.py +0 -0
  267. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_fom_resource_options_invariants.py +0 -0
  268. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_fom_response_shapes_invariants.py +0 -0
  269. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_fom_response_time_dynamic_invariants.py +0 -0
  270. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_grid_generation_local.py +0 -0
  271. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_grid_point_modifiers_invariants.py +0 -0
  272. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_resource_reports_invariants.py +0 -0
  273. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/coverage/test_sgp4_grid_membership_skyfield.py +0 -0
  274. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/libration/_support.py +0 -0
  275. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/libration/test_cross_endpoint_consistency.py +0 -0
  276. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/libration/test_crtbp_trajectory.py +0 -0
  277. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/libration/test_fixed_x_correction.py +0 -0
  278. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/libration/test_orekit_qualification.py +0 -0
  279. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/libration/test_periodic_families.py +0 -0
  280. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/libration/test_positions_and_units.py +0 -0
  281. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/lighting/__init__.py +0 -0
  282. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/lighting/test_site_sun_skyfield.py +0 -0
  283. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/lighting/test_spacecraft_solar_intensity_orekit.py +0 -0
  284. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/lighting/test_spacecraft_sun_skyfield.py +0 -0
  285. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/orbit_system/__init__.py +0 -0
  286. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/orbit_system/_support.py +0 -0
  287. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/orbit_system/test_convert_czml_position.py +0 -0
  288. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/orbit_system/test_earth_moon_libration.py +0 -0
  289. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/orbits/__init__.py +0 -0
  290. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/orbits/test_kozai_izsak_mean_elements_invariants.py +0 -0
  291. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/orbits/test_lambert_lamberthub.py +0 -0
  292. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/orbits/test_walker_constellation_equations.py +0 -0
  293. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/orbits/test_wizards_local_derivation.py +0 -0
  294. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/propagator/test_ballistic_geodetic.py +0 -0
  295. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/propagator/test_hpop_gmat.py +0 -0
  296. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/propagator/test_j2_analytical.py +0 -0
  297. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/propagator/test_multi_sgp4_skyfield.py +0 -0
  298. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/propagator/test_sgp4_skyfield.py +0 -0
  299. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/propagator/test_simple_ascent_geodetic.py +0 -0
  300. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/propagator/test_two_body_brahe.py +0 -0
  301. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/rocket/__init__.py +0 -0
  302. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/rocket/test_landing_zone_geographiclib.py +0 -0
  303. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/cross_validation/terrain/test_terrain_mask_invariants.py +0 -0
  304. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/__init__.py +0 -0
  305. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/access/__init__.py +0 -0
  306. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/access/access.snap.json +0 -0
  307. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/access/test_access.py +0 -0
  308. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/access/test_chain_topology.py +0 -0
  309. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/access/test_compute_model_pairs.py +0 -0
  310. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/access/test_compute_options.py +0 -0
  311. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/astrogator/__init__.py +0 -0
  312. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/astrogator/run_mcs.snap.json +0 -0
  313. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/cat/cat.snap.json +0 -0
  314. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/cat/test_cat.py +0 -0
  315. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/catalog/catalog.snap.json +0 -0
  316. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/catalog/test_catalog.py +0 -0
  317. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/conjunction/close_approaches.snap.json +0 -0
  318. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/conjunction/test_close_approaches.py +0 -0
  319. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/coverage/coverage.snap.json +0 -0
  320. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/coverage/test_coverage.py +0 -0
  321. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/libration/libration.snap.json +0 -0
  322. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/libration/test_libration.py +0 -0
  323. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/lighting/__init__.py +0 -0
  324. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/lighting/lighting.snap.json +0 -0
  325. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/lighting/test_lighting.py +0 -0
  326. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/orbits/__init__.py +0 -0
  327. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/orbits/orbit_system.snap.json +0 -0
  328. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/orbits/test_conversion_roundtrip.py +0 -0
  329. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/orbits/test_orbit_system.py +0 -0
  330. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/orbits/test_wizards.py +0 -0
  331. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/orbits/wizards.snap.json +0 -0
  332. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/__init__.py +0 -0
  333. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/ballistic.snap.json +0 -0
  334. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/hpop.snap.json +0 -0
  335. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/j2.snap.json +0 -0
  336. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/multi_j2.snap.json +0 -0
  337. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/multi_sgp4.snap.json +0 -0
  338. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/multi_two_body.snap.json +0 -0
  339. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/sgp4.snap.json +0 -0
  340. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/simple_ascent.snap.json +0 -0
  341. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/test_ballistic.py +0 -0
  342. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/test_hpop.py +0 -0
  343. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/test_j2.py +0 -0
  344. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/test_multi_j2.py +0 -0
  345. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/test_multi_sgp4.py +0 -0
  346. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/test_multi_two_body.py +0 -0
  347. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/test_sgp4.py +0 -0
  348. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/propagator/test_simple_ascent.py +0 -0
  349. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/rocket/__init__.py +0 -0
  350. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/rocket/landing_zone.snap.json +0 -0
  351. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/rocket/test_landing_zone.py +0 -0
  352. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/terrain/terrain.snap.json +0 -0
  353. {astrox_python-1.0.0 → astrox_python-1.2.0}/tests/validation/live_snapshot/terrain/test_terrain.py +0 -0
@@ -11,9 +11,13 @@ wheels/
11
11
  # Virtual environments
12
12
  .venv
13
13
 
14
+ # Local-only server runtime for validation triage (never commit)
15
+ .local-runtime/
16
+
14
17
  # Internal & intermediate docs
15
18
  *.md
16
19
  !README.md
20
+ !AGENTS.md
17
21
  !docs/**/*.md
18
22
  docs/MAINTAINER_QUESTIONS.md
19
23
  !openapi/**/*.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: astrox-python
3
- Version: 1.0.0
3
+ Version: 1.2.0
4
4
  Summary: Python SDK for the ASTROX Web API.
5
5
  Project-URL: Homepage, https://github.com/Mtrya/astrox-python
6
6
  Project-URL: Repository, https://github.com/Mtrya/astrox-python.git
@@ -74,6 +74,9 @@ class MpcOrbitalElements:
74
74
  raan_deg: float | None = None
75
75
  argument_of_periapsis_deg: float | None = None
76
76
  mean_anomaly_deg: float | None = None
77
+ reference_frame: str | None = None
78
+ """Heliocentric mean-ecliptic variant: ``MeanEclpJ2000`` (JPL) or
79
+ ``EclpJ2000ICRF`` (MPC, server default)."""
77
80
 
78
81
  def __post_init__(self) -> None:
79
82
  for field_name in (
@@ -95,9 +98,14 @@ class MpcOrbitalElements:
95
98
  parameter=field_name,
96
99
  ),
97
100
  )
101
+ object.__setattr__(
102
+ self,
103
+ "reference_frame",
104
+ _optional_string(self.reference_frame, parameter="reference_frame"),
105
+ )
98
106
 
99
- def to_wire(self) -> dict[str, float]:
100
- payload: dict[str, float] = {}
107
+ def to_wire(self) -> dict[str, Any]:
108
+ payload: dict[str, Any] = {}
101
109
  _include_if_supplied(payload, "EpochMjdTdt", self.epoch_mjd_tdt)
102
110
  _include_if_supplied(payload, "PeriTimeMjdTdt", self.periapsis_time_mjd_tdt)
103
111
  _include_if_supplied(payload, "Q", self.periapsis_distance_au)
@@ -111,6 +119,7 @@ class MpcOrbitalElements:
111
119
  self.argument_of_periapsis_deg,
112
120
  )
113
121
  _include_if_supplied(payload, "MeanAnomaly", self.mean_anomaly_deg)
122
+ _include_if_supplied(payload, "ReferenceFrame", self.reference_frame)
114
123
  return payload
115
124
 
116
125
 
@@ -125,6 +134,7 @@ def mpc_orbital_elements(
125
134
  raan_deg: float | None = None,
126
135
  argument_of_periapsis_deg: float | None = None,
127
136
  mean_anomaly_deg: float | None = None,
137
+ reference_frame: str | None = None,
128
138
  ) -> MpcOrbitalElements:
129
139
  """Build an MPC orbital-element fragment without adding physics policy."""
130
140
  return MpcOrbitalElements(
@@ -137,6 +147,7 @@ def mpc_orbital_elements(
137
147
  raan_deg=raan_deg,
138
148
  argument_of_periapsis_deg=argument_of_periapsis_deg,
139
149
  mean_anomaly_deg=mean_anomaly_deg,
150
+ reference_frame=reference_frame,
140
151
  )
141
152
 
142
153
 
@@ -153,7 +164,7 @@ def _elements_to_wire(
153
164
  value: MpcOrbitalElements | None,
154
165
  *,
155
166
  parameter: str,
156
- ) -> dict[str, float] | None:
167
+ ) -> dict[str, Any] | None:
157
168
  if value is None:
158
169
  return None
159
170
  if not isinstance(value, MpcOrbitalElements):
@@ -175,6 +186,9 @@ def lambert_transfer_window(
175
186
  arrival_step_days: float | None = None,
176
187
  departure_elements: MpcOrbitalElements | None = None,
177
188
  arrival_elements: MpcOrbitalElements | None = None,
189
+ max_departure_delta_v_m_s: int | None = None,
190
+ max_arrival_delta_v_m_s: int | None = None,
191
+ max_time_of_flight_days: int | None = None,
178
192
  ) -> dict[str, Any]:
179
193
  """Return a Lambert transfer-window scan from ASTROX.
180
194
 
@@ -236,6 +250,30 @@ def lambert_transfer_window(
236
250
  "ArrivalElements",
237
251
  _elements_to_wire(arrival_elements, parameter="arrival_elements"),
238
252
  )
253
+ _include_if_supplied(
254
+ payload,
255
+ "MaxDepartureDV",
256
+ _optional_integer(
257
+ max_departure_delta_v_m_s,
258
+ parameter="max_departure_delta_v_m_s",
259
+ ),
260
+ )
261
+ _include_if_supplied(
262
+ payload,
263
+ "MaxArrivalDV",
264
+ _optional_integer(
265
+ max_arrival_delta_v_m_s,
266
+ parameter="max_arrival_delta_v_m_s",
267
+ ),
268
+ )
269
+ _include_if_supplied(
270
+ payload,
271
+ "MaxTofDays",
272
+ _optional_integer(
273
+ max_time_of_flight_days,
274
+ parameter="max_time_of_flight_days",
275
+ ),
276
+ )
239
277
  return _without_status_fields(
240
278
  raw.post("/celestial/transfer", json=payload),
241
279
  endpoint="/celestial/transfer",
@@ -331,8 +369,16 @@ def mpc_ephemeris(
331
369
  observer_frame: str | None = None,
332
370
  start: str | None = None,
333
371
  stop: str | None = None,
372
+ step_s: float | None = None,
373
+ target_elements: MpcOrbitalElements | None = None,
334
374
  ) -> dict[str, Any]:
335
- """Return ASTROX minor-planet ephemeris output from its MPC-backed route."""
375
+ """Return ASTROX minor-planet ephemeris output from its MPC-backed route.
376
+
377
+ When ``target_elements`` is supplied, the server integrates those MPC
378
+ orbital elements directly instead of resolving ``target_name`` through the
379
+ MPC network query. ``step_s`` controls the output sampling cadence; zero
380
+ requests the server's internal integration grid.
381
+ """
336
382
  payload: dict[str, Any] = {
337
383
  "TargetName": _string(target_name, parameter="target_name"),
338
384
  }
@@ -351,6 +397,16 @@ def mpc_ephemeris(
351
397
  "Stop",
352
398
  _optional_string(stop, parameter="stop"),
353
399
  )
400
+ _include_if_supplied(
401
+ payload,
402
+ "Step",
403
+ _optional_number(step_s, parameter="step_s"),
404
+ )
405
+ _include_if_supplied(
406
+ payload,
407
+ "TargetElements",
408
+ _elements_to_wire(target_elements, parameter="target_elements"),
409
+ )
354
410
  return _without_status_fields(
355
411
  raw.post("/celestial/mpc", json=payload),
356
412
  endpoint="/celestial/mpc",
@@ -11,6 +11,7 @@ from astrox._http import raw
11
11
  __all__ = [
12
12
  "CartesianState",
13
13
  "KeplerianElements",
14
+ "LambertResult",
14
15
  "MeanKeplerianElements",
15
16
  "Tle",
16
17
  "cartesian_state",
@@ -517,14 +518,37 @@ def geo_ym_lambert_delta_v(
517
518
  )
518
519
 
519
520
 
521
+ @dataclass(frozen=True, kw_only=True)
522
+ class LambertResult:
523
+ """Single-case Lambert solution with the sampled transfer positions."""
524
+
525
+ departure_delta_v_m_s: tuple[float, float, float]
526
+ arrival_delta_v_m_s: tuple[float, float, float]
527
+ positions: tuple[float, ...]
528
+ """Flat ``(x, y, z, ...)`` transfer position sequence in meters.
529
+
530
+ The server samples ``path_point_count`` points including the departure and
531
+ arrival positions, so the sequence length is ``path_point_count * 3``.
532
+ """
533
+
534
+
520
535
  def lambert_delta_v(
521
536
  *,
522
537
  departure_state: CartesianState,
523
538
  arrival_state: CartesianState,
524
539
  time_of_flight_s: float,
525
540
  gravitational_parameter_m3_s2: float | None = None,
526
- ) -> tuple[tuple[float, float, float], tuple[float, float, float]]:
527
- """Return single-revolution Lambert delta-v between two Cartesian states."""
541
+ get_path_points: bool = False,
542
+ path_point_count: int | None = None,
543
+ ) -> tuple[tuple[float, float, float], tuple[float, float, float]] | LambertResult:
544
+ """Return single-revolution Lambert delta-v between two Cartesian states.
545
+
546
+ By default returns ``(departure_delta_v_m_s, arrival_delta_v_m_s)``. When
547
+ ``get_path_points`` is true, the server also samples the transfer orbit and
548
+ the return is a :class:`LambertResult` carrying the delta-v pair plus the
549
+ flat position sequence; ``path_point_count`` sets the sample count
550
+ (server default 100, including both endpoints).
551
+ """
528
552
  if not isinstance(departure_state, CartesianState):
529
553
  raise TypeError("departure_state must be a CartesianState instance")
530
554
  if not isinstance(arrival_state, CartesianState):
@@ -536,12 +560,20 @@ def lambert_delta_v(
536
560
  "TOF": [time_of_flight_s],
537
561
  }
538
562
  _include_if_supplied(payload, "Gm", gravitational_parameter_m3_s2)
563
+ if get_path_points:
564
+ payload["GetPathPoints"] = True
565
+ _include_if_supplied(payload, "NumberOfPathPoints", path_point_count)
539
566
 
540
567
  result = raw.post("/orbit/lambert", json=payload)
541
- return (
542
- (result["DV1"][0], result["DV1"][1], result["DV1"][2]),
543
- (result["DV2"][0], result["DV2"][1], result["DV2"][2]),
544
- )
568
+ departure_delta_v = (result["DV1"][0], result["DV1"][1], result["DV1"][2])
569
+ arrival_delta_v = (result["DV2"][0], result["DV2"][1], result["DV2"][2])
570
+ if get_path_points:
571
+ return LambertResult(
572
+ departure_delta_v_m_s=departure_delta_v,
573
+ arrival_delta_v_m_s=arrival_delta_v,
574
+ positions=tuple(result["Positions"]),
575
+ )
576
+ return departure_delta_v, arrival_delta_v
545
577
 
546
578
 
547
579
  def convert_czml_position(
@@ -42,6 +42,7 @@ __all__ = [
42
42
  "sgp4",
43
43
  "simple_ascent",
44
44
  "two_body",
45
+ "two_body_rv",
45
46
  ]
46
47
 
47
48
 
@@ -672,6 +673,36 @@ def two_body(
672
673
  return _success_path(result)
673
674
 
674
675
 
676
+ def two_body_rv(
677
+ *,
678
+ state: CartesianState,
679
+ time_of_flight_s: float,
680
+ gravitational_parameter_m3_s2: float | None = None,
681
+ step_s: float | None = None,
682
+ ) -> tuple[float, ...]:
683
+ """Propagate a Cartesian state with two-body dynamics and return the sampled ephemeris.
684
+
685
+ Returns the flat ``[t, x, y, z, vx, vy, vz, ...]`` sequence, where ``t`` is
686
+ seconds relative to the initial epoch, positions are in meters, and
687
+ velocities are in m/s. The sequence includes the start and stop samples;
688
+ intermediate samples follow ``step_s`` (server default 60 s).
689
+ """
690
+ if not isinstance(state, CartesianState):
691
+ raise TypeError("state must be a CartesianState instance")
692
+
693
+ payload: dict[str, Any] = {
694
+ "RV0": state.to_wire(),
695
+ "TimeOfFlight": time_of_flight_s,
696
+ }
697
+ if gravitational_parameter_m3_s2 is not None:
698
+ payload["Gm"] = gravitational_parameter_m3_s2
699
+ if step_s is not None:
700
+ payload["Step"] = step_s
701
+
702
+ result = raw.post("/Propagator/TwoBodyRV", json=payload)
703
+ return tuple(result["Positions"])
704
+
705
+
675
706
  def j2(
676
707
  *,
677
708
  start: str,
@@ -23,6 +23,9 @@ transfer = celestial.lambert_transfer_window(
23
23
  min_time_of_flight_days=10,
24
24
  departure_step_days=2.0,
25
25
  arrival_step_days=1.0,
26
+ # 该窗口出发双曲超速约 15 km/s,超出服务端 MaxDepartureDV 缺省值
27
+ # (10000 m/s),需要显式放宽上限才能保留结果
28
+ max_departure_delta_v_m_s=20000,
26
29
  )
27
30
 
28
31
  results = transfer["TransferResults"]
@@ -32,7 +35,8 @@ for result in results:
32
35
  print(
33
36
  f"出发 {result['DepartureTime']} → 到达 {result['ArrivalTime']}: "
34
37
  f"|DeltaV1|={result['DV1_Mag']:.1f} m/s, "
35
- f"|DeltaV2|={result['DV2_Mag']:.1f} m/s"
38
+ f"|DeltaV2|={result['DV2_Mag']:.1f} m/s, "
39
+ f"TOF={result['TimeOfFlightDays']:.0f} d"
36
40
  )
37
41
  ```
38
42
 
@@ -47,14 +51,17 @@ python compute_lambert_transfer.py
47
51
  1. **选出发与到达天体**:`departure_body`/`arrival_body` 接受服务端支持的天体名称(如 `Earth`、`Mars`、`Ceres`)以及 MPC 编号或名称(如 `2015 XF261`)。小行星省略对应的 `*_elements` 参数时,服务端通过网络查询 MPC 根数。
48
52
  2. **定两个时间窗口**:`departure_start`/`departure_stop` 与 `arrival_start`/`arrival_stop` 各定义一个 UTC 时间窗口,SDK 分别组合为 `DepartureInterval`/`ArrivalInterval` 的 `"开始/结束"` 字符串。`departure_step_days` 与 `arrival_step_days`(单位 d)控制窗口内的采样步长,结果个数约等于两个窗口采样点数的乘积;示例中的 2 个出发日 × 3 个到达日产生 6 条结果。`min_time_of_flight_days`(单位 d,整数)过滤掉转移时间太短的组合,服务端缺省 10。
49
53
  3. **选输出参考系**:`sun_frame` 服务端缺省 `MeanEclpJ2000`;`ICRF` 分支的转移速度已与独立零圈顺行 Lambert 解一致,端点位置方向也已识别为 ICRF 轴方向,而 `MeanEclpJ2000` 与 ICRF 的精确关系尚未独立确认,需要参考系明确的数值时建议显式传 `sun_frame="ICRF"`。
54
+ 4. **按需调整过滤上限**:2026-08-20 起服务端按 `max_departure_delta_v_m_s`/`max_arrival_delta_v_m_s`(缺省各 10000 m/s,分别对应出发/到达双曲超速大小)与 `max_time_of_flight_days`(缺省 500 d)过滤算例,全部超界时返回空列表;扫描大 ΔV 或超长转移窗口时需显式放宽,示例中的 Earth→Mars 窗口就属于这种情况。
50
55
 
51
56
  ## 读懂结果
52
57
 
53
58
  每个结果对象包含:
54
59
 
55
60
  - `DepartureTime`/`ArrivalTime`:出发/到达时刻(UTC 字符串)。
56
- - `DeltaV1`/`DeltaV2`:出发/到达速度增量向量(m/s);`DV1_Mag`/`DV2_Mag` 是它们的欧几里得范数(m/s)。`DeltaV` 相对端点天体速度的物理含义尚未独立确认,需要严格物理解释时请先核对。
61
+ - `DeltaV1`/`DeltaV2`:出发/到达速度增量向量(出发/到达双曲超速矢量,m/s);`DV1_Mag`/`DV2_Mag` 是它们的欧几里得范数(m/s)。`DeltaV` 相对端点天体速度的物理含义尚未独立确认,需要严格物理解释时请先核对。
57
62
  - `RV1`/`RV2`:出发/到达时的日心位置速度 `[x, y, z, vx, vy, vz]`(位置 m、速度 m/s);ICRF 分支下转移速度与独立 Lambert 解一致,端点位置方向与 ICRF 轴方向一致。
63
+ - `TimeOfFlightDays`:飞行时间(d),已验证为到达与出发时刻的精确天数差。
64
+ - `ArrivalLightAngle`:到达时刻太阳光照角(deg),已验证为 `DeltaV2` 与 `RV2` 位置矢量的夹角。
58
65
 
59
66
  ## 小行星与显式 MPC 根数
60
67
 
@@ -84,7 +91,7 @@ transfer = celestial.lambert_transfer_window(
84
91
  )
85
92
  ```
86
93
 
87
- 注意:显式 MPC 根数的独立开普勒递推尚未验证,元素系、参考系与时间约定未确认;这个分支可调用、响应结构已由 live 快照记录,但数值语义请自行核对。
94
+ 注意:显式 MPC 根数在转移路由中的独立开普勒递推尚未验证,元素系与时间约定未确认(`reference_frame` 选项不改变该路由的到达状态);这个分支可调用、响应结构已由 live 快照记录,但数值语义请自行核对。`mpc_ephemeris` 的 `target_elements` 分支已验证(见天体手册)。
88
95
 
89
96
  ## 了解更多
90
97
 
@@ -6,9 +6,10 @@
6
6
 
7
7
  1. **输入决定传播器**:
8
8
  - 有开普勒根数 → 用 `propagator.j2` 或 `propagator.two_body`。
9
+ - 有笛卡尔位置速度状态 → 用 `propagator.two_body_rv`(纯二体,返回扁平星历序列,不返回 `(period_s, position)`)。
9
10
  - 有两行根数(TLE) → 用 `propagator.sgp4`。
10
11
  - 有力模型配置 → 用 `propagator.hpop`。
11
- 2. **读取采样**:所有单轨传播函数都返回 `(period_s, position)`,其中 `position.cartesian_velocity` 是 CZML 风格的扁平序列 `[t, x, y, z, vx, vy, vz, ...]`。
12
+ 2. **读取采样**:除 `two_body_rv` 外,所有单轨传播函数都返回 `(period_s, position)`,其中 `position.cartesian_velocity` 是 CZML 风格的扁平序列 `[t, x, y, z, vx, vy, vz, ...]`。
12
13
 
13
14
  ## 完整示例
14
15
 
@@ -139,6 +140,7 @@ HPOP 传播
139
140
  | --- | --- | --- |
140
141
  | 开普勒根数 | `propagator.j2` | 考虑 J2 摄动,适合大多数低轨任务。 |
141
142
  | 开普勒根数,纯二体 | `propagator.two_body` | 只考虑中心天体引力,计算最快。 |
143
+ | 笛卡尔位置速度状态 | `propagator.two_body_rv` | 定步长数值二体积分,返回扁平星历序列 `[t, x, y, z, vx, vy, vz, ...]`。 |
142
144
  | 两行根数(TLE) | `propagator.sgp4` | 直接从 TLE 传播,无需手动构造根数。 |
143
145
  | 需要配置力模型 | `propagator.hpop` | 支持重力场、大气、太阳辐射压、第三方天体摄动等配置。 |
144
146
 
@@ -23,6 +23,10 @@ transfer = celestial.lambert_transfer_window(
23
23
  min_time_of_flight_days=10,
24
24
  departure_step_days=2.0,
25
25
  arrival_step_days=1.0,
26
+ # this window's departure hyperbolic excess speed is about 15 km/s, above
27
+ # the server MaxDepartureDV default (10000 m/s); widen the bound explicitly
28
+ # to keep the results
29
+ max_departure_delta_v_m_s=20000,
26
30
  )
27
31
 
28
32
  results = transfer["TransferResults"]
@@ -32,7 +36,8 @@ for result in results:
32
36
  print(
33
37
  f"Departure {result['DepartureTime']} → arrival {result['ArrivalTime']}: "
34
38
  f"|DeltaV1|={result['DV1_Mag']:.1f} m/s, "
35
- f"|DeltaV2|={result['DV2_Mag']:.1f} m/s"
39
+ f"|DeltaV2|={result['DV2_Mag']:.1f} m/s, "
40
+ f"TOF={result['TimeOfFlightDays']:.0f} d"
36
41
  )
37
42
  ```
38
43
 
@@ -47,14 +52,17 @@ python compute_lambert_transfer.py
47
52
  1. **Choose the departure and arrival bodies**: `departure_body`/`arrival_body` accept server-supported body names (e.g. `Earth`, `Mars`, `Ceres`) and MPC numbers or names (e.g. `2015 XF261`). When the matching `*_elements` argument is omitted for an asteroid, the server queries the MPC elements over the network.
48
53
  2. **Set the two time windows**: `departure_start`/`departure_stop` and `arrival_start`/`arrival_stop` each define a UTC time window, which the SDK combines into the `"start/stop"` string of `DepartureInterval`/`ArrivalInterval` respectively. `departure_step_days` and `arrival_step_days` (unit d) control the sample step within each window; the number of results is roughly the product of the two windows' sample counts — the 2 departure days × 3 arrival days in the example produce 6 results. `min_time_of_flight_days` (unit d, integer) filters out combinations whose transfer time is too short; the server default is 10.
49
54
  3. **Choose the output reference frame**: the server default for `sun_frame` is `MeanEclpJ2000`; the transfer velocities of the `ICRF` branch agree with an independent zero-revolution prograde Lambert solution, and the endpoint position directions have also been identified as ICRF axes, while the exact relationship between `MeanEclpJ2000` and ICRF is not yet independently confirmed, so pass `sun_frame="ICRF"` explicitly when you need numbers with an identified frame.
55
+ 4. **Adjust the filter bounds as needed**: since 2026-08-20 the server filters cases by `max_departure_delta_v_m_s`/`max_arrival_delta_v_m_s` (defaults 10000 m/s each, the departure/arrival hyperbolic excess speed magnitudes) and `max_time_of_flight_days` (default 500 d), returning an empty list when everything is out of bounds; widen the bounds explicitly when scanning large-ΔV or very long transfer windows — the Earth→Mars window in the example is such a case.
50
56
 
51
57
  ## Reading the results
52
58
 
53
59
  Each result object contains:
54
60
 
55
61
  - `DepartureTime`/`ArrivalTime`: departure/arrival times (UTC strings).
56
- - `DeltaV1`/`DeltaV2`: departure/arrival velocity-increment vectors (m/s); `DV1_Mag`/`DV2_Mag` are their Euclidean norms (m/s). The physical meaning of `DeltaV` relative to the endpoint bodies' velocities is not yet independently confirmed, so verify it yourself when you need a strict physical interpretation.
62
+ - `DeltaV1`/`DeltaV2`: departure/arrival velocity-increment vectors (departure/arrival hyperbolic excess velocity vectors, m/s); `DV1_Mag`/`DV2_Mag` are their Euclidean norms (m/s). The physical meaning of `DeltaV` relative to the endpoint bodies' velocities is not yet independently confirmed, so verify it yourself when you need a strict physical interpretation.
57
63
  - `RV1`/`RV2`: heliocentric position and velocity at departure/arrival `[x, y, z, vx, vy, vz]` (positions m, velocities m/s); under the ICRF branch the transfer velocities agree with the independent Lambert solution, and the endpoint position directions match the ICRF axes.
64
+ - `TimeOfFlightDays`: time of flight (d), verified to be the exact day difference between the arrival and departure times.
65
+ - `ArrivalLightAngle`: Sun lighting angle at arrival (deg), verified to be the angle between `DeltaV2` and the `RV2` position vector.
58
66
 
59
67
  ## Asteroids and explicit MPC elements
60
68
 
@@ -84,7 +92,7 @@ transfer = celestial.lambert_transfer_window(
84
92
  )
85
93
  ```
86
94
 
87
- Note: independent Kepler propagation of explicit MPC elements is not yet verified, and the element system, reference frame, and time convention are unconfirmed; this branch is callable and its response structure is recorded by live snapshots, but verify the numeric semantics yourself.
95
+ Note: independent Kepler propagation of explicit MPC elements in the transfer route is not yet verified, and the element system and time convention are unconfirmed (the `reference_frame` option does not change the arrival states of that route); this branch is callable and its response structure is recorded by live snapshots, but verify the numeric semantics yourself. The `target_elements` branch of `mpc_ephemeris` is verified (see the celestial manual).
88
96
 
89
97
  ## Learn more
90
98
 
@@ -6,9 +6,10 @@ This page solves a specific task: choose the right propagator from the orbit des
6
6
 
7
7
  1. **Input determines the propagator**:
8
8
  - You have Keplerian elements → use `propagator.j2` or `propagator.two_body`.
9
+ - You have a Cartesian position/velocity state → use `propagator.two_body_rv` (pure two-body; returns a flat ephemeris sequence, not `(period_s, position)`).
9
10
  - You have a two-line element set (TLE) → use `propagator.sgp4`.
10
11
  - You have a force model config → use `propagator.hpop`.
11
- 2. **Reading the samples**: all single-orbit propagation functions return `(period_s, position)`, where `position.cartesian_velocity` is a CZML-style flat sequence `[t, x, y, z, vx, vy, vz, ...]`.
12
+ 2. **Reading the samples**: except for `two_body_rv`, all single-orbit propagation functions return `(period_s, position)`, where `position.cartesian_velocity` is a CZML-style flat sequence `[t, x, y, z, vx, vy, vz, ...]`.
12
13
 
13
14
  ## Complete example
14
15
 
@@ -139,6 +140,7 @@ Every 7 numbers in `cartesian_velocity` form one frame: time offset (seconds), p
139
140
  | --- | --- | --- |
140
141
  | Keplerian elements | `propagator.j2` | Includes J2 perturbation; suitable for most LEO missions. |
141
142
  | Keplerian elements, pure two-body | `propagator.two_body` | Only central-body gravity; fastest computation. |
143
+ | Cartesian position/velocity state | `propagator.two_body_rv` | Fixed-step numerical two-body integration; returns a flat ephemeris sequence `[t, x, y, z, vx, vy, vz, ...]`. |
142
144
  | Two-line element set (TLE) | `propagator.sgp4` | Propagates directly from TLE; no need to build elements manually. |
143
145
  | Need to configure a force model | `propagator.hpop` | Supports gravity field, atmosphere, solar radiation pressure, third-body perturbations, and more. |
144
146
 
@@ -32,7 +32,7 @@ Computes an ephemeris for a target body over a time window and returns a raw JSO
32
32
  | `start` | `Start` | Analysis start time (UTC, `yyyy-MM-ddTHH:mm:ssZ`). Optional; the server default is January 1 of the current year |
33
33
  | `stop` | `Stop` | Analysis stop time (UTC). Optional; the server default is December 31 of the current year |
34
34
  | `observer_name` | `ObserverName` | Observer name, e.g. `Earth`; the server default is `Sun` |
35
- | `observer_frame` | `ObserverFrame` | Observer frame, server options `FIXED`, `INERTIAL`, `MeanEclpJ2000`, `J2000`, default `MeanEclpJ2000` |
35
+ | `observer_frame` | `ObserverFrame` | Observer frame; the server currently accepts `FIXED`, `INERTIAL`, `MeanEclpJ2000`, `EclpJ2000ICRF`, `J2000`, and `ICRF`; default `MeanEclpJ2000` |
36
36
  | `step_s` | `Step` | Sample step, in s, server default 86400 s |
37
37
 
38
38
  `target_name` is the only required request field of this function; `start` and `stop` are optional — when omitted they are not sent to ASTROX and the server selects January 1 to December 31 of the current year as the window. Other optional fields that are not supplied are likewise not sent to ASTROX, and the server retains its default values.
@@ -43,7 +43,7 @@ from astrox import celestial
43
43
  start = "2026-01-01T00:00:00.000Z"
44
44
  stop = "2026-01-02T00:00:00.000Z"
45
45
 
46
- for frame in ("J2000", "MeanEclpJ2000"):
46
+ for frame in ("J2000", "MeanEclpJ2000", "EclpJ2000ICRF"):
47
47
  ephemeris = celestial.ephemeris(
48
48
  target_name="Moon",
49
49
  start=start,
@@ -81,11 +81,11 @@ Computes the rotation from the coordinate axes of the source central body to tho
81
81
  | `from_central_body` | `FromCbName` | Source central body name, e.g. `Earth` |
82
82
  | `to_central_body` | `ToCbName` | Target central body name, e.g. `Moon` |
83
83
  | `epoch` | `Epoch` | Epoch time (UTC) |
84
- | `from_frame` | `FromCbFrame` | Source frame, server options `FIXED`, `INERTIAL`, `J2000`, `ICRF`, `MeanEclpJ2000`, default `INERTIAL` |
84
+ | `from_frame` | `FromCbFrame` | Source frame, server options `FIXED`, `INERTIAL`, `J2000`, `ICRF`, `MeanEclpJ2000`, `EclpJ2000ICRF`, default `INERTIAL` |
85
85
  | `to_frame` | `ToCbFrame` | Target frame, same options, default `FIXED` |
86
86
  | `order` | `Order` | Rotation motion order: `0` returns the quaternion only, `1` returns the quaternion and angular velocity; passed through as an integer |
87
87
 
88
- `order` is preserved as an integer and lowered to the server as-is; the SDK does not rewrite the branch. The `Rotation` field of the response is a numeric array: with `order=0` it has length 4 (quaternion `[qx, qy, qz, qw]`), and with `order=1` it has length 7 (quaternion plus angular-velocity components, unit rad/s per the server documentation). Verified numeric semantics include: for the same central body on both sides with `INERTIAL` frames on both sides, the server returns the identity quaternion with zero angular velocity at `order=1`; the Earth `INERTIAL`→`FIXED` quaternion and angular velocity; and the Earth→Moon `INERTIAL`→`FIXED` angular velocity at `order=1`. The Earth→Moon `INERTIAL`→`FIXED` quaternion is unresolved, and other combinations are unverified, so verify their meaning yourself before use.
88
+ `order` is preserved as an integer and lowered to the server as-is; the SDK does not rewrite the branch. The `Rotation` field of the response is a numeric array: with `order=0` it has length 4 (quaternion `[qx, qy, qz, qw]`), and with `order=1` it has length 7 (quaternion plus angular-velocity components, unit rad/s per the server documentation). Verified numeric semantics include: for the same central body on both sides with `INERTIAL` frames on both sides, the server returns the identity quaternion with zero angular velocity at `order=1`; Earth→Earth `EclpJ2000ICRF`→`ICRF` follows the fixed J2000 mean-obliquity rotation with zero angular velocity at the two maintained epochs and `order=0/1`; the Earth `INERTIAL`→`FIXED` quaternion and angular velocity; and the Earth→Moon `INERTIAL`→`FIXED` angular velocity at `order=1`. The Earth→Moon `INERTIAL`→`FIXED` quaternion is unresolved, and other combinations are unverified, so verify their meaning yourself before use.
89
89
 
90
90
  ```python
91
91
  rotation = celestial.cb_axes_rotation(
@@ -113,22 +113,28 @@ celestial.mpc_ephemeris(
113
113
  observer_frame: str | None = None,
114
114
  start: str | None = None,
115
115
  stop: str | None = None,
116
+ step_s: float | None = None,
117
+ target_elements: MpcOrbitalElements | None = None,
116
118
  ) -> dict[str, Any]
117
119
  ```
118
120
 
119
- Queries an MPC minor-planet ephemeris by asteroid name or number and returns a raw JSON response dictionary.
121
+ Queries an MPC minor-planet ephemeris by asteroid name or number and returns a raw JSON response dictionary. When `target_elements` is provided, the server integrates the given MPC orbital elements directly instead of querying MPC over the network.
120
122
 
121
123
  | Parameter | Wire parameter | Description |
122
124
  | --- | --- | --- |
123
125
  | `target_name` | `TargetName` | Asteroid name or number, e.g. `Ceres`, `99942` |
124
- | `observer_frame` | `ObserverFrame` | Heliocentric frame, server options `FIXED`, `INERTIAL`, `MeanEclpJ2000`, `J2000`, default `MeanEclpJ2000` |
126
+ | `observer_frame` | `ObserverFrame` | Heliocentric frame, server options `FIXED`, `INERTIAL`, `J2000`, `ICRF`, `MeanEclpJ2000`, `EclpJ2000ICRF`, default `MeanEclpJ2000` |
125
127
  | `start` | `Start` | Start time (UTC); defaults to the orbital epoch and cannot be earlier than the orbital epoch (server rule) |
126
128
  | `stop` | `Stop` | Stop time (UTC); defaults to 1 year after `Start` |
129
+ | `step_s` | `Step` | Output sample step, in s, server default 86400 s; pass `0` to output at the internal integration steps |
130
+ | `target_elements` | `TargetElements` | Explicit MPC orbital elements (built with `mpc_orbital_elements`); when omitted, the server queries MPC over the network |
131
+
132
+ This route fetches orbital elements from the external MPC data source (element epoch in MJD TDT). The server contract declares adaptive heliocentric integration followed by Hermite interpolation onto the fixed output grid selected by `step_s`; `step_s=0` requests output at the server-declared internal integration steps. The response is a heliocentric CZML Position structure containing `OrbitElements` (orbital elements with keys `EpochMjdTdt`, `PeriTimeMjdTdt`, `Q`, `SemimajorAxis`, `Eccentricity`, `Inclination`, `Raan`, `ArgOfPeriapsis`, `MeanAnomaly`, `ReferenceFrame`) and `Position` (CZML structure, same as `ephemeris`). The orbital-element values come from external MPC data, are owned by that external data source, and may change with MPC updates. When `start`/`stop` are omitted, the server uses the orbital-epoch default window (`start` is the orbital epoch and `stop` is one year after it); an explicit fixed window depends on the orbital epoch at query time, and once the external MPC orbital epoch updates, a previously fixed window may fall before the new epoch and be rejected by the server, so prefer omitting the window parameters or following the current epoch.
127
133
 
128
- This route fetches orbital elements from the external MPC data source (element epoch in MJD TDT), which the server propagates heliocentrically with a fixed 1-day step, and outputs a heliocentric CZML Position structure. The response contains `OrbitElements` (orbital elements with keys `EpochMjdTdt`, `PeriTimeMjdTdt`, `Q`, `SemimajorAxis`, `Eccentricity`, `Inclination`, `Raan`, `ArgOfPeriapsis`, `MeanAnomaly`) and `Position` (CZML structure, same as `ephemeris`). The orbital-element values come from external MPC data, are owned by that external data source, and may change with MPC updates. When `start`/`stop` are omitted, the server uses the orbital-epoch default window (`start` is the orbital epoch and `stop` is one year after it); an explicit fixed window depends on the orbital epoch at query time, and once the external MPC orbital epoch updates, a previously fixed window may fall before the new epoch and be rejected by the server, so prefer omitting the window parameters or following the current epoch.
134
+ Verified (within-route invariants): passing the `OrbitElements` returned by a name query back as `target_elements` reproduces the name-query ephemeris exactly; omitting `step_s` exactly matches explicit `86400`, `172800` produces an exact subset of the daily grid, and `0` returns the same endpoints on a nonuniform internal integration grid; the `reference_frame` values `EclpJ2000ICRF` (MPC convention, server default) and `MeanEclpJ2000` (JPL convention) are two distinguishable branches. This evidence verifies request branches and output-sampling semantics, not absolute orbit accuracy. See the [celestial validation page](../../../../validation/celestial.md) for details.
129
135
 
130
136
  ```python
131
- mpc = celestial.mpc_ephemeris(target_name="Ceres")
137
+ mpc = celestial.mpc_ephemeris(target_name="Ceres", step_s=172800.0)
132
138
 
133
139
  print(f"Ceres MPC ephemeris: {len(mpc['Position']['cartesianVelocity']) // 7} state samples")
134
140
  ```
@@ -149,6 +155,7 @@ celestial.mpc_orbital_elements(
149
155
  raan_deg: float | None = None,
150
156
  argument_of_periapsis_deg: float | None = None,
151
157
  mean_anomaly_deg: float | None = None,
158
+ reference_frame: str | None = None,
152
159
  ) -> MpcOrbitalElements
153
160
  ```
154
161
 
@@ -165,6 +172,7 @@ Builds a heliocentric MPC orbital-element fragment. When either the departure or
165
172
  | `raan_deg` | `Raan` | deg |
166
173
  | `argument_of_periapsis_deg` | `ArgOfPeriapsis` | deg |
167
174
  | `mean_anomaly_deg` | `MeanAnomaly` | deg |
175
+ | `reference_frame` | `ReferenceFrame` | Heliocentric ecliptic frame variant: `MeanEclpJ2000` (JPL) or `EclpJ2000ICRF` (MPC, server default) |
168
176
 
169
177
  ```python
170
178
  from astrox import celestial
@@ -184,7 +192,7 @@ elements = celestial.mpc_orbital_elements(
184
192
  print(elements.to_wire())
185
193
  ```
186
194
 
187
- `to_wire()` returns the ASTROX `MpcOrbElements` request fragment; the example above prints `{'EpochMjdTdt': 61000.0, 'PeriTimeMjdTdt': 60900.0, 'Q': 0.6740515, 'SemimajorAxis': 0.9898367, 'Eccentricity': 0.3190276, 'Inclination': 0.79379, 'Raan': 209.81829, 'ArgOfPeriapsis': 100.88187, 'MeanAnomaly': 120.0}`. When passed to `lambert_transfer_window`, the server propagates heliocentrically directly with these elements and no longer queries MPC over the network. The independent Kepler propagation of explicit elements is unverified: the element system, reference frame, and time convention are not confirmed, so verify their meaning yourself before use.
195
+ `to_wire()` returns the ASTROX `MpcOrbElements` request fragment; the example above prints `{'EpochMjdTdt': 61000.0, 'PeriTimeMjdTdt': 60900.0, 'Q': 0.6740515, 'SemimajorAxis': 0.9898367, 'Eccentricity': 0.3190276, 'Inclination': 0.79379, 'Raan': 209.81829, 'ArgOfPeriapsis': 100.88187, 'MeanAnomaly': 120.0}`. When passed to `lambert_transfer_window`, the server propagates heliocentrically directly with these elements and no longer queries MPC over the network. The independent Kepler propagation of explicit elements in that route is unverified: the element system and time convention are not confirmed (the `reference_frame` option does not change the arrival states of that route); the `target_elements` branch of `mpc_ephemeris` is verified (see above), so verify the meaning yourself before use.
188
196
 
189
197
  ## Lambert transfer windows
190
198
 
@@ -205,10 +213,13 @@ celestial.lambert_transfer_window(
205
213
  arrival_step_days: float | None = None,
206
214
  departure_elements: MpcOrbitalElements | None = None,
207
215
  arrival_elements: MpcOrbitalElements | None = None,
216
+ max_departure_delta_v_m_s: int | None = None,
217
+ max_arrival_delta_v_m_s: int | None = None,
218
+ max_time_of_flight_days: int | None = None,
208
219
  ) -> dict[str, Any]
209
220
  ```
210
221
 
211
- Samples over the departure time window and the arrival time window, computes Lambert transfers between bodies, and returns a raw JSON response dictionary. It is not the single-case `orbits.lambert_delta_v` interface: that function takes two `CartesianState` values and a `time_of_flight_s`, calls `/orbit/lambert`, and returns the two triples `(DV1, DV2)`; this function scans the whole grid of departure/arrival time pairs and returns a `TransferResults` list.
222
+ Samples over the departure time window and the arrival time window, computes Lambert transfers between bodies, and returns a raw JSON response dictionary. It is not the single-case `orbits.lambert_delta_v` interface: that function takes two `CartesianState` values and a `time_of_flight_s`, calls `/orbit/lambert`, and by default returns the two triples `(DV1, DV2)`; this function scans the whole grid of departure/arrival time pairs and returns a `TransferResults` list.
212
223
 
213
224
  | Parameter | Wire parameter | Description |
214
225
  | --- | --- | --- |
@@ -218,12 +229,15 @@ Samples over the departure time window and the arrival time window, computes Lam
218
229
  | `departure_stop` | `DepartureInterval` | Departure time window end (UTC) |
219
230
  | `arrival_start` | `ArrivalInterval` | Arrival time window start (UTC); combined with `arrival_stop` into `"start/stop"` |
220
231
  | `arrival_stop` | `ArrivalInterval` | Arrival time window end (UTC) |
221
- | `sun_frame` | `SunFrameName` | Heliocentric frame, server options `MeanEclpJ2000`, `ICRF`, default `MeanEclpJ2000` |
232
+ | `sun_frame` | `SunFrameName` | Heliocentric output frame; the server currently accepts `MeanEclpJ2000`, `EclpJ2000ICRF`, and `ICRF`; default `EclpJ2000ICRF` |
222
233
  | `min_time_of_flight_days` | `MinTofDays` | Minimum transfer time, in d, integer; server default 10 |
223
234
  | `departure_step_days` | `DepartureStepDay` | Departure time sample step, in d; server default 1 |
224
235
  | `arrival_step_days` | `ArrivalStepDay` | Arrival time sample step, in d; server default 1 |
225
236
  | `departure_elements` | `DepartureElements` | MPC orbital elements of the departure asteroid (built with `mpc_orbital_elements`); when omitted, the server queries MPC over the network |
226
237
  | `arrival_elements` | `ArrivalElements` | MPC orbital elements of the arrival asteroid; when omitted, the server queries MPC over the network |
238
+ | `max_departure_delta_v_m_s` | `MaxDepartureDV` | Maximum departure velocity increment (departure hyperbolic excess speed magnitude), in m/s, integer; server default 10000, cases above it are filtered out |
239
+ | `max_arrival_delta_v_m_s` | `MaxArrivalDV` | Maximum arrival velocity increment (arrival hyperbolic excess speed magnitude), in m/s, integer; server default 10000, cases above it are filtered out |
240
+ | `max_time_of_flight_days` | `MaxTofDays` | Maximum transfer time, in d, integer; server default 500, cases above it are filtered out |
227
241
 
228
242
  `departure_body`, `arrival_body`, and the four time strings are the required request fields of this function; `DepartureInterval`/`ArrivalInterval` is a single `"start/stop"` string, e.g. `"2028-06-01T00:00:00Z/2028-06-03T00:00:00Z"`. Other optional parameters that are not supplied are not sent to ASTROX, and the server retains its default values.
229
243
 
@@ -241,6 +255,9 @@ transfer = celestial.lambert_transfer_window(
241
255
  min_time_of_flight_days=10,
242
256
  departure_step_days=2.0,
243
257
  arrival_step_days=1.0,
258
+ # this window's departure hyperbolic excess speed is about 15 km/s, above
259
+ # the server MaxDepartureDV default (10000 m/s); widen the bound explicitly
260
+ max_departure_delta_v_m_s=20000,
244
261
  )
245
262
 
246
263
  results = transfer["TransferResults"]
@@ -248,20 +265,23 @@ first = results[0]
248
265
  print(f"{len(results)} transfer results")
249
266
  print(
250
267
  f"First: {first['DepartureTime']} → {first['ArrivalTime']}, "
251
- f"|DeltaV1|={first['DV1_Mag']:.1f} m/s, |DeltaV2|={first['DV2_Mag']:.1f} m/s"
268
+ f"|DeltaV1|={first['DV1_Mag']:.1f} m/s, |DeltaV2|={first['DV2_Mag']:.1f} m/s, "
269
+ f"TOF={first['TimeOfFlightDays']:.0f} d"
252
270
  )
253
271
  ```
254
272
 
255
- The response contains `TransferResults` (an array of transfer results; each element corresponds to one sampled departure/arrival time pair, and the number of results is determined jointly by the two time windows and the sample steps). Each result has the following keys:
273
+ The response contains `TransferResults` (an array of transfer results; each element corresponds to one sampled departure/arrival time pair, and the number of results is determined jointly by the two time windows and the sample steps, and is also affected by `min_time_of_flight_days` and the `max_departure_delta_v_m_s`/`max_arrival_delta_v_m_s`/`max_time_of_flight_days` filter bounds — when every case is out of bounds the list is empty). Each result has the following keys:
256
274
 
257
275
  | Key | Type | Unit / description |
258
276
  | --- | --- | --- |
259
277
  | `DepartureTime` / `ArrivalTime` | string | Departure/arrival time (UTC string) |
260
- | `DeltaV1` / `DeltaV2` | number[3] | Departure/arrival velocity-increment vector, m/s |
278
+ | `DeltaV1` / `DeltaV2` | number[3] | Departure/arrival velocity-increment vector (departure/arrival hyperbolic excess velocity vector), m/s |
261
279
  | `DV1_Mag` / `DV2_Mag` | number | Departure/arrival velocity-increment magnitude, m/s; verified to be the Euclidean norm of the corresponding `DeltaV` vector |
262
280
  | `RV1` / `RV2` | number[6] | Position and velocity at departure/arrival (heliocentric) `[x, y, z, vx, vy, vz]`, positions m, velocities m/s |
281
+ | `TimeOfFlightDays` | number | Time of flight, in d; verified to be the exact day difference between `ArrivalTime` and `DepartureTime` |
282
+ | `ArrivalLightAngle` | number | Sun lighting angle at arrival, in deg; verified to be the angle between `DeltaV2` and the `RV2` position vector |
263
283
 
264
- Verified (supported by independent cross-validation): with `sun_frame="ICRF"`, the transfer velocities in `RV1`/`RV2` follow the zero-revolution prograde Lambert relationship, and the endpoint position directions use the ICRF axes. Unresolved: the exact coordinate relationship between `MeanEclpJ2000` and ICRF, the physical meaning of `DeltaV` relative to the endpoint-body velocities, and independent Kepler propagation of explicit MPC elements. These branches currently have only request-construction and response-structure evidence, so verify their meaning yourself before use.
284
+ Verified (supported by independent cross-validation): omitting `sun_frame` produces exactly the same `TransferResults` as explicit `EclpJ2000ICRF`; `EclpJ2000ICRF` output is the `ICRF` output rotated by the fixed 23.43929111111111° J2000 mean obliquity; with `sun_frame="ICRF"`, the transfer velocities in `RV1`/`RV2` follow the zero-revolution prograde Lambert relationship, and the endpoint position directions use the ICRF axes; `max_departure_delta_v_m_s`/`max_arrival_delta_v_m_s`/`max_time_of_flight_days` filter the sampled grid by the `DV1_Mag`/`DV2_Mag`/time-of-flight upper bounds respectively. Note that since 2026-08-20 the server defaults (10000 m/s each for departure/arrival, 500 d) filter out cases beyond the defaults, so scans over large-ΔV windows need explicitly widened bounds. Unresolved: the exact coordinate relationship between explicit `MeanEclpJ2000` and ICRF, the physical meaning of `DeltaV` relative to the endpoint-body velocities, and independent Kepler propagation of explicit MPC elements (the `reference_frame` option does not change the arrival states of that route; the element convention is still unconfirmed). The numeric semantics of those branches remain unverified, so check them before use.
265
285
 
266
286
  ## Convention notes
267
287
 
@@ -269,6 +289,7 @@ Verified (supported by independent cross-validation): with `sun_frame="ICRF"`, t
269
289
  - Each `cartesianVelocity` sample is `[Time, X, Y, Z, dX, dY, dZ]`, with `Time` in seconds from the reference epoch, positions in m, and velocities in m/s.
270
290
  - `cb_axes_rotation` passes the integer `order` through as-is; the `Rotation` length corresponds to `order` (`0` → 4, `1` → 7).
271
291
  - `mpc_ephemeris` relies on the server's orbital-epoch default window when `start`/`stop` are omitted; an explicit fixed window may expire when the external MPC orbital epoch updates.
292
+ - `mpc_ephemeris` `step_s` controls the output sampling grid; when omitted the server default is 86400 s, while `0` outputs at the internal integration steps.
272
293
  - The returns of all four functions on this page have the transport-level `IsSuccess` and `Message` removed, and the remaining server fields are preserved; errors are still raised by the HTTP layer (see error handling).
273
294
  - `lambert_transfer_window` combines `departure_start`/`departure_stop` and `arrival_start`/`arrival_stop` into the `"start/stop"` strings of `DepartureInterval`/`ArrivalInterval` respectively.
274
295
  - `mpc_orbital_elements` only performs the type checks required for lowering and does not perform physical-validity validation; fields that are not supplied do not appear in the `to_wire()` fragment.