.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/ex_orbit.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. or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_ex_orbit.py: ******************* Orbit Interpolation ******************* This library facilitates the interpolation of orbit ephemerides from a template file that contains satellite positions for a single orbit cycle. It supports the propagation of the orbit over time, making it useful for simulations and other applications that require orbit propagation. To begin, we will load the orbit ephemerides from the template file. In this example, we will create a simple function to load the data from the test file. .. GENERATED FROM PYTHON SOURCE LINES 16-74 .. code-block:: Python import pathlib import cartopy.crs as ccrs import matplotlib.pyplot as plt import numpy as np import pandas as pd import pyinterp import pyinterp.tests def load_test_ephemeris( filename: pathlib.Path ) -> tuple[float, np.ndarray, np.ndarray, np.ndarray, np.timedelta64]: """Loads the ephemeris from a text file. Args: filename: Name of the file to be loaded. Returns: A tuple containing the height of the orbit, the ephemeris and the duration of the cycle. """ with open(filename) as stream: lines = stream.readlines() def to_dict(comments) -> dict[str, float]: """Returns a dictionary describing the parameters of the orbit.""" result = {} for item in comments: assert item.startswith('#'), 'Comments must start with #' key, value = item[1:].split('=') result[key.strip()] = float(value) return result # The two first lines are the header and contain the height and the # duration of the cycle in fractional days. settings = to_dict(lines[:2]) del lines[:2] # The rest of the lines are the ephemeris ephemeris = np.loadtxt(lines, delimiter=' ', dtype={ 'names': ('time', 'longitude', 'latitude', 'height'), 'formats': ('f8', 'f8', 'f8', 'f8') }) return ( settings['height'], ephemeris['longitude'], ephemeris['latitude'], ephemeris['time'].astype('timedelta64[s]'), np.timedelta64(int(settings['cycle_duration'] * 86400.0 * 1e9), 'ns'), ) .. GENERATED FROM PYTHON SOURCE LINES 75-76 Set the path to the test file .. GENERATED FROM PYTHON SOURCE LINES 76-79 .. code-block:: Python swot_calval_ephemeris_path = pyinterp.tests.swot_calval_ephemeris_path() ephemeris = load_test_ephemeris(swot_calval_ephemeris_path) .. GENERATED FROM PYTHON SOURCE LINES 80-81 Compute the orbit properties from the provided ephemeris .. GENERATED FROM PYTHON SOURCE LINES 81-83 .. code-block:: Python orbit = pyinterp.calculate_orbit(*ephemeris) .. GENERATED FROM PYTHON SOURCE LINES 84-85 The orbit object provides a method to calculate the number of passes per cycle .. GENERATED FROM PYTHON SOURCE LINES 85-87 .. code-block:: Python print(orbit.passes_per_cycle()) .. rst-class:: sphx-glr-script-out .. code-block:: none 28 .. GENERATED FROM PYTHON SOURCE LINES 88-90 To get the cycle duration, and the orbit duration we can use the `cycle_duration` method and the `orbit_duration` method respectively. .. GENERATED FROM PYTHON SOURCE LINES 90-93 .. code-block:: Python print(orbit.cycle_duration().astype('m8[ms]').item()) print(orbit.orbit_duration().astype('m8[ms]').item()) .. rst-class:: sphx-glr-script-out .. code-block:: none 23:25:23.172000 1:40:23.083000 .. GENERATED FROM PYTHON SOURCE LINES 94-95 We can also retrieve the pass duration for a given pass number: .. GENERATED FROM PYTHON SOURCE LINES 95-97 .. code-block:: Python print(orbit.pass_duration(2).astype('m8[ms]').item()) .. rst-class:: sphx-glr-script-out .. code-block:: none 0:55:44.350000 .. GENERATED FROM PYTHON SOURCE LINES 98-103 A utility function is provided to compute an absolute pass number from a relative pass number and to decode the absolute pass number back into a relative pass number. This function is useful for storing the pass number in a database or indexing the passes in a file, among other applications. .. GENERATED FROM PYTHON SOURCE LINES 103-110 .. code-block:: Python absolute_pass_number = orbit.encode_absolute_pass_number(cycle_number=11, pass_number=2) print(absolute_pass_number) cycle_number, pass_number = orbit.decode_absolute_pass_number( absolute_pass_number) print(cycle_number, pass_number) .. rst-class:: sphx-glr-script-out .. code-block:: none 282 11 2 .. GENERATED FROM PYTHON SOURCE LINES 111-128 The online documentation provides more information about the available methods for the this object: :py:class:`Orbit `. The next step is to interpolate the orbit ephemerides over time to get the satellite positions for a given relative pass number. .. note:: Is it possible to iterate over the relative pass numbers over time periods using the :py:meth:`iterate ` method. .. code:: python for cycle_number, pass_number, first_location_date in orbit.iterate( start_date, end_date): ... .. GENERATED FROM PYTHON SOURCE LINES 128-136 .. code-block:: Python nadir_pass_corrdinates = pyinterp.calculate_pass(2, orbit) assert nadir_pass_corrdinates is not None pd.DataFrame({ 'time': nadir_pass_corrdinates.time, 'lon_nadir': nadir_pass_corrdinates.lon_nadir, 'lat_nadir': nadir_pass_corrdinates.lat_nadir, }) .. raw:: html
time lon_nadir lat_nadir
0 0 days 00:25:53.799409419 -29.393586 -77.497916
1 0 days 00:25:54.519992305 -29.310591 -77.497883
2 0 days 00:25:55.241146762 -29.227597 -77.497825
3 0 days 00:25:55.962772250 -29.144604 -77.497741
4 0 days 00:25:56.684960867 -29.061612 -77.497632
... ... ... ...
9953 0 days 01:21:25.850882766 146.412747 77.727877
9954 0 days 01:21:28.310619399 146.497271 77.727982
9955 0 days 01:21:30.770464201 146.581797 77.728059
9956 0 days 01:21:33.230367978 146.666324 77.728106
9957 0 days 01:21:35.690281545 146.750851 77.728124

9958 rows × 3 columns



.. GENERATED FROM PYTHON SOURCE LINES 137-139 .. code-block:: Python print(nadir_pass_corrdinates.equator_coordinates) .. rst-class:: sphx-glr-script-out .. code-block:: none EquatorCoordinates(longitude=59.20360095529902, time=np.timedelta64(3087382968771,'ns')) .. GENERATED FROM PYTHON SOURCE LINES 140-159 The variable `nadir_pass_corrdinates` contains the satellite positions for the given pass: - The nadir longitude in degrees - The nadir latitude in degrees - The time for each position in a numpy.datetime64 array - The along track distance in meters - And the coordinates of the satellite at the equator. .. note:: The variable `nadir_pass_corrdinates` could be `None` if the pass number is outside the bounding box defined during the instantiation of the :py:class:`Orbit ` object. See the online documentation for more information about the available methods for the :py:class:`Pass ` object. Finally, we can calculate the satellite positions for a given pass number over a swath. .. GENERATED FROM PYTHON SOURCE LINES 159-162 .. code-block:: Python assert nadir_pass_corrdinates is not None swath = pyinterp.calculate_swath(nadir_pass_corrdinates) .. GENERATED FROM PYTHON SOURCE LINES 163-166 The `swath` object contains the properties of the pass, similar to the previous example. Additionally, it includes the coordinates of the satellite over the swath for each location on the nadir track. .. GENERATED FROM PYTHON SOURCE LINES 166-172 .. code-block:: Python pd.DataFrame({ 'time': swath.time, 'lon_nadir': swath.lon_nadir, 'lat_nadir': swath.lat_nadir, }) .. raw:: html
time lon_nadir lat_nadir
0 0 days 00:25:53.799409419 -29.393586 -77.497916
1 0 days 00:25:54.519992305 -29.310591 -77.497883
2 0 days 00:25:55.241146762 -29.227597 -77.497825
3 0 days 00:25:55.962772250 -29.144604 -77.497741
4 0 days 00:25:56.684960867 -29.061612 -77.497632
... ... ... ...
9953 0 days 01:21:25.850882766 146.412747 77.727877
9954 0 days 01:21:28.310619399 146.497271 77.727982
9955 0 days 01:21:30.770464201 146.581797 77.728059
9956 0 days 01:21:33.230367978 146.666324 77.728106
9957 0 days 01:21:35.690281545 146.750851 77.728124

9958 rows × 3 columns



.. GENERATED FROM PYTHON SOURCE LINES 173-176 The DataFrame `df` shows the longitude and latitude coordinates of the satellite for the first two lines of the swath. The index `x_ac` represents the across-track distance in meters. .. GENERATED FROM PYTHON SOURCE LINES 176-188 .. code-block:: Python df = pd.DataFrame( { 'lon_0': swath.lon[0, :], 'lon_1': swath.lon[1, :], 'lat_0': swath.lat[0, :], 'lat_1': swath.lat[1, :], }, index=swath.x_ac[0, :], ) df.index.name = 'x_ac' df .. raw:: html
lon_0 lon_1 lat_0 lat_1
x_ac
-70000.0 -29.396648 -29.317550 -76.870888 -76.870857
-68000.0 -29.396565 -29.317360 -76.888803 -76.888772
-66000.0 -29.396481 -29.317170 -76.906719 -76.906688
-64000.0 -29.396397 -29.316979 -76.924634 -76.924603
-62000.0 -29.396312 -29.316788 -76.942550 -76.942519
... ... ... ... ...
62000.0 -29.390618 -29.303828 -78.053251 -78.053217
64000.0 -29.390518 -29.303599 -78.071164 -78.071130
66000.0 -29.390417 -29.303370 -78.089078 -78.089044
68000.0 -29.390317 -29.303140 -78.106991 -78.106957
70000.0 -29.390216 -29.302910 -78.124905 -78.124871

70 rows × 4 columns



.. GENERATED FROM PYTHON SOURCE LINES 189-190 We can plot the satellite positions over the swath using the following code: .. GENERATED FROM PYTHON SOURCE LINES 190-217 .. code-block:: Python fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(20, 10), subplot_kw={'projection': ccrs.PlateCarree()}) # Zoomed plot ax1.set_extent([58, 70, 12, 32], crs=ccrs.PlateCarree()) ax1.plot(swath.lon[::4, ::4].ravel(), swath.lat[::4, ::4].ravel(), 'b.', markersize=1) ax1.plot(swath.lon_nadir, swath.lat_nadir, 'r.', markersize=0.5) ax1.set_title('Satellite positions - Zoomed') ax1.coastlines() ax1.gridlines(draw_labels=True) # Full swath plot ax2.plot(swath.lon.ravel(), swath.lat.ravel(), 'b.', markersize=1) ax2.plot(swath.lon_nadir, swath.lat_nadir, 'r.', markersize=0.5) ax2.set_title('Satellite positions - Full Swath') ax2.coastlines() ax2.gridlines(draw_labels=True) ax1.set_aspect('auto') ax2.set_aspect('auto') plt.show() .. image-sg:: /auto_examples/images/sphx_glr_ex_orbit_001.png :alt: Satellite positions - Zoomed, Satellite positions - Full Swath :srcset: /auto_examples/images/sphx_glr_ex_orbit_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.885 seconds) .. _sphx_glr_download_auto_examples_ex_orbit.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/CNES/pangeo-pyinterp/master?urlpath=lab/tree/notebooks/auto_examples/ex_orbit.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: ex_orbit.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: ex_orbit.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: ex_orbit.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_