Skip to content

Instantly share code, notes, and snippets.

@barronh
Created March 26, 2025 20:40
Show Gist options
  • Select an option

  • Save barronh/fa8489fa6183bde20e2b4422fe35cb27 to your computer and use it in GitHub Desktop.

Select an option

Save barronh/fa8489fa6183bde20e2b4422fe35cb27 to your computer and use it in GitHub Desktop.
TEMPO_CloudRasterFormat.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"authorship_tag": "ABX9TyNxIyPFkJsdSNnV07qk8fFc",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/barronh/fa8489fa6183bde20e2b4422fe35cb27/tempo_cloudrasterformat.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"source": [
"# Rapid Access to TEMPO through gis.earthdata.nasa.gov\n",
"\n",
"---\n",
" author: Barron H. Henderson\n",
" last updated: 2025-03-06\n",
"---\n",
"\n",
"This example shows how to get a single location's NO2 from TEMPO for any amount of time in just a few seconds. The code is adapted from Hazem Mahmoud's code that he shared with me.\n"
],
"metadata": {
"id": "w_NCE5SdIA0E"
}
},
{
"cell_type": "code",
"source": [
"def getl3(lon, lat, start, end):\n",
" \"\"\"\n",
" Get Level 3 TEMPO Tropospheric NO2 quickly!\n",
"\n",
" Arguments\n",
" ---------\n",
" lon : float\n",
" Longitude in degrees_east\n",
" lat : float\n",
" Latitude in degrees_north\n",
" start : str or datetime-like\n",
" Beginning of time-series. Must be convertable to a time using\n",
" pandas.to_datetime with utc=True\n",
" end : str or datetime-like\n",
" End of time-series. Must be convertable to a time using\n",
" pandas.to_datetime with utc=True\n",
"\n",
" Returns\n",
" -------\n",
" df : pandas.DataFrame\n",
" DataFrame with time as an index and NO2 Tropospheric as the only column\n",
" \"\"\"\n",
" import pandas as pd\n",
" import requests\n",
" conceptid = 'C2930763263-LARC_CLOUD' # TEMPO L3 V03\n",
" filename = 'TEMPO_NO2_L3_V03_HOURLY_TROPOSPHERIC_VERTICAL_COLUMN'\n",
" base_url = 'https://gis.earthdata.nasa.gov/image/rest/services/'\n",
" base_url += f'{conceptid}/{filename}/ImageServer/getSamples/'\n",
"\n",
" # time bounds in ms since EPOCH\n",
" stime = pd.to_datetime(start, utc=True).timestamp() * 1000\n",
" etime = pd.to_datetime(end, utc=True).timestamp() * 1000\n",
"\n",
" # Standard Settings\n",
" # variable_name = 'NO2 Troposphere'\n",
" params = {\n",
" 'sampleDistance': '', 'sampleCount': '', 'pixelSize': '', 'outFields': '',\n",
" 'sliceId': '', 'mosaicRule': '',\n",
" # 'mosaicRule': f'{{\"multidimensionalDefinition\"{variable_name}}}',\n",
" 'returnFirstValueOnly': 'false', 'interpolation': 'RSP_NearestNeighbor',\n",
" 'geometryType': 'esriGeometryPoint',\n",
" 'geometry': f'{lon},{lat}', # required, to be filled in by user\n",
" 'time': f'{stime:.0f},{etime:.0f}', # required, to be filled in by user\n",
" 'f': 'pjson'\n",
" }\n",
" # Make the request to the API\n",
" response = requests.get(base_url, params=params, stream=True)\n",
" response.raise_for_status()\n",
"\n",
" # Convert to JSON\n",
" data = response.json()\n",
" # Convert to DataFrame\n",
" varkey = data['samples'][0]['attributes']['Variables']\n",
" df = pd.DataFrame.from_records([\n",
" {\n",
" 'time': rec['attributes']['StdTime'],\n",
" varkey: rec.get('value', rec['attributes'].get(varkey, ''))\n",
" }\n",
" for rec in data['samples']\n",
" ])\n",
" df['time'] = pd.to_datetime(df['time'], unit='ms')\n",
" # convert string data to double precision floats\n",
" df[varkey] = df[varkey].replace('', 'nan').astype('d')\n",
" # Set the index as time\n",
" df.set_index('time', inplace=True)\n",
" return df"
],
"metadata": {
"id": "-mxPUoJ8IHqb"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"lon = -84.3885\n",
"lat = 33.7501\n",
"start = '2023-09-01 12:00:00+0000'\n",
"end = '2025-03-01 12:00:00+0000'\n",
"df = getl3(lon, lat, start, end)"
],
"metadata": {
"id": "bQeGNnjiJQjZ"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"ax = df.query(f'NO2_Troposphere > -5e15').resample('1h').mean().plot(marker='o', figsize=(24, 3))\n",
"_ = ax.set(title=f'Hourly Trop NO2 VCD at {lon},{lat} from {start} to {end}', ylabel='NO2 [molec/cm$^3$]', ylim=(None, None))"
],
"metadata": {
"id": "pFu37NOMJQ1Q"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [],
"metadata": {
"id": "rRVEMOgUJl6G"
},
"execution_count": null,
"outputs": []
}
]
}
@barronh
Copy link
Author

barronh commented Mar 26, 2025

This makes:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment