.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/plot_ranging.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_plot_ranging.py: Systematic Ranging of a Short-Arc NEO ====================================== Demonstrate orbit uncertainty sampling from a single short-arc tracklet using the systematic ranging algorithm (Farnocchia, Chesley & Micheli 2015). With only a few minutes of observations the orbit is highly degenerate: almost any distance from Earth is consistent with the data. Ranging scans a 2-D grid over topocentric range and range-rate, scores each cell by how well the implied orbit fits the observed curvature, and returns a weighted sample of plausible orbits. The resulting cloud shows the full family of solutions. .. GENERATED FROM PYTHON SOURCE LINES 14-20 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np import kete .. GENERATED FROM PYTHON SOURCE LINES 21-25 Parse MPC-Format Observations ------------------------------ Four detections of CEKWD72 from G96 (Catalina Sky Survey, Mt. Lemmon) in standard 80-column MPC format, spanning about 7 minutes on 2026-04-25. .. GENERATED FROM PYTHON SOURCE LINES 25-40 .. code-block:: Python mpc_lines = [ " CEKWD72*1C2026 04 25.47779021 00 57.820-00 54 14.76 22.05GVNEOCPG96", " CEKWD72 1C2026 04 25.48209121 00 59.058-00 54 05.11 21.40GVNEOCPG96", " CEKWD72 1C2026 04 25.48639821 01 00.239-00 53 56.47 20.50GVNEOCPG96", " CEKWD72 1C2026 04 25.49071521 01 01.470-00 53 49.27 20.12GVNEOCPG96", ] mpc_obs = kete.orbit_fitting.MPCObservation.from_lines(mpc_lines) observations = kete.orbit_fitting.mpc_obs_to_observations(mpc_obs) print( f"Parsed {len(observations)} observations spanning " f"{(observations[-1].epoch.jd - observations[0].epoch.jd) * 24 * 60:.1f} minutes" ) .. rst-class:: sphx-glr-script-out .. code-block:: none Parsed 4 observations spanning 18.6 minutes .. GENERATED FROM PYTHON SOURCE LINES 41-44 Ranging ------- Scan the (rho, rho_dot) grid and draw weighted orbit samples. .. GENERATED FROM PYTHON SOURCE LINES 44-50 .. code-block:: Python samples = kete.orbit_fitting.fit_orbit_ranging(observations, num_draws=10000) print(samples) if samples.convergence_warning: print(f"Warning: {samples.convergence_warning}") .. rst-class:: sphx-glr-script-out .. code-block:: none RangingSamples(draws=10000, ess=13513.7, epoch=2461155.978591) .. GENERATED FROM PYTHON SOURCE LINES 51-55 Extract Orbital Elements ------------------------ ``draws`` returns Sun-centered Ecliptic states; each state carries orbital element accessors. We also grab the log-posterior weights for coloring. .. GENERATED FROM PYTHON SOURCE LINES 55-67 .. code-block:: Python states = samples.draws log_w = np.array(samples.log_posterior) peri_dist = np.array([s.peri_dist for s in states]) eccentricity = np.array([s.eccentricity for s in states]) inclination = np.array([s.inclination for s in states]) print(f"\nPerihelion distance: {peri_dist.min():.3f} -- {peri_dist.max():.3f} AU") print(f"Eccentricity: {eccentricity.min():.3f} -- {eccentricity.max():.3f}") print(f"Inclination: {inclination.min():.1f} -- {inclination.max():.1f} deg") .. rst-class:: sphx-glr-script-out .. code-block:: none Perihelion distance: 0.000 -- 1.488 AU Eccentricity: 0.020 -- 4.589 Inclination: 0.3 -- 167.4 deg .. GENERATED FROM PYTHON SOURCE LINES 68-72 Plot the Orbital Uncertainty Cloud ------------------------------------ Each point is one sampled orbit, colored by log-posterior weight. The spread shows the full range of solutions consistent with the short arc. .. GENERATED FROM PYTHON SOURCE LINES 72-93 .. code-block:: Python fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(7, 3), dpi=200) sc = ax1.scatter( peri_dist, eccentricity, s=1, c=log_w, cmap="RdBu", vmin=-3, vmax=0, rasterized=True ) ax1.set_xlabel("Perihelion Distance (AU)") ax1.set_ylabel("Eccentricity") ax1.set_title("Perihelion vs Eccentricity") ax1.set_ylim(0, 1.05) ax2.scatter( peri_dist, inclination, s=1, c=log_w, cmap="RdBu", vmin=-3, vmax=0, rasterized=True ) ax2.set_xlabel("Perihelion Distance (AU)") ax2.set_ylabel("Inclination (deg)") ax2.set_title("Perihelion vs Inclination") fig.colorbar(sc, ax=ax2, label="Log-posterior weight") plt.tight_layout() plt.show() .. image-sg:: /auto_examples/images/sphx_glr_plot_ranging_001.png :alt: Perihelion vs Eccentricity, Perihelion vs Inclination :srcset: /auto_examples/images/sphx_glr_plot_ranging_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.143 seconds) .. _sphx_glr_download_auto_examples_plot_ranging.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_ranging.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_ranging.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_ranging.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_