{ "cells": [ { "cell_type": "markdown", "id": "512def2e-ec76-47d5-92d0-1ace1d51414c", "metadata": {}, "source": [ "## Accessing Sentinel-3 SRAL data with the Planetary Computer STAC API\n", "\n", "The [Sentinel 3 SRAL instrument](https://sentinel.esa.int/web/sentinel/technical-guides/sentinel-3-altimetry) uses Synthetic Aperture Radar (SAR) to measure surface height, significant wave height, and wind speed over the ocean surface.\n", "There are two SRAL collections in the Plantery Computer:\n", "\n", "- Land measurements: `sentinel-3-sral-lan-l2-netcdf`\n", "- Water measurements: `sentinel-3-slstr-wat-l2-netcdf`\n", "\n", "This notebook demonstrates accessing and visualizing data from both collections.\n", "\n", "### Data Access\n", "\n", "This notebook works with or without an API key, but you will be given more permissive access to the data with an API key. If you are using the [Planetary Computer Hub](https://planetarycomputer.microsoft.com/compute) to run this notebook, then your API key is automatically set to the environment variable `PC_SDK_SUBSCRIPTION_KEY` for you when your server is started. Otherwise, you can view your keys by signing in to the [developer portal](https://planetarycomputer.developer.azure-api.net/). The API key may be manually set via the environment variable `PC_SDK_SUBSCRIPTION_KEY` or the following code:\n", "\n", "```python\n", "import planetary_computer\n", "planetary_computer.settings.set_subscription_key()\n", "```\n", "\n", "The datasets hosted by the Planetary Computer are available in [Azure Blob Storage](https://docs.microsoft.com/en-us/azure/storage/blobs/). We'll use [pystac-client](https://pystac-client.readthedocs.io/) to search the Planetary Computer's [STAC API](https://planetarycomputer.microsoft.com/api/stac/v1/docs) for the subset of the data that we care about, and then we'll load the data directly from Azure Blob Storage. We'll specify a `modifier` so that we can access the data stored in the Planetary Computer's private Blob Storage Containers. See [Reading from the STAC API](https://planetarycomputer.microsoft.com/docs/quickstarts/reading-stac/) and [Using tokens for data access](https://planetarycomputer.microsoft.com/docs/concepts/sas/) for more.\n", "\n" ] }, { "cell_type": "markdown", "id": "e11587aa", "metadata": {}, "source": [ "### Water measurements\n", "\n", "The collection's description provides more information about the water product." ] }, { "cell_type": "code", "execution_count": 1, "id": "8b9c7b88", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/markdown": [ "### sentinel-3-sral-wat-l2-netcdf\n", "\n", "This Collection provides Sentinel-3 [SRAL Level-2 Ocean Altimetry](https://sentinel.esa.int/web/sentinel/technical-guides/sentinel-3-altimetry/level-2-algorithms-products) products, which contain data on ocean radar altimetry measurements. Each product contains three NetCDF files:\n", "\n", "- A reduced data file containing a subset of the 1 Hz Ku-band parameters.\n", "- A standard data file containing the standard 1 Hz and 20 Hz Ku- and C-band parameters.\n", "- An enhanced data file containing the standard 1 Hz and 20 Hz Ku- and C-band parameters along with the waveforms and parameters necessary to reprocess the data.\n", "\n", "More information about the product and data processing can be found in the [User Guide](https://sentinels.copernicus.eu/web/sentinel/user-guides/sentinel-3-altimetry/overview) and [Technical Guide](https://sentinel.esa.int/web/sentinel/technical-guides/sentinel-3-altimetry).\n", "\n", "This Collection contains Level-2 data in NetCDF files from January 2017 to present.\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import planetary_computer\n", "import pystac_client\n", "from IPython.display import display, Markdown\n", "\n", "catalog = pystac_client.Client.open(\n", " \"http://planetarycomputer.microsoft.com/api/stac/v1\",\n", " modifier=planetary_computer.sign_inplace,\n", ")\n", "collection = catalog.get_collection(\"sentinel-3-sral-wat-l2-netcdf\")\n", "\n", "display(Markdown(f\"### {collection.id}\\n\\n{collection.description}\"))" ] }, { "cell_type": "markdown", "id": "dfe7f4ae-d5fd-494c-87e4-fc8010f524c7", "metadata": {}, "source": [ "### Define the area of interest and search the water collection\n", "\n", "We'll search for items.\n", "Since this is an altimetry product, the swaths of data are very narrow, making a point-based search unrealistic.\n", "We search for any product that intersects the Gulf of Mexico." ] }, { "cell_type": "code", "execution_count": 2, "id": "3b7ff72d-9d8c-4505-b0dd-65ab5e4fd182", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "import xarray as xr\n", "import fsspec\n", "\n", "geometry = {\n", " \"type\": \"Polygon\",\n", " \"coordinates\": [\n", " [\n", " [-95.8376336, 28.3457752],\n", " [-92.3259525, 29.3100131],\n", " [-89.5198038, 28.8301497],\n", " [-87.049173, 30.183914],\n", " [-83.1468269, 28.6421247],\n", " [-81.6808886, 23.9413637],\n", " [-85.0055647, 22.0886049],\n", " [-90.4653539, 21.4938454],\n", " [-90.8618749, 19.4939949],\n", " [-92.9054832, 18.7158187],\n", " [-96.1081528, 19.1774025],\n", " [-97.6942368, 23.4665839],\n", " [-95.8376336, 28.3457752],\n", " ]\n", " ],\n", "}\n", "search = catalog.search(\n", " collections=[\"sentinel-3-sral-wat-l2-netcdf\"], intersects=geometry\n", ")\n", "item = next(search.items())" ] }, { "cell_type": "markdown", "id": "46ff6ec3-ae8f-4e2e-96fc-c7b3726c8bd8", "metadata": {}, "source": [ "### Available Assets and Metadata\n", "\n", "Each item includes a handful of assets linking to NetCDF files with the data or additional metadata files." ] }, { "cell_type": "code", "execution_count": 3, "id": "4a9b22f3-3b64-4642-8416-52f0edeeabb6", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/html": [ "
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃ Key                   Value                                                                                    ┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│ eop-metadata         │ Product metadata file produced by the European Organisation for the Exploitation of      │\n",
       "│                      │ Meteorological Satellites (EUMETSAT)                                                     │\n",
       "│ safe-manifest        │ SAFE product manifest                                                                    │\n",
       "│ reduced-measurement  │ Reduced measurement data file                                                            │\n",
       "│ enhanced-measurement │ Enhanced measurement data file                                                           │\n",
       "│ standard-measurement │ Standard measurement data file                                                           │\n",
       "└──────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────┘\n",
       "
\n" ], "text/plain": [ "┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mKey \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mValue \u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", "│ eop-metadata │ Product metadata file produced by the European Organisation for the Exploitation of │\n", "│ │ Meteorological Satellites (EUMETSAT) │\n", "│ safe-manifest │ SAFE product manifest │\n", "│ reduced-measurement │ Reduced measurement data file │\n", "│ enhanced-measurement │ Enhanced measurement data file │\n", "│ standard-measurement │ Standard measurement data file │\n", "└──────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────┘\n" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import rich.table\n", "\n", "t = rich.table.Table(\"Key\", \"Value\")\n", "for key, asset in item.assets.items():\n", " t.add_row(key, asset.description)\n", "\n", "t" ] }, { "cell_type": "markdown", "id": "599fa91b-d2d9-428f-adf2-f79d9a3821e6", "metadata": {}, "source": [ "### Reading data\n", "\n", "We can use xarray to read each NetCDF file directly from Blob Storage." ] }, { "cell_type": "code", "execution_count": 4, "id": "503bbecb-12f2-4910-834f-d58d29694cb4", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset>\n",
       "Dimensions:                                        (time_01: 1687,\n",
       "                                                    time_20_ku: 33611,\n",
       "                                                    time_20_c: 32900)\n",
       "Coordinates:\n",
       "  * time_01                                        (time_01) datetime64[ns] 2...\n",
       "  * time_20_ku                                     (time_20_ku) datetime64[ns] ...\n",
       "  * time_20_c                                      (time_20_c) datetime64[ns] ...\n",
       "    lat_01                                         (time_01) float64 ...\n",
       "    lon_01                                         (time_01) float64 ...\n",
       "    lat_20_ku                                      (time_20_ku) float64 ...\n",
       "    lon_20_ku                                      (time_20_ku) float64 ...\n",
       "    lat_20_c                                       (time_20_c) float64 ...\n",
       "    lon_20_c                                       (time_20_c) float64 ...\n",
       "Data variables: (12/294)\n",
       "    UTC_day_01                                     (time_01) datetime64[ns] ...\n",
       "    UTC_sec_01                                     (time_01) float64 ...\n",
       "    UTC_day_20_ku                                  (time_20_ku) datetime64[ns] ...\n",
       "    UTC_sec_20_ku                                  (time_20_ku) float64 ...\n",
       "    UTC_day_20_c                                   (time_20_c) datetime64[ns] ...\n",
       "    UTC_sec_20_c                                   (time_20_c) float64 ...\n",
       "    ...                                             ...\n",
       "    num_20hz_meas_01_ku                            (time_01) float32 ...\n",
       "    num_20hz_meas_01_c                             (time_01) float32 ...\n",
       "    orbit_type_01                                  (time_01) float32 ...\n",
       "    waveform_qual_ice_20_ku                        (time_20_ku) float32 ...\n",
       "    iono_cor_alt_filtered_01_ku                    (time_01) float32 ...\n",
       "    iono_cor_alt_filtered_01_plrm_ku               (time_01) float32 ...\n",
       "Attributes: (12/62)\n",
       "    Conventions:                                 CF-1.6\n",
       "    title:                                       IPF SRAL/MWR Level 2 Measure...\n",
       "    mission_name:                                Sentinel 3A\n",
       "    altimeter_sensor_name:                       SRAL\n",
       "    radiometer_sensor_name:                      MWR\n",
       "    gnss_sensor_name:                            GNSS\n",
       "    ...                                          ...\n",
       "    algo_bias_wind_speed_sig0_sar_ku_added:      -0.0413\n",
       "    algo_bias_wind_speed_2p_sig0_sar_ku_added:   2.744\n",
       "    algo_bias_wind_speed_2p_swh_sar_ku_added:    0.0\n",
       "    algo_bias_wind_speed_sig0_plrm_ku_added:     -0.0382\n",
       "    algo_bias_wind_speed_2p_sig0_plrm_ku_added:  2.7525\n",
       "    algo_bias_wind_speed_2p_swh_plrm_ku_added:   0.0
" ], "text/plain": [ "\n", "Dimensions: (time_01: 1687,\n", " time_20_ku: 33611,\n", " time_20_c: 32900)\n", "Coordinates:\n", " * time_01 (time_01) datetime64[ns] 2...\n", " * time_20_ku (time_20_ku) datetime64[ns] ...\n", " * time_20_c (time_20_c) datetime64[ns] ...\n", " lat_01 (time_01) float64 ...\n", " lon_01 (time_01) float64 ...\n", " lat_20_ku (time_20_ku) float64 ...\n", " lon_20_ku (time_20_ku) float64 ...\n", " lat_20_c (time_20_c) float64 ...\n", " lon_20_c (time_20_c) float64 ...\n", "Data variables: (12/294)\n", " UTC_day_01 (time_01) datetime64[ns] ...\n", " UTC_sec_01 (time_01) float64 ...\n", " UTC_day_20_ku (time_20_ku) datetime64[ns] ...\n", " UTC_sec_20_ku (time_20_ku) float64 ...\n", " UTC_day_20_c (time_20_c) datetime64[ns] ...\n", " UTC_sec_20_c (time_20_c) float64 ...\n", " ... ...\n", " num_20hz_meas_01_ku (time_01) float32 ...\n", " num_20hz_meas_01_c (time_01) float32 ...\n", " orbit_type_01 (time_01) float32 ...\n", " waveform_qual_ice_20_ku (time_20_ku) float32 ...\n", " iono_cor_alt_filtered_01_ku (time_01) float32 ...\n", " iono_cor_alt_filtered_01_plrm_ku (time_01) float32 ...\n", "Attributes: (12/62)\n", " Conventions: CF-1.6\n", " title: IPF SRAL/MWR Level 2 Measure...\n", " mission_name: Sentinel 3A\n", " altimeter_sensor_name: SRAL\n", " radiometer_sensor_name: MWR\n", " gnss_sensor_name: GNSS\n", " ... ...\n", " algo_bias_wind_speed_sig0_sar_ku_added: -0.0413\n", " algo_bias_wind_speed_2p_sig0_sar_ku_added: 2.744\n", " algo_bias_wind_speed_2p_swh_sar_ku_added: 0.0\n", " algo_bias_wind_speed_sig0_plrm_ku_added: -0.0382\n", " algo_bias_wind_speed_2p_sig0_plrm_ku_added: 2.7525\n", " algo_bias_wind_speed_2p_swh_plrm_ku_added: 0.0" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dataset = xr.open_dataset(fsspec.open(item.assets[\"standard-measurement\"].href).open())\n", "dataset" ] }, { "cell_type": "markdown", "id": "edb37542-993a-4f85-b80c-3f0c3f1f6fb4", "metadata": {}, "source": [ "### Visualizing\n", "\n", "There's a huge numbers of variables here, and going into detail on them is beyond the scope of this example.\n", "To demonstrate data access and visualization, we'll plot a significant wave height value, `swh_ocean_01_ku`.\n", "This is 1HZ data from the KU band of the altimeter.\n", "Significant wave height is [\"an average measurement of the largest 33% of waves.\"](https://www.weather.gov/mfl/waves)" ] }, { "cell_type": "code", "execution_count": 5, "id": "6d8b5d8e", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
longitudelatitudeswh
155-49.801750-69.6748710.113000
156-49.878709-69.6215770.530000
157-49.955304-69.5682520.889000
164-50.481525-69.1941440.461000
165-50.555308-69.1405830.266000
............
1432-113.04560772.68289313.717001
1436-113.46592772.8875010.859000
1506-122.66384076.302961-0.199000
1507-122.82611076.3488860.178000
1654-162.14304781.2002640.441000
\n", "

1071 rows × 3 columns

\n", "
" ], "text/plain": [ " longitude latitude swh\n", "155 -49.801750 -69.674871 0.113000\n", "156 -49.878709 -69.621577 0.530000\n", "157 -49.955304 -69.568252 0.889000\n", "164 -50.481525 -69.194144 0.461000\n", "165 -50.555308 -69.140583 0.266000\n", "... ... ... ...\n", "1432 -113.045607 72.682893 13.717001\n", "1436 -113.465927 72.887501 0.859000\n", "1506 -122.663840 76.302961 -0.199000\n", "1507 -122.826110 76.348886 0.178000\n", "1654 -162.143047 81.200264 0.441000\n", "\n", "[1071 rows x 3 columns]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas\n", "\n", "data = pandas.DataFrame(\n", " {\n", " # Longitude values are between zero and 360, so we remap them to -180 to 180.\n", " \"longitude\": (dataset.lon_01.data.ravel() + 180) % 360 - 180,\n", " \"latitude\": dataset.lat_01.data.ravel(),\n", " \"swh\": dataset.swh_ocean_01_ku.load().data.ravel(),\n", " }\n", ").dropna()\n", "data" ] }, { "cell_type": "code", "execution_count": 11, "id": "63fa6014", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import shapely.geometry\n", "from cartopy.crs import PlateCarree\n", "import matplotlib.pyplot as plt\n", "\n", "fig, ax = plt.subplots(\n", " subplot_kw=dict(projection=PlateCarree()),\n", " figsize=(12, 8),\n", ")\n", "\n", "ax.add_geometries(\n", " shapely.geometry.shape(item.geometry),\n", " crs=PlateCarree(),\n", " color=\"coral\",\n", " alpha=0.1,\n", ")\n", "\n", "data.plot.scatter(\n", " x=\"longitude\",\n", " y=\"latitude\",\n", " c=\"swh\",\n", " ax=ax,\n", " colormap=\"viridis\",\n", " marker=\".\",\n", " alpha=0.8,\n", ")\n", "ax.coastlines();" ] }, { "cell_type": "markdown", "id": "d4eb1ffc", "metadata": {}, "source": [ "Not very interesting.\n", "Let's try the mean sea surface height stored in `mean_sea_surf_sol1_01`." ] }, { "cell_type": "code", "execution_count": 13, "id": "df31941b", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "data = pandas.DataFrame(\n", " {\n", " # Longitude values are between zero and 360, so we remap them to -180 to 180.\n", " \"longitude\": (dataset.lon_01.data.ravel() + 180) % 360 - 180,\n", " \"latitude\": dataset.lat_01.data.ravel(),\n", " \"ssh\": dataset.mean_sea_surf_sol1_01.load().data.ravel(),\n", " }\n", ").dropna()\n", "fig, ax = plt.subplots(\n", " subplot_kw=dict(projection=PlateCarree()),\n", " figsize=(12, 8),\n", ")\n", "\n", "ax.add_geometries(\n", " shapely.geometry.shape(item.geometry),\n", " crs=PlateCarree(),\n", " color=\"coral\",\n", " alpha=0.1,\n", ")\n", "\n", "data.plot.scatter(\n", " x=\"longitude\",\n", " y=\"latitude\",\n", " c=\"ssh\",\n", " ax=ax,\n", " colormap=\"viridis\",\n", " marker=\".\",\n", " alpha=0.2,\n", ")\n", "ax.coastlines();" ] }, { "cell_type": "markdown", "id": "8557d45b", "metadata": {}, "source": [ "### Land data\n", "\n", "Let's do the same process, but for the land product, which is very similar to the water product but just processed by a different centre.\n", "We'll use the reduced NetCDF this time, which has the most useful subset of variables.\n", "We'll plot `mean_dyn_topo_01`, which is the mean dynamic topography." ] }, { "cell_type": "code", "execution_count": 14, "id": "5c09ff0d", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/markdown": [ "### sentinel-3-sral-lan-l2-netcdf\n", "\n", "This Collection provides Sentinel-3 [SRAL Level-2 Land Altimetry](https://sentinel.esa.int/web/sentinel/technical-guides/sentinel-3-altimetry/level-2-algorithms-products) products, which contain data on land radar altimetry measurements. Each product contains three NetCDF files:\n", "\n", "- A reduced data file containing a subset of the 1 Hz Ku-band parameters.\n", "- A standard data file containing the standard 1 Hz and 20 Hz Ku- and C-band parameters.\n", "- An enhanced data file containing the standard 1 Hz and 20 Hz Ku- and C-band parameters along with the waveforms and parameters necessary to reprocess the data.\n", "\n", "More information about the product and data processing can be found in the [User Guide](https://sentinels.copernicus.eu/web/sentinel/user-guides/sentinel-3-altimetry/overview) and [Technical Guide](https://sentinel.esa.int/web/sentinel/technical-guides/sentinel-3-altimetry).\n", "\n", "This Collection contains Level-2 data in NetCDF files from March 2016 to present.\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "collection = catalog.get_collection(\"sentinel-3-sral-lan-l2-netcdf\")\n", "\n", "display(Markdown(f\"### {collection.id}\\n\\n{collection.description}\"))" ] }, { "cell_type": "code", "execution_count": 15, "id": "dffcec76", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/html": [ "
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃ Key                   Value                          ┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│ safe-manifest        │ SAFE product manifest          │\n",
       "│ reduced-measurement  │ Reduced measurement data file  │\n",
       "│ enhanced-measurement │ Enhanced measurement data file │\n",
       "│ standard-measurement │ Standard measurement data file │\n",
       "└──────────────────────┴────────────────────────────────┘\n",
       "
\n" ], "text/plain": [ "┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mKey \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mValue \u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", "│ safe-manifest │ SAFE product manifest │\n", "│ reduced-measurement │ Reduced measurement data file │\n", "│ enhanced-measurement │ Enhanced measurement data file │\n", "│ standard-measurement │ Standard measurement data file │\n", "└──────────────────────┴────────────────────────────────┘\n" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "search = catalog.search(\n", " collections=[\"sentinel-3-sral-lan-l2-netcdf\"],\n", " intersects=geometry,\n", ")\n", "item = next(search.items())\n", "t = rich.table.Table(\"Key\", \"Value\")\n", "for key, asset in item.assets.items():\n", " t.add_row(key, asset.description)\n", "\n", "t" ] }, { "cell_type": "code", "execution_count": 16, "id": "0dc20f6b", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset>\n",
       "Dimensions:                             (time_01: 1548)\n",
       "Coordinates:\n",
       "  * time_01                             (time_01) datetime64[ns] 2023-04-07T1...\n",
       "    lat_01                              (time_01) float64 ...\n",
       "    lon_01                              (time_01) float64 ...\n",
       "Data variables: (12/47)\n",
       "    UTC_day_01                          (time_01) datetime64[ns] ...\n",
       "    UTC_sec_01                          (time_01) float64 ...\n",
       "    surf_type_01                        (time_01) float32 ...\n",
       "    surf_class_01                       (time_01) float32 ...\n",
       "    rad_surf_type_01                    (time_01) float32 ...\n",
       "    alt_01                              (time_01) float64 ...\n",
       "    ...                                  ...\n",
       "    rain_flag_01_plrm_ku                (time_01) float32 ...\n",
       "    open_sea_ice_flag_01_ku             (time_01) float32 ...\n",
       "    open_sea_ice_flag_01_plrm_ku        (time_01) float32 ...\n",
       "    orbit_type_01                       (time_01) float32 ...\n",
       "    iono_cor_alt_filtered_01_ku         (time_01) float32 ...\n",
       "    iono_cor_alt_filtered_01_plrm_ku    (time_01) float32 ...\n",
       "Attributes: (12/45)\n",
       "    Conventions:                       CF-1.6\n",
       "    title:                             IPF SRAL/MWR Level 2 Measurement\n",
       "    mission_name:                      Sentinel 3B\n",
       "    altimeter_sensor_name:             SRAL\n",
       "    radiometer_sensor_name:            MWR\n",
       "    gnss_sensor_name:                  GNSS\n",
       "    ...                                ...\n",
       "    xref_iono_data:                    S3B_SR_2_RGI_AX_20230407T000000_202304...\n",
       "    xref_mog2d_data:                   S3__SR_2_RMO_AX_20230407T120000_202304...\n",
       "    xref_seaice_concentration:         S3__SR_2_SIC_AX_20230405T000000_202304...\n",
       "    xref_altimeter_ltm:                S3B_SR_1_CA1LAX_20000101T000000_202305...\n",
       "    xref_doris_uso:                    S3B_SR_1_USO_AX_20180501T144459_202304...\n",
       "    xref_time_correlation:             S3B_AX___FRO_AX_20230407T000000_202304...
" ], "text/plain": [ "\n", "Dimensions: (time_01: 1548)\n", "Coordinates:\n", " * time_01 (time_01) datetime64[ns] 2023-04-07T1...\n", " lat_01 (time_01) float64 ...\n", " lon_01 (time_01) float64 ...\n", "Data variables: (12/47)\n", " UTC_day_01 (time_01) datetime64[ns] ...\n", " UTC_sec_01 (time_01) float64 ...\n", " surf_type_01 (time_01) float32 ...\n", " surf_class_01 (time_01) float32 ...\n", " rad_surf_type_01 (time_01) float32 ...\n", " alt_01 (time_01) float64 ...\n", " ... ...\n", " rain_flag_01_plrm_ku (time_01) float32 ...\n", " open_sea_ice_flag_01_ku (time_01) float32 ...\n", " open_sea_ice_flag_01_plrm_ku (time_01) float32 ...\n", " orbit_type_01 (time_01) float32 ...\n", " iono_cor_alt_filtered_01_ku (time_01) float32 ...\n", " iono_cor_alt_filtered_01_plrm_ku (time_01) float32 ...\n", "Attributes: (12/45)\n", " Conventions: CF-1.6\n", " title: IPF SRAL/MWR Level 2 Measurement\n", " mission_name: Sentinel 3B\n", " altimeter_sensor_name: SRAL\n", " radiometer_sensor_name: MWR\n", " gnss_sensor_name: GNSS\n", " ... ...\n", " xref_iono_data: S3B_SR_2_RGI_AX_20230407T000000_202304...\n", " xref_mog2d_data: S3__SR_2_RMO_AX_20230407T120000_202304...\n", " xref_seaice_concentration: S3__SR_2_SIC_AX_20230405T000000_202304...\n", " xref_altimeter_ltm: S3B_SR_1_CA1LAX_20000101T000000_202305...\n", " xref_doris_uso: S3B_SR_1_USO_AX_20180501T144459_202304...\n", " xref_time_correlation: S3B_AX___FRO_AX_20230407T000000_202304..." ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dataset = xr.open_dataset(fsspec.open(item.assets[\"reduced-measurement\"].href).open())\n", "dataset" ] }, { "cell_type": "code", "execution_count": 17, "id": "f8235acd", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
longitudelatitudetopography
0359.15570581.413514-0.3510
1358.75518081.412293-0.3493
2358.35478681.410668-0.3371
3357.95456081.408639-0.3336
4357.55453781.406205-0.3287
............
1330225.251033-74.585162-1.1825
1331225.121916-74.633909-1.1828
1332224.992024-74.682586-1.1833
1333224.729891-74.779726-1.1839
1334224.597637-74.828188-1.1841
\n", "

627 rows × 3 columns

\n", "
" ], "text/plain": [ " longitude latitude topography\n", "0 359.155705 81.413514 -0.3510\n", "1 358.755180 81.412293 -0.3493\n", "2 358.354786 81.410668 -0.3371\n", "3 357.954560 81.408639 -0.3336\n", "4 357.554537 81.406205 -0.3287\n", "... ... ... ...\n", "1330 225.251033 -74.585162 -1.1825\n", "1331 225.121916 -74.633909 -1.1828\n", "1332 224.992024 -74.682586 -1.1833\n", "1333 224.729891 -74.779726 -1.1839\n", "1334 224.597637 -74.828188 -1.1841\n", "\n", "[627 rows x 3 columns]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas\n", "\n", "data = pandas.DataFrame(\n", " {\n", " \"longitude\": dataset.lon_01.data.ravel(),\n", " \"latitude\": dataset.lat_01.data.ravel(),\n", " \"topography\": dataset.mean_dyn_topo_01.load().data.ravel(),\n", " }\n", ").dropna()\n", "data" ] }, { "cell_type": "code", "execution_count": 21, "id": "1cd6b497", "metadata": { "tags": [], "vscode": { "languageId": "python" } }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(\n", " subplot_kw=dict(projection=PlateCarree()),\n", " figsize=(12, 8),\n", ")\n", "\n", "ax.add_geometries(\n", " shapely.geometry.shape(item.geometry),\n", " crs=PlateCarree(),\n", " color=\"coral\",\n", " alpha=0.1,\n", ")\n", "\n", "data.plot.scatter(\n", " x=\"longitude\",\n", " y=\"latitude\",\n", " c=\"topography\",\n", " ax=ax,\n", " colormap=\"viridis\",\n", " marker=\".\",\n", " alpha=0.2,\n", ")\n", "ax.coastlines();" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }