.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/plot_observability.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_observability.py: Plot observability of an object =============================== Plot the observability of a given object from a position on the Earth. Given the following information: - Observers location on Earth in latitude/longitude. - Name of the object. - A start and stop date range. This then plot various information about how observable the object is over the date range. The first 3 plots are relatively self explanatory, the final of the plots is more complex. It plots the amount of time that the object is visible during the night. Specifically, it counts the total number of hours which the object is above the specified elevation. The dotted black line corresponds to the total length of the night as defined exactly sunset and sunrise at the observers location. .. GENERATED FROM PYTHON SOURCE LINES 21-167 .. image-sg:: /auto_examples/images/sphx_glr_plot_observability_001.png :alt: Eros :srcset: /auto_examples/images/sphx_glr_plot_observability_001.png :class: sphx-glr-single-img .. code-block:: Python import matplotlib.pyplot as plt import matplotlib.dates as mdates import numpy as np import kete # Inputs: # ------- obj = kete.HorizonsProperties.fetch("Eros", update_name=False) start_time = kete.Time.from_ymd(2024, 11, 1).jd end_time = kete.Time.from_ymd(2025, 11, 1).jd # Observers position: site = "Palomar Mountain" # Plotting: # --------- n_steps = 1000 times = np.linspace(start_time, end_time, n_steps) g_phase = 0.15 if obj.g_phase is None or np.isnan(obj.g_phase) else obj.g_phase if obj.g_phase is None: print("Horizons doesn't contain a g parameter for this object, assuming 0.15!") if obj.h_mag is None: print("Horizons doesn't have an h mag for this object, no mags will be computed!") state = kete.propagate_n_body([obj.state], start_time)[0] mags = [] solar_elon = [] phases = [] dist = [] sun_dist = [] for t in times: # For each time, compute the geometry, then compute the mag as well as all of the # various angle and distance values. state = kete.propagate_n_body([state], t)[0] sun2obs = kete.spice.mpc_code_to_ecliptic(site, t).pos earth2obs = kete.spice.mpc_code_to_ecliptic(site, t, center="399").pos sun2obj = state.pos obs2obj = -sun2obs + sun2obj # if we cannot compute mag, set the mag to NAN and keep moving if obj.h_mag is not None: mag = kete.flux.hg_apparent_mag( sun2obj=sun2obj, sun2obs=sun2obs, h_mag=obj.h_mag, g_param=g_phase ) mag = np.clip(mag, -1000, 1000) else: mag = np.nan mags.append(mag) sun_dist.append(sun2obj.r) solar_elon.append((-sun2obs).angle_between(obs2obj)) phases.append((-sun2obj).angle_between(-obs2obj)) dist.append(obs2obj.r) dates = [kete.Time(t).to_datetime() for t in times] plt.figure(dpi=150, figsize=(8, 5)) plt.suptitle(f"{obj.desig}") plt.subplot(221) plt.plot(dates, sun_dist, c="C2", label=r"$r_H$") plt.plot(dates, dist, c="C3", label=r"$\Delta$") plt.ylabel("Distance (AU)") plt.legend() plt.xticks([]) plt.subplot(222) plt.plot(dates, solar_elon, c="C1", label="Elongation") plt.plot(dates, phases, c="C4", label="Phase") plt.ylabel("Angle (deg)") plt.legend() plt.xticks([]) plt.subplot(223) plt.plot(dates, mags) plt.gca().invert_yaxis() plt.ylabel("Mag") plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%Y/%m/%d")) plt.gcf().autofmt_xdate() plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator()) plt.gca().xaxis.set_minor_locator(mdates.MonthLocator()) plt.subplot(224) # Final plot is more complicated, it requires looking at batched intervals of time that # are at least 1 full day, preferably several days. # During this interval, the average length of time the object is visible is computed # during local night at the observers location. step_size = 3 day_steps = np.arange(start_time, end_time, step_size) # Substeps are done at 6 minute intervals substeps = np.linspace(0, step_size, 24 * 10 * step_size) substep_time = np.diff(substeps)[0] elevations = [] night_len = [] for t in day_steps: elevation = [] state = kete.propagate_n_body([state], t + substep_time / 2)[0] nights = [] for subrange in substeps: approx_state = kete.propagate_two_body([state], t + subrange)[0] sun2obs = kete.spice.mpc_code_to_ecliptic(site, t + subrange).pos earth2obs = kete.spice.mpc_code_to_ecliptic( site, t + subrange, center="399" ).pos sun2obj = approx_state.pos obs2obj = sun2obj - sun2obs cur_alt = 90 - earth2obs.angle_between(obs2obj) night = earth2obs.angle_between(-sun2obs) > 90 nights.append(night) if night: elevation.append(cur_alt) night_len.append(sum(nights) * substep_time) elevations.append(elevation) dates = [kete.Time(t + step_size / 2).to_datetime() for t in day_steps] for ang in [0, 15, 30, 45, 60, 75]: plt.plot( dates, [sum(np.array(a) > ang) * substep_time * 24 / step_size for a in elevations], label=f"{ang}" + r"$^{\circ}$", ) plt.plot(dates, np.array(night_len) * 24 / step_size, ls="--", c="k", label="Night") plt.gca().legend(loc="center left", bbox_to_anchor=(1, 0.5)) plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%Y/%m/%d")) plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator()) plt.gca().xaxis.set_minor_locator(mdates.MonthLocator()) plt.gcf().autofmt_xdate() plt.ylabel("Hours above Altitude") plt.tight_layout() plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.606 seconds) .. _sphx_glr_download_auto_examples_plot_observability.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_observability.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_observability.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_observability.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_