sidereon 3.0.1__tar.gz → 3.0.2__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.
- {sidereon-3.0.1 → sidereon-3.0.2}/.github/workflows/release.yml +40 -4
- {sidereon-3.0.1 → sidereon-3.0.2}/CHANGELOG.md +7 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/Cargo.lock +5 -5
- {sidereon-3.0.1 → sidereon-3.0.2}/Cargo.toml +4 -4
- {sidereon-3.0.1 → sidereon-3.0.2}/PKG-INFO +1 -1
- {sidereon-3.0.1 → sidereon-3.0.2}/THIRD-PARTY-NOTICES.md +3 -3
- {sidereon-3.0.1 → sidereon-3.0.2}/pyproject.toml +4 -4
- {sidereon-3.0.1 → sidereon-3.0.2}/scripts/check-release.py +4 -4
- {sidereon-3.0.1 → sidereon-3.0.2}/scripts/core_source_identity.rs +1 -1
- sidereon-3.0.2/tests/fixtures/bodies/observe_de.bsp +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/core_goldens.json +1 -1
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/ppp_esbc.json +1 -1
- sidereon-3.0.2/tests/test_body_observe_reference.py +311 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_core_revision.py +38 -23
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_release_guard.py +1 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/uv.lock +1 -1
- {sidereon-3.0.1 → sidereon-3.0.2}/.cargo/config.toml.disabled +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/.gitattributes +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/.github/workflows/ci.yml +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/.gitignore +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/COVERAGE.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/LICENSE +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/README.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/bench/README.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/bench/bench_fleet.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/docs/antex.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/docs/observations.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/docs/public-gnss-distribution-sources.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/docs/releasing.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/docs/rinex-clock.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/docs/sp3.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/docs/tdm.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/examples/clean_a_phone_track.ipynb +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/examples/static_occupation_vs_cors.ipynb +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/__init__.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/__init__.pyi +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/_compression.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/_exact_cache.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/_ingress.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/data.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/data.pyi +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/distribution.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/distribution.pyi +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/exact_cache.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/exact_cache.pyi +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/exact_sp3.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/exact_sp3.pyi +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/ntrip.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/ntrip.pyi +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/python/sidereon/py.typed +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/rust-toolchain.toml +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/scripts/coverage/bindmap.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/scripts/coverage/pubapi.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/scripts/coverage/render_coverage.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/scripts/smoke-release.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/almanac.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/angles.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/anomaly.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/antex.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/araim.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/atmosphere.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/bias.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/bodies.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/body_observe.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/broadcast_comparison.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/cdm.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/clock_stability.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/conjunction.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/constellation.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/core_error_detail.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/covariance.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/coverage.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/data_catalog.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/defaults.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/dgnss.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/doppler.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/elements.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/emission.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/ephemeris.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/equinoctial.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/error_metrics.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/estimation.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/events.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/exact_cache.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/exact_time.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/fallback.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/forces.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/format_diagnostics.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/frame_catalog.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/frames.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/fusion.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/geodesic.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/geodetic_time_series.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/geofence.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/geoid.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/geometry.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/geometry_quality.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/ils.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/iod.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/ionex.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/lambert.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/leap.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/least_squares.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/lib.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/lnav.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/marshal.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/nmea.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/normality.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/ntrip.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/observables.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/observation.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/oem.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/omm.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/opm.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/orbit_determination.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/ppp.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/ppp_corrections.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/products.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/propagation.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/qc.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/reduced_orbit.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/relative.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/reliability.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/rf.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/rinex.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/rinex_clock.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/rtcm.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/rtk.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/sbas_pl.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/sbas_ssr.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/scenario.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/sidereal.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/signal_analysis.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/sky.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/solve_error_detail.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/source_localization.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/space_weather.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/spk.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/spp.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/spp_error_detail.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/staleness.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/static_positioning.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/tca.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/tdm.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/terrain.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/terrain_store.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/tides.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/time_model_error.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/tle_fit_error_detail.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/tropo.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/src/unix_compress.rs +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/_helpers.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/_sp3_merge.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/README.md +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/antex/igs20_pasa_scoa_gps.atx +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/antex/igs20_wettzell_trim.atx +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/batch_fleet.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/cdm.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/clk/lossless/rinex_clock304_table_a17.clk +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/clk/lossless/rinex_clock304_table_a18.clk +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/clk/synthetic_rinex_clock.clk +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/conjunction.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/constellation/gps_ops_sample.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/constellation/navcen_forecast_cases.html +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/constellation/navcen_gps_sample.html +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/events_bodies_dop.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/format_diagnostics_inputs.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/frames_time.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/geodesic/geodtest_row.dat +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/geoid/egm2008_25_norcal_crop.bin +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/gnss_data/igs22376.sp3.Z.b64 +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/gnss_data/ncompress-current-b9-counter.Z.b64 +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/listings/aiub-iono-prd-20260923.csv +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/listings/gfz-ultra-w2430-20260804.html +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/nav/BRDC00GOP_R_20210010000_01D_MN.rnx +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/nav/ESBC00DNK_R_20201770000_01D_MN.rnx +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/nav/KMS300DNK_R_20221591000_01H_MN.rnx +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/numerical_propagation.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/obs/ESBC00DNK_R_20201770000_01D_30S_MO_trim.crx +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/obs/ESBC00DNK_R_20201770000_01D_30S_MO_trim.rnx +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/obs/algo0010_2015001_v1_trim.crx +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/obs/algo0010_2015001_v1_trim.rnx +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/omm.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/pass_finder.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/rf_link_budget.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/rtk_wtzr.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/scenario_base.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/sgp4_topocentric.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/sp3/IGS0OPSFIN_20261200945_02H30M_15M_ORB.SP3 +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/sp3-merge-input-v1.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/sp3-merge-report-v3.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/sp3_bodies.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/spk/horizons_eros_type21.bsp +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/tdm/annex_e_01.kvn +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/fixtures/tle_roundtrip.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/golden/sp3-terminal-record-v1.json +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_012_bindings.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_013_bindings.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_014_bindings.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_015_bindings.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_016_wave2_bindings.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_017_domain_exposure.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_018_domain_exposure.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_019_track.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_020_error_metrics.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_antex.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_antex_public_equality.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_antex_public_pcv_sample_fields.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_atmosphere.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_attested_open.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_batch.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_broadcast_comparison.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_broadcast_fallback.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_cdm.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_cdm_top_level.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_cdm_value_equality.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_codec_error_details.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_conjunction.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_constellation.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_constellation_fleet.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_core_defaults.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_core_public_api_parity.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_core_round3_surfaces.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_covariance.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_covariance_propagation.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_coverage.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_crinex.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_data.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_data_publication_resilience.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_dgnss.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_distribution.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_distribution_fallback.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_dop_at_epoch.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_dop_convention.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_doppler.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_dted_tile_error_details.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_egm96.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_elements.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_events_bodies_dop.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_exact_cache_atomicity.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_field_mode_bindings.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_forces.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_format_diagnostics.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_frames_time.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ftp_transport.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_fusion_error_details.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_geoid.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_geometry.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ils.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_import.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_inertial_mechanization.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ionex.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ionex_instant_queries.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ionex_policies.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ionex_public_equality.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ionosphere_nequick.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_klobuchar_native.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_lambert_iod.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_leap_seconds.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_least_squares.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_lnav.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_misc_public_equality.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_moving_baseline.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_new_core_api.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_next_issue_due.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_nmea_finish_output.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ntrip.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_numerical.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_obs_policies.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_observables.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_observables_broadcast.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_observables_error_details.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_observation.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_observation_qc.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_observe_batch.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_oem.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_oem_full_dto.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_omm.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_omm_full_dto.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_opm.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_opm_full_dto.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_parity_gaps.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_parse_tle_file.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_passes.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ppp.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ppp_corrections.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_ppp_range_corrections.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_precise_interpolant_public_values.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_precise_samples.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_precise_samples_errors.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_propagation.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_qc.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_reduced_orbit.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_reduced_orbit_piecewise.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_residual_stats.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_rf.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_rinex_clock.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_rinex_clock_equality.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_rinex_clock_header_field_details.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_rinex_clock_lossless.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_rinex_nav.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_rinex_obs.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_rtcm.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_rtk.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_rtk_unresolved_carriers.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sbas_decoded_lists.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sbas_unassigned_mask.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_scenario_external_sources.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sky.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_bodies.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_catalog_exact.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_clock_reference.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_interpolation_policy.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_merge.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_merge_coverage.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_merge_per_epoch_provenance.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_public_metadata.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_terminal_record.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_window_continuity.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_sp3_write_and_records.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_spk.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_spp.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_spp_error_details.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_spp_glonass.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_spp_robustness.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_staleness.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_stub_accuracy.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_tca.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_tdm_policies.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_terrain_unknown_elevation.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_tides.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_time_model_error_details.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_time_offset_error_details.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_tle_fit.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_tle_roundtrip.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_tropo.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_unix_compress.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_visible_ground_track.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/tests/test_weather_terrain_error_details.py +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/third_party_licenses/ERFA-BSD-3-Clause.txt +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/third_party_licenses/IERS-CONVENTIONS-SOFTWARE-LICENSE.txt +0 -0
- {sidereon-3.0.1 → sidereon-3.0.2}/third_party_licenses/SciPy-BSD-3-Clause.txt +0 -0
- {sidereon-3.0.1/third_party_source/sidereon-core-3.0.1 → sidereon-3.0.2/third_party_source/sidereon-core-3.0.2}/tides/mod.rs +0 -0
- {sidereon-3.0.1/third_party_source/sidereon-core-3.0.1 → sidereon-3.0.2/third_party_source/sidereon-core-3.0.2}/tides/ocean.rs +0 -0
- {sidereon-3.0.1/third_party_source/sidereon-core-3.0.1 → sidereon-3.0.2/third_party_source/sidereon-core-3.0.2}/tides/pole.rs +0 -0
|
@@ -153,10 +153,10 @@ jobs:
|
|
|
153
153
|
done
|
|
154
154
|
for source in mod.rs ocean.rs pole.rs; do
|
|
155
155
|
unzip -p "$wheel" \
|
|
156
|
-
"third_party_source/sidereon-core-3.0.
|
|
156
|
+
"third_party_source/sidereon-core-3.0.2/tides/$source" \
|
|
157
157
|
>"$RUNNER_TEMP/$source"
|
|
158
158
|
cmp "$RUNNER_TEMP/$source" \
|
|
159
|
-
"third_party_source/sidereon-core-3.0.
|
|
159
|
+
"third_party_source/sidereon-core-3.0.2/tides/$source"
|
|
160
160
|
done
|
|
161
161
|
done
|
|
162
162
|
notice="$RUNNER_TEMP/sdist.notices"
|
|
@@ -173,10 +173,10 @@ jobs:
|
|
|
173
173
|
done
|
|
174
174
|
for source in mod.rs ocean.rs pole.rs; do
|
|
175
175
|
tar -xOf "${sdists[0]}" --wildcards \
|
|
176
|
-
"*/third_party_source/sidereon-core-3.0.
|
|
176
|
+
"*/third_party_source/sidereon-core-3.0.2/tides/$source" \
|
|
177
177
|
>"$RUNNER_TEMP/sdist-$source"
|
|
178
178
|
cmp "$RUNNER_TEMP/sdist-$source" \
|
|
179
|
-
"third_party_source/sidereon-core-3.0.
|
|
179
|
+
"third_party_source/sidereon-core-3.0.2/tides/$source"
|
|
180
180
|
done
|
|
181
181
|
- name: Smoke-test installed x86_64 Linux wheel
|
|
182
182
|
shell: bash
|
|
@@ -218,3 +218,39 @@ jobs:
|
|
|
218
218
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
219
219
|
with:
|
|
220
220
|
attestations: true
|
|
221
|
+
|
|
222
|
+
public-consumer:
|
|
223
|
+
name: Verify public PyPI consumer
|
|
224
|
+
runs-on: ubuntu-24.04-arm
|
|
225
|
+
timeout-minutes: 15
|
|
226
|
+
needs: publish
|
|
227
|
+
steps:
|
|
228
|
+
- uses: actions/checkout@v4
|
|
229
|
+
- uses: actions/setup-python@v5
|
|
230
|
+
with:
|
|
231
|
+
python-version: '3.12'
|
|
232
|
+
- name: Install exact published wheel and exercise public references
|
|
233
|
+
shell: bash
|
|
234
|
+
run: |
|
|
235
|
+
set -euo pipefail
|
|
236
|
+
version="${GITHUB_REF_NAME#v}"
|
|
237
|
+
scratch="$(mktemp -d)"
|
|
238
|
+
trap 'rm -rf "$scratch"' EXIT
|
|
239
|
+
python -m venv "$scratch/venv"
|
|
240
|
+
installed=false
|
|
241
|
+
for attempt in 1 2 3 4 5 6; do
|
|
242
|
+
if "$scratch/venv/bin/python" -m pip install --only-binary=sidereon "sidereon==$version" pytest; then
|
|
243
|
+
installed=true
|
|
244
|
+
break
|
|
245
|
+
fi
|
|
246
|
+
sleep 10
|
|
247
|
+
done
|
|
248
|
+
test "$installed" = true
|
|
249
|
+
mkdir -p "$scratch/tests/fixtures/bodies"
|
|
250
|
+
cp scripts/smoke-release.py "$scratch/smoke-release.py"
|
|
251
|
+
cp tests/test_body_observe_reference.py "$scratch/tests/"
|
|
252
|
+
cp tests/fixtures/bodies/observe_de.bsp "$scratch/tests/fixtures/bodies/"
|
|
253
|
+
cd "$scratch"
|
|
254
|
+
unset PYTHONPATH
|
|
255
|
+
SIDEREON_EXPECTED_VERSION="$version" "$scratch/venv/bin/python" -I smoke-release.py
|
|
256
|
+
"$scratch/venv/bin/python" -I -m pytest -q tests/test_body_observe_reference.py
|
|
@@ -4,6 +4,13 @@ All notable changes to the Sidereon Python interface are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [3.0.2] - 2026-10-05
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Use the coordinated 3.0.2 Rust engine release, including NaN-safe Portable ULP comparisons.
|
|
12
|
+
- Retain the existing Python API while keeping package versions and shipped source disclosures aligned across all libraries.
|
|
13
|
+
|
|
7
14
|
## [3.0.1] - 2026-10-04
|
|
8
15
|
|
|
9
16
|
### Added
|
|
@@ -611,9 +611,9 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
|
|
611
611
|
|
|
612
612
|
[[package]]
|
|
613
613
|
name = "sidereon"
|
|
614
|
-
version = "3.0.
|
|
614
|
+
version = "3.0.2"
|
|
615
615
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
616
|
-
checksum = "
|
|
616
|
+
checksum = "8a424bd9dea809b4cf2b816c27aa129a3e437b95139389ecbc94416aeee27951"
|
|
617
617
|
dependencies = [
|
|
618
618
|
"crc32fast",
|
|
619
619
|
"flate2",
|
|
@@ -622,9 +622,9 @@ dependencies = [
|
|
|
622
622
|
|
|
623
623
|
[[package]]
|
|
624
624
|
name = "sidereon-core"
|
|
625
|
-
version = "3.0.
|
|
625
|
+
version = "3.0.2"
|
|
626
626
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
627
|
-
checksum = "
|
|
627
|
+
checksum = "29f682ba7089c512d83cfea712bdc6ce9caac5e46d9acbeca7a1b2151ad8ee5b"
|
|
628
628
|
dependencies = [
|
|
629
629
|
"approx",
|
|
630
630
|
"cc",
|
|
@@ -646,7 +646,7 @@ dependencies = [
|
|
|
646
646
|
|
|
647
647
|
[[package]]
|
|
648
648
|
name = "sidereon-py"
|
|
649
|
-
version = "3.0.
|
|
649
|
+
version = "3.0.2"
|
|
650
650
|
dependencies = [
|
|
651
651
|
"nalgebra",
|
|
652
652
|
"numpy",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "sidereon-py"
|
|
3
|
-
version = "3.0.
|
|
3
|
+
version = "3.0.2"
|
|
4
4
|
authors = []
|
|
5
5
|
edition = "2021"
|
|
6
6
|
description = "Python (PyO3) bindings over the sidereon ergonomic API: SP3 loading and SPP/RTK/PPP positioning solves"
|
|
@@ -25,12 +25,12 @@ exact-cache-test-failpoints = ["sidereon-core/exact-cache-test-failpoints"]
|
|
|
25
25
|
# The thin ergonomic engine surface this binding marshals to. No modeling logic
|
|
26
26
|
# lives here: every solve delegates to a `sidereon` entry point, which in turn
|
|
27
27
|
# delegates to `sidereon-core`.
|
|
28
|
-
sidereon =
|
|
29
|
-
sidereon-core = { version = "=3.0.
|
|
28
|
+
sidereon = "=3.0.2"
|
|
29
|
+
sidereon-core = { version = "=3.0.2", features = ["mmap"] }
|
|
30
30
|
# The standalone general-purpose trust-region least-squares solver: a data-driven
|
|
31
31
|
# `least_squares` whose residual and Jacobian are evaluated entirely in Rust, so
|
|
32
32
|
# no per-iteration Python callback is paid.
|
|
33
|
-
trust-region-least-squares = "0.11.0"
|
|
33
|
+
trust-region-least-squares = "=0.11.0"
|
|
34
34
|
pyo3 = { version = "0.25", features = ["abi3-py39"] }
|
|
35
35
|
# Zero-copy ndarray marshalling so a batched propagate/look-angle call crosses
|
|
36
36
|
# the FFI boundary once (1-D epochs in, 2-D states / 1-D angles out) instead of a
|
|
@@ -330,9 +330,9 @@ endorsed by the IERS Conventions Center. The Rust source describes the origin,
|
|
|
330
330
|
the renamed routines, and the differences from the Fortran implementation.
|
|
331
331
|
The complete non-test tide source distributed in the compiled extension is
|
|
332
332
|
included under
|
|
333
|
-
`third_party_source/sidereon-core-3.0.
|
|
334
|
-
distributions. These files match sidereon-core 3.0.
|
|
335
|
-
Source: [sidereon-core tides at the pinned commit](https://github.com/neilberkman/sidereon/tree/
|
|
333
|
+
`third_party_source/sidereon-core-3.0.2/tides/` in wheels and source
|
|
334
|
+
distributions. These files match sidereon-core 3.0.2 at commit 8694648892d8ab065d94014e2e21d6cd5054818e.
|
|
335
|
+
Source: [sidereon-core tides at the pinned commit](https://github.com/neilberkman/sidereon/tree/8694648892d8ab065d94014e2e21d6cd5054818e/crates/sidereon-core/src/tides).
|
|
336
336
|
The authoritative original is available from:
|
|
337
337
|
|
|
338
338
|
<https://iers-conventions.obspm.fr/content/chapter7/software/dehanttideinel/DEHANTTIDEINEL.F>
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "sidereon"
|
|
7
|
-
version = "3.0.
|
|
7
|
+
version = "3.0.2"
|
|
8
8
|
description = "Python (PyO3) bindings over the sidereon engine: SP3 loading and SPP/RTK/PPP positioning solves"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -82,7 +82,7 @@ include = [
|
|
|
82
82
|
"third_party_licenses/ERFA-BSD-3-Clause.txt",
|
|
83
83
|
"third_party_licenses/IERS-CONVENTIONS-SOFTWARE-LICENSE.txt",
|
|
84
84
|
"third_party_licenses/SciPy-BSD-3-Clause.txt",
|
|
85
|
-
"third_party_source/sidereon-core-3.0.
|
|
86
|
-
"third_party_source/sidereon-core-3.0.
|
|
87
|
-
"third_party_source/sidereon-core-3.0.
|
|
85
|
+
"third_party_source/sidereon-core-3.0.2/tides/mod.rs",
|
|
86
|
+
"third_party_source/sidereon-core-3.0.2/tides/ocean.rs",
|
|
87
|
+
"third_party_source/sidereon-core-3.0.2/tides/pole.rs",
|
|
88
88
|
]
|
|
@@ -13,7 +13,7 @@ import tomllib
|
|
|
13
13
|
ROOT = Path(__file__).resolve().parents[1]
|
|
14
14
|
CORE_GIT_URL = "https://github.com/neilberkman/sidereon"
|
|
15
15
|
FULL_GIT_REVISION = re.compile(r"^[0-9a-f]{40}$")
|
|
16
|
-
CORE_SOURCE_REVISION = "
|
|
16
|
+
CORE_SOURCE_REVISION = "8694648892d8ab065d94014e2e21d6cd5054818e"
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def registry_version(name, value, package_version):
|
|
@@ -114,7 +114,7 @@ def validate_trust_region_dependency(
|
|
|
114
114
|
value, engine_dependencies, package_version, *, allow_candidate
|
|
115
115
|
):
|
|
116
116
|
"""Accept the registry release or its exact coordinated Git candidate."""
|
|
117
|
-
if value
|
|
117
|
+
if value in ("0.11.0", "=0.11.0"):
|
|
118
118
|
return
|
|
119
119
|
if not allow_candidate:
|
|
120
120
|
raise ValueError(
|
|
@@ -309,7 +309,7 @@ def main() -> None:
|
|
|
309
309
|
"ocean.rs": "25946677944425671a92717860ac2d70f255de5403eeb1fbf98b361716821d5c",
|
|
310
310
|
"pole.rs": "b4cc4c16bdd8ce1d8f04073602ab47dfb85a002b946ab192e8d4d2d600f0a1f8",
|
|
311
311
|
}
|
|
312
|
-
tide_root = ROOT / "third_party_source" / "sidereon-core-3.0.
|
|
312
|
+
tide_root = ROOT / "third_party_source" / "sidereon-core-3.0.2" / "tides"
|
|
313
313
|
for filename, expected_digest in tide_sources.items():
|
|
314
314
|
source = tide_root / filename
|
|
315
315
|
if not source.is_file():
|
|
@@ -318,7 +318,7 @@ def main() -> None:
|
|
|
318
318
|
if digest != expected_digest:
|
|
319
319
|
raise SystemExit(
|
|
320
320
|
f"IERS-derived source disclosure {source} has digest {digest}, "
|
|
321
|
-
f"expected {expected_digest} from sidereon-core 3.0.
|
|
321
|
+
f"expected {expected_digest} from sidereon-core 3.0.2 at "
|
|
322
322
|
f"{CORE_SOURCE_REVISION}"
|
|
323
323
|
)
|
|
324
324
|
|
|
@@ -8,7 +8,7 @@ use std::path::{Path, PathBuf};
|
|
|
8
8
|
|
|
9
9
|
const REGISTRY_SOURCE: &str = "registry+https://github.com/rust-lang/crates.io-index";
|
|
10
10
|
const GIT_SOURCE_PREFIX: &str = "git+https://github.com/neilberkman/sidereon?rev=";
|
|
11
|
-
const RELEASE_VERSION: &str = "3.0.
|
|
11
|
+
const RELEASE_VERSION: &str = "3.0.2";
|
|
12
12
|
|
|
13
13
|
#[derive(Debug)]
|
|
14
14
|
struct LockedPackage {
|
|
Binary file
|
|
@@ -16520,5 +16520,5 @@
|
|
|
16520
16520
|
]
|
|
16521
16521
|
}
|
|
16522
16522
|
},
|
|
16523
|
-
"core_revision": "
|
|
16523
|
+
"core_revision": "8694648892d8ab065d94014e2e21d6cd5054818e"
|
|
16524
16524
|
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"""Public body-observation checks against independent ephemeris references.
|
|
2
|
+
|
|
3
|
+
JPL values are reproducible with GET https://ssd.jpl.nasa.gov/api/horizons.api
|
|
4
|
+
and format=text, OBJ_DATA=NO, MAKE_EPHEM=YES, EPHEM_TYPE=OBSERVER,
|
|
5
|
+
CENTER=coord@399, COORD_TYPE=GEODETIC, SITE_COORD=0,51.4769,0.046,
|
|
6
|
+
STEP_SIZE=1 m, TIME_TYPE=UT, QUANTITIES=2,4,20, ANG_FORMAT=DEG,
|
|
7
|
+
APPARENT=AIRLESS, RANGE_UNITS=KM. For the Sun use COMMAND=10,
|
|
8
|
+
START_TIME=2024-06-20 12:01:42, STOP_TIME=2024-06-20 12:02:42; for the
|
|
9
|
+
Moon use COMMAND=301, START_TIME=2024-04-23 23:55:59,
|
|
10
|
+
STOP_TIME=2024-04-24 00:00:59. Both responses identify DE441. First data
|
|
11
|
+
rows (apparent RA/Dec, az/el, range km) are Sun 89.61786, 23.43665,
|
|
12
|
+
179.997296, 61.959749, 1.5201128641E+08; Moon 211.50898, -15.40328,
|
|
13
|
+
179.999082, 23.119822, 3.9720636319E+05. The JPL manual documents q2 apparent
|
|
14
|
+
coordinates as true-equator/equinox-of-date for Earth sites and q4 azimuth as
|
|
15
|
+
clockwise from north. Sidereon's analytic Sun/Moon series are intended for
|
|
16
|
+
planning and visualization, not almanac precision, so the angular tolerances
|
|
17
|
+
are deliberately sub-degree.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from datetime import datetime, timezone
|
|
21
|
+
|
|
22
|
+
import pytest
|
|
23
|
+
import sidereon
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.mark.parametrize(
|
|
27
|
+
(
|
|
28
|
+
"target",
|
|
29
|
+
"epoch",
|
|
30
|
+
"apparent_ra_deg",
|
|
31
|
+
"apparent_dec_deg",
|
|
32
|
+
"azimuth_deg",
|
|
33
|
+
"elevation_deg",
|
|
34
|
+
"range_km",
|
|
35
|
+
"angle_tolerance_deg",
|
|
36
|
+
"range_tolerance_km",
|
|
37
|
+
),
|
|
38
|
+
[
|
|
39
|
+
(
|
|
40
|
+
sidereon.Target.sun(),
|
|
41
|
+
datetime(2024, 6, 20, 12, 1, 42, tzinfo=timezone.utc),
|
|
42
|
+
89.61786,
|
|
43
|
+
23.43665,
|
|
44
|
+
179.997296,
|
|
45
|
+
61.959749,
|
|
46
|
+
152_011_286.41,
|
|
47
|
+
0.01,
|
|
48
|
+
100_000.0,
|
|
49
|
+
),
|
|
50
|
+
(
|
|
51
|
+
sidereon.Target.moon(),
|
|
52
|
+
datetime(2024, 4, 23, 23, 55, 59, tzinfo=timezone.utc),
|
|
53
|
+
211.50898,
|
|
54
|
+
-15.40328,
|
|
55
|
+
179.999082,
|
|
56
|
+
23.119822,
|
|
57
|
+
397_206.36319,
|
|
58
|
+
0.95,
|
|
59
|
+
1_000.0,
|
|
60
|
+
),
|
|
61
|
+
],
|
|
62
|
+
ids=("sun", "moon"),
|
|
63
|
+
)
|
|
64
|
+
def test_ground_observation_tracks_independent_horizons_reference(
|
|
65
|
+
target,
|
|
66
|
+
epoch,
|
|
67
|
+
apparent_ra_deg,
|
|
68
|
+
apparent_dec_deg,
|
|
69
|
+
azimuth_deg,
|
|
70
|
+
elevation_deg,
|
|
71
|
+
range_km,
|
|
72
|
+
angle_tolerance_deg,
|
|
73
|
+
range_tolerance_km,
|
|
74
|
+
):
|
|
75
|
+
epoch_unix_us = int(epoch.timestamp()) * 1_000_000
|
|
76
|
+
|
|
77
|
+
observation = sidereon.observe_body(
|
|
78
|
+
51.4769,
|
|
79
|
+
0.0,
|
|
80
|
+
0.046,
|
|
81
|
+
epoch_unix_us,
|
|
82
|
+
target,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
assert observation.reduced is True
|
|
86
|
+
assert 0.0 <= observation.apparent.right_ascension_deg < 360.0
|
|
87
|
+
assert 0.0 <= observation.apparent.right_ascension_hours < 24.0
|
|
88
|
+
assert -180.0 < observation.hour_angle_deg <= 180.0
|
|
89
|
+
assert -12.0 < observation.hour_angle_hours <= 12.0
|
|
90
|
+
assert 0.0 <= observation.horizontal.azimuth_deg < 360.0
|
|
91
|
+
assert observation.apparent.right_ascension_deg == pytest.approx(
|
|
92
|
+
apparent_ra_deg, abs=angle_tolerance_deg, rel=0.0
|
|
93
|
+
)
|
|
94
|
+
assert observation.apparent.declination_deg == pytest.approx(
|
|
95
|
+
apparent_dec_deg, abs=angle_tolerance_deg, rel=0.0
|
|
96
|
+
)
|
|
97
|
+
assert observation.horizontal.azimuth_deg == pytest.approx(
|
|
98
|
+
azimuth_deg, abs=angle_tolerance_deg, rel=0.0
|
|
99
|
+
)
|
|
100
|
+
assert observation.horizontal.elevation_deg == pytest.approx(
|
|
101
|
+
elevation_deg, abs=angle_tolerance_deg, rel=0.0
|
|
102
|
+
)
|
|
103
|
+
assert observation.horizontal.range_km == pytest.approx(
|
|
104
|
+
range_km, abs=range_tolerance_km, rel=0.0
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# The API exposes both degree and hour forms of RA/hour angle.
|
|
108
|
+
assert observation.apparent.right_ascension_hours * 15.0 == pytest.approx(
|
|
109
|
+
observation.apparent.right_ascension_deg, abs=1e-12, rel=0.0
|
|
110
|
+
)
|
|
111
|
+
assert observation.hour_angle_hours * 15.0 == pytest.approx(
|
|
112
|
+
observation.hour_angle_deg, abs=1e-12, rel=0.0
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# Full-target values are generated independently by the pinned Skyfield
|
|
117
|
+
# fixture generator also used by the core integration test. Its source is
|
|
118
|
+
# tests/fixtures/bodies/gen_observe_golden.py in sidereon-core; that generator
|
|
119
|
+
# uses observe_de.bsp and applies Sun-only gravitational deflection.
|
|
120
|
+
@pytest.mark.parametrize(
|
|
121
|
+
(
|
|
122
|
+
"naif_id",
|
|
123
|
+
"latitude_deg",
|
|
124
|
+
"longitude_deg",
|
|
125
|
+
"altitude_km",
|
|
126
|
+
"apparent_ra_deg",
|
|
127
|
+
"apparent_dec_deg",
|
|
128
|
+
"apparent_distance_km",
|
|
129
|
+
"apparent_icrs_ra_deg",
|
|
130
|
+
"apparent_icrs_dec_deg",
|
|
131
|
+
"apparent_icrs_distance_km",
|
|
132
|
+
"astrometric_ra_deg",
|
|
133
|
+
"astrometric_dec_deg",
|
|
134
|
+
"astrometric_distance_km",
|
|
135
|
+
"azimuth_deg",
|
|
136
|
+
"elevation_deg",
|
|
137
|
+
"range_km",
|
|
138
|
+
"ecliptic_longitude_deg",
|
|
139
|
+
"ecliptic_latitude_deg",
|
|
140
|
+
"ecliptic_distance_km",
|
|
141
|
+
),
|
|
142
|
+
[
|
|
143
|
+
(
|
|
144
|
+
4,
|
|
145
|
+
51.4779,
|
|
146
|
+
-0.0015,
|
|
147
|
+
0.046,
|
|
148
|
+
267.0545293733468,
|
|
149
|
+
-23.96185179890772,
|
|
150
|
+
362_601_889.49888045,
|
|
151
|
+
266.689454311102,
|
|
152
|
+
-23.95235998065674,
|
|
153
|
+
362_601_889.4988812,
|
|
154
|
+
266.69569176937006,
|
|
155
|
+
-23.95250704362053,
|
|
156
|
+
362_601_889.498879,
|
|
157
|
+
25.029803759785487,
|
|
158
|
+
-60.701353351529,
|
|
159
|
+
362_601_889.4988805,
|
|
160
|
+
267.3084528018354,
|
|
161
|
+
-0.550968260129117,
|
|
162
|
+
362_601_889.49888045,
|
|
163
|
+
),
|
|
164
|
+
(
|
|
165
|
+
5,
|
|
166
|
+
-33.8568,
|
|
167
|
+
151.2153,
|
|
168
|
+
0.040,
|
|
169
|
+
33.685726736672464,
|
|
170
|
+
12.26418101472206,
|
|
171
|
+
670_428_149.8823149,
|
|
172
|
+
33.36411888660434,
|
|
173
|
+
12.152064228124974,
|
|
174
|
+
670_428_149.8823142,
|
|
175
|
+
33.36174062892731,
|
|
176
|
+
12.151348694023607,
|
|
177
|
+
670_428_149.8823142,
|
|
178
|
+
113.07414946418533,
|
|
179
|
+
-49.51460784852244,
|
|
180
|
+
670_428_149.8823149,
|
|
181
|
+
35.582668467646254,
|
|
182
|
+
-1.1853565914672937,
|
|
183
|
+
670_428_149.8823149,
|
|
184
|
+
),
|
|
185
|
+
],
|
|
186
|
+
ids=("mars-greenwich", "jupiter-sydney"),
|
|
187
|
+
)
|
|
188
|
+
def test_spk_target_projects_complete_skyfield_golden(
|
|
189
|
+
naif_id,
|
|
190
|
+
latitude_deg,
|
|
191
|
+
longitude_deg,
|
|
192
|
+
altitude_km,
|
|
193
|
+
apparent_ra_deg,
|
|
194
|
+
apparent_dec_deg,
|
|
195
|
+
apparent_distance_km,
|
|
196
|
+
apparent_icrs_ra_deg,
|
|
197
|
+
apparent_icrs_dec_deg,
|
|
198
|
+
apparent_icrs_distance_km,
|
|
199
|
+
astrometric_ra_deg,
|
|
200
|
+
astrometric_dec_deg,
|
|
201
|
+
astrometric_distance_km,
|
|
202
|
+
azimuth_deg,
|
|
203
|
+
elevation_deg,
|
|
204
|
+
range_km,
|
|
205
|
+
ecliptic_longitude_deg,
|
|
206
|
+
ecliptic_latitude_deg,
|
|
207
|
+
ecliptic_distance_km,
|
|
208
|
+
):
|
|
209
|
+
import math
|
|
210
|
+
from pathlib import Path
|
|
211
|
+
|
|
212
|
+
kernel = sidereon.load_spk(
|
|
213
|
+
Path(__file__).parent / "fixtures" / "bodies" / "observe_de.bsp"
|
|
214
|
+
)
|
|
215
|
+
observation = sidereon.observe_body(
|
|
216
|
+
latitude_deg,
|
|
217
|
+
longitude_deg,
|
|
218
|
+
altitude_km,
|
|
219
|
+
int(datetime(2024, 1, 1, tzinfo=timezone.utc).timestamp()) * 1_000_000,
|
|
220
|
+
sidereon.Target.spk(kernel, naif_id),
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
def equatorial_separation_arcsec(coords, expected_ra_deg, expected_dec_deg):
|
|
224
|
+
def vector(ra_deg, dec_deg):
|
|
225
|
+
ra = math.radians(ra_deg)
|
|
226
|
+
dec = math.radians(dec_deg)
|
|
227
|
+
return (
|
|
228
|
+
math.cos(dec) * math.cos(ra),
|
|
229
|
+
math.cos(dec) * math.sin(ra),
|
|
230
|
+
math.sin(dec),
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
actual = vector(coords.right_ascension_deg, coords.declination_deg)
|
|
234
|
+
expected = vector(expected_ra_deg, expected_dec_deg)
|
|
235
|
+
cross = (
|
|
236
|
+
actual[1] * expected[2] - actual[2] * expected[1],
|
|
237
|
+
actual[2] * expected[0] - actual[0] * expected[2],
|
|
238
|
+
actual[0] * expected[1] - actual[1] * expected[0],
|
|
239
|
+
)
|
|
240
|
+
cross_norm = math.sqrt(sum(component * component for component in cross))
|
|
241
|
+
dot = sum(a * b for a, b in zip(actual, expected))
|
|
242
|
+
return math.degrees(math.atan2(cross_norm, dot)) * 3600.0
|
|
243
|
+
|
|
244
|
+
def relative_distance(actual, expected):
|
|
245
|
+
return abs(actual - expected) / max(abs(expected), 1.0)
|
|
246
|
+
|
|
247
|
+
assert observation.reduced is False
|
|
248
|
+
for coords, ra, dec, distance in (
|
|
249
|
+
(
|
|
250
|
+
observation.astrometric,
|
|
251
|
+
astrometric_ra_deg,
|
|
252
|
+
astrometric_dec_deg,
|
|
253
|
+
astrometric_distance_km,
|
|
254
|
+
),
|
|
255
|
+
(
|
|
256
|
+
observation.apparent_icrs,
|
|
257
|
+
apparent_icrs_ra_deg,
|
|
258
|
+
apparent_icrs_dec_deg,
|
|
259
|
+
apparent_icrs_distance_km,
|
|
260
|
+
),
|
|
261
|
+
(
|
|
262
|
+
observation.apparent,
|
|
263
|
+
apparent_ra_deg,
|
|
264
|
+
apparent_dec_deg,
|
|
265
|
+
apparent_distance_km,
|
|
266
|
+
),
|
|
267
|
+
):
|
|
268
|
+
assert 0.0 <= coords.right_ascension_deg < 360.0
|
|
269
|
+
assert 0.0 <= coords.right_ascension_hours < 24.0
|
|
270
|
+
assert equatorial_separation_arcsec(coords, ra, dec) < 1.0
|
|
271
|
+
assert relative_distance(coords.distance_km, distance) < 1e-8
|
|
272
|
+
assert coords.right_ascension_hours * 15.0 == pytest.approx(
|
|
273
|
+
coords.right_ascension_deg, abs=1e-12, rel=0.0
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
assert -180.0 < observation.hour_angle_deg <= 180.0
|
|
277
|
+
assert -12.0 < observation.hour_angle_hours <= 12.0
|
|
278
|
+
assert 0.0 <= observation.horizontal.azimuth_deg < 360.0
|
|
279
|
+
assert observation.horizontal.azimuth_deg == pytest.approx(
|
|
280
|
+
azimuth_deg, abs=2.0 / 3600.0, rel=0.0
|
|
281
|
+
)
|
|
282
|
+
assert observation.horizontal.elevation_deg == pytest.approx(
|
|
283
|
+
elevation_deg, abs=2.0 / 3600.0, rel=0.0
|
|
284
|
+
)
|
|
285
|
+
assert relative_distance(observation.horizontal.range_km, range_km) < 1e-8
|
|
286
|
+
assert 0.0 <= observation.ecliptic.longitude_deg < 360.0
|
|
287
|
+
assert observation.ecliptic.longitude_deg == pytest.approx(
|
|
288
|
+
ecliptic_longitude_deg, abs=1.0 / 3600.0, rel=0.0
|
|
289
|
+
)
|
|
290
|
+
assert observation.ecliptic.latitude_deg == pytest.approx(
|
|
291
|
+
ecliptic_latitude_deg, abs=1.0 / 3600.0, rel=0.0
|
|
292
|
+
)
|
|
293
|
+
assert (
|
|
294
|
+
relative_distance(observation.ecliptic.distance_km, ecliptic_distance_km) < 1e-8
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
# Recover local hour angle from the independent Skyfield alt/az values.
|
|
298
|
+
lat = math.radians(latitude_deg)
|
|
299
|
+
az = math.radians(azimuth_deg)
|
|
300
|
+
el = math.radians(elevation_deg)
|
|
301
|
+
hour_angle = math.degrees(
|
|
302
|
+
math.atan2(
|
|
303
|
+
-math.sin(az) * math.cos(el),
|
|
304
|
+
math.sin(el) * math.cos(lat) - math.cos(el) * math.sin(lat) * math.cos(az),
|
|
305
|
+
)
|
|
306
|
+
)
|
|
307
|
+
delta_hour_angle = (observation.hour_angle_deg - hour_angle + 180.0) % 360.0 - 180.0
|
|
308
|
+
assert abs(delta_hour_angle) < 5.0 / 3600.0
|
|
309
|
+
assert observation.hour_angle_hours * 15.0 == pytest.approx(
|
|
310
|
+
observation.hour_angle_deg, abs=1e-12, rel=0.0
|
|
311
|
+
)
|