{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Surface map of METAR data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Table of Contents \n", "\n", "* [Objective](#objective)\n", "* [Strategy](#strategy)\n", "* [Step 0: Import required packages](#step0)\n", "* [Step 1: Browse a THREDDS Data Server (TDS)](#step1)\n", "* [Step 2: Determine the date and hour to gather observations](#step2)\n", "* [Step 3: Surface observations](#step3)\n", " * [Step 3a: Determine catalog location for Surface observations](#step3a)\n", " * [Step 3b: Subset Surface observations](#step3b) \n", " * [Step 3c: Retrieve Surface observations](#step3c)\n", " * [Step 3d: Process Surface observations](#step3d)\n", " * [Step 3e: Visualize Surface observations](#step3e)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Objective\n", "> In this notebook, we will make a surface map based on current observations from METAR sites across North America." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Step 0: Import required packages \n", "[Top](#top)\n", "> But first, we need to import all our required packages. Today we're working with:\n", "> - datetime\n", "> - numpy\n", "> - pandas\n", "> - matplotlib\n", "> - cartopy\n", "> - metpy\n", "> - siphon\n", "\n", "> We will also import a couple of functions that convert weather and cloud cover symbols from METAR files encoded in GEMPAK format." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from datetime import datetime,timedelta\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "\n", "import cartopy.crs as ccrs\n", "import cartopy.feature as cfeature\n", "\n", "from metpy.calc import wind_components, reduce_point_density\n", "from metpy.units import units\n", "from metpy.plots import StationPlot\n", "from metpy.plots.wx_symbols import current_weather, sky_cover, wx_code_map\n", "\n", "from siphon.catalog import TDSCatalog\n", "from siphon.ncss import NCSS" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Load in a collection of functions that process GEMPAK weather conditions and cloud cover data.\n", "%run /kt11/ktyle/python/metargem.py" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Step 1: Browse a THREDDS Data Server (TDS) \n", "[Top](#top)\n", "\n", "> A **THREDDS Data Server** provides us with coherent access to a large collection of real-time and archived datasets from a variety of environmental data sources at a number of distributed server sites. \n", "> Various institutions serve data via THREDDS, including our department. You can browse our department's TDS in your web browser using this link: \n", "\n", "http://thredds.atmos.albany.edu:8080/thredds\n", "\n", "\n", "> Let's take a few moments to browse the catalog in a new tab of your web browser." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Step 2: Determine the date and hour to gather observations " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Use the current time, or set your own for a past time.\n", "# Set current to False if you want to specify a past time.\n", "\n", "nowTime = datetime.utcnow()\n", "current = True\n", "#current = False\n", "if (current):\n", " validTime = datetime.utcnow()\n", " year = validTime.year\n", " month = validTime.month\n", " day = validTime.day\n", " hour = validTime.hour\n", "else:\n", " year = 2024\n", " month = 1\n", " day = 11\n", " hour = 22\n", " \n", "validTime = datetime(year, month, day, hour)\n", "deltaTime = nowTime - validTime\n", "deltaDays = deltaTime.days\n", "\n", "timeStr = validTime.strftime(\"%Y-%m-%d %H UTC\")\n", "timeStr2 = validTime.strftime(\"%Y%m%d%H\")\n", "print(timeStr)\n", "print(validTime)\n", "print(deltaTime)\n", "print(deltaDays)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Step 3: Surface observations " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Step 3a: Determine catalog location for Surface observations \n", "[Top](#top)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If the date is within the past week, use the current METAR data catalog.\n", "Otherwise, use the archive METAR data catalog." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "if (deltaDays <= 7):\n", " # First URL has a subset of stations, just over N. America\n", " NAmCurrent = 'http://thredds.atmos.albany.edu:8080/thredds/catalog/metar/ncdecodedNAm/catalog.xml?dataset=metar/ncdecodedNAm/Metar_NAm_Station_Data_fc.cdmr'\n", " # Second URL has all stations worldwide ... will take longer to load and you definitely need to adjust the point density in step 3d\n", " WorldCurrent = 'http://thredds.atmos.albany.edu:8080/thredds/catalog/metar/ncdecoded/catalog.xml?dataset=metar/ncdecoded/Metar_Station_Data_fc.cdmr'\n", " \n", " metar_cat_url = NAmCurrent\n", "# metar_cat_url = WorldCurrent\n", "else:\n", " metar_cat_url = 'http://thredds.atmos.albany.edu:8080/thredds/catalog/metarArchive/ncdecoded/catalog.xml?dataset=metarArchive/ncdecoded/Archived_Metar_Station_Data_fc.cdmr'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Note:
\n", " In general, our METAR archive goes back two years. Requests for older dates may fail. If you need data for an earlier date, email Ross or Kevin.\n", "