2018-10-11 20:33:23 -06:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
2018-10-14 13:17:01 -06:00
"The ModelSounding class allows us to create a vertical sounding through any available AWIPS model with isobaric levels.\n",
"\n",
"* A Shapely Point geometry is used to select longitude and latitude:\n",
" from shapely.geometry import Point\n",
" point = Point(-104.67,39.87)\n",
"* Parameters `['T','DpT','uW','vW']` are requested for all isobaric levels available for the selected model.\n",
"\n",
"* There is a single-record query performed for `level = \"0.0FHAG\"` to determine the surface pressure level.\n",
"* Pay attention to units when switching models. This notebook was written for the NAM 40km AWIPS model where temperature and dewpoint are returned as Kelvin and wind components as m/s."
2018-10-11 20:33:23 -06:00
]
},
{
"cell_type": "code",
2018-10-14 13:17:01 -06:00
"execution_count": 1,
2018-10-11 20:33:23 -06:00
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2023-05-17 15:35:11 -06:00
"Using NAM40 forecast time 2023-05-17 12:00:00\n"
2018-10-11 20:33:23 -06:00
]
}
],
"source": [
2018-10-14 13:17:01 -06:00
"%matplotlib inline\n",
"from awips.dataaccess import DataAccessLayer, ModelSounding\n",
"from awips import ThriftClient\n",
2018-10-11 20:33:23 -06:00
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
2018-10-14 13:17:01 -06:00
"from metpy.plots import SkewT, Hodograph\n",
2018-10-11 20:33:23 -06:00
"from metpy.units import units\n",
2018-10-14 13:17:01 -06:00
"from mpl_toolkits.axes_grid1.inset_locator import inset_axes\n",
"from math import sqrt\n",
"from datetime import datetime, timedelta\n",
"from shapely.geometry import Point, Polygon\n",
"import shapely.wkb\n",
"import timeit\n",
"model=\"NAM40\"\n",
"parms = ['T','DpT','uW','vW']\n",
2018-10-11 20:33:23 -06:00
"server = 'edex-cloud.unidata.ucar.edu'\n",
"DataAccessLayer.changeEDEXHost(server)\n",
2018-10-14 13:17:01 -06:00
"\n",
"# note the order is LON,lat and not lat,LON\n",
"point = Point(-104.67,39.87)\n",
"\n",
"inc = 0.005\n",
"bbox=[point.y-inc, point.y+inc, point.x-inc, point.x+inc]\n",
"polygon = Polygon([(bbox[0],bbox[2]),(bbox[0],bbox[3]), \n",
" (bbox[1],bbox[3]),(bbox[1],bbox[2]),\n",
" (bbox[0],bbox[2])])\n",
"\n",
"# Get latest forecast cycle run\n",
"timeReq = DataAccessLayer.newDataRequest(\"grid\")\n",
"timeReq.setLocationNames(model)\n",
"cycles = DataAccessLayer.getAvailableTimes(timeReq, True)\n",
"times = DataAccessLayer.getAvailableTimes(timeReq)\n",
2018-10-15 08:25:13 -06:00
"fcstRun = DataAccessLayer.getForecastRun(cycles[-2], times)\n",
2018-10-14 13:17:01 -06:00
"\n",
"print(\"Using \" + model + \" forecast time \" + str(fcstRun[0]))"
2018-10-11 20:33:23 -06:00
]
},
{
"cell_type": "code",
2018-10-14 13:17:01 -06:00
"execution_count": 2,
2018-10-11 20:33:23 -06:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2023-05-17 15:35:11 -06:00
"Found surface record at 830.1MB\n"
2018-10-11 20:33:23 -06:00
]
}
],
"source": [
2018-10-14 13:17:01 -06:00
"p,t,d,u,v = [],[],[],[],[]\n",
"use_parms = ['T','DpT','uW','vW','P']\n",
"use_level = \"0.0FHAG\"\n",
"sndObject = ModelSounding.getSounding(model, use_parms, \n",
2018-10-15 08:25:13 -06:00
" [\"0.0FHAG\"], point, timeRange=[fcstRun[0]])\n",
2018-10-14 13:17:01 -06:00
"if len(sndObject) > 0:\n",
" for time in sndObject._dataDict:\n",
" p.append(float(sndObject._dataDict[time][use_level]['P']))\n",
" t.append(float(sndObject._dataDict[time][use_level]['T']))\n",
" d.append(float(sndObject._dataDict[time][use_level]['DpT']))\n",
" u.append(float(sndObject._dataDict[time][use_level]['uW']))\n",
" v.append(float(sndObject._dataDict[time][use_level]['vW']))\n",
" print(\"Found surface record at \" + \"%.1f\" % p[0] + \"MB\")\n",
"else:\n",
" raise ValueError(\"sndObject returned empty for query [\" \n",
" + ', '.join(str(x) for x in (model, use_parms, point, use_level)) +\"]\")\n",
2018-10-15 08:25:13 -06:00
" \n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2023-05-17 15:35:11 -06:00
"Using 32 levels between 830.1 and 50.0MB\n"
2018-10-15 08:25:13 -06:00
]
}
],
"source": [
2018-10-14 13:17:01 -06:00
"\n",
"# Get isobaric levels with our requested parameters\n",
"levelReq = DataAccessLayer.newDataRequest(\"grid\", envelope=point)\n",
"levelReq.setLocationNames(model)\n",
"levelReq.setParameters('T','DpT','uW','vW')\n",
"availableLevels = DataAccessLayer.getAvailableLevels(levelReq)\n",
"\n",
"# Clean levels list of unit string (MB, FHAG, etc.)\n",
"levels = []\n",
"for lvl in availableLevels:\n",
" name=str(lvl)\n",
" if 'MB' in name and '_' not in name:\n",
" # If this level is above (less than in mb) our 0.0FHAG record\n",
" if float(name.replace('MB','')) < p[0]:\n",
" levels.append(lvl)\n",
"\n",
"# Get Sounding\n",
"sndObject = ModelSounding.getSounding(model, parms, levels, point, \n",
" timeRange=[fcstRun[0]])\n",
"\n",
"if not len(sndObject) > 0:\n",
" raise ValueError(\"sndObject returned empty for query [\" \n",
" + ', '.join(str(x) for x in (model, parms, point, levels)) +\"]\")\n",
" \n",
"for time in sndObject._dataDict:\n",
" for lvl in sndObject._dataDict[time].levels():\n",
" for parm in sndObject._dataDict[time][lvl].parameters():\n",
" if parm == \"T\":\n",
" t.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == \"DpT\":\n",
" d.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == 'uW':\n",
" u.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == 'vW':\n",
" v.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" else:\n",
" print(\"WHAT IS THIS\")\n",
" print(sndObject._dataDict[time][lvl][parm])\n",
" # Pressure is our requested level rather than a returned parameter\n",
" p.append(float(lvl.replace('MB','')))\n",
"\n",
"# convert to numpy.array()\n",
"p = np.array(p, dtype=float)\n",
"t = (np.array(t, dtype=float) - 273.15) * units.degC\n",
"d = (np.array(d, dtype=float) - 273.15) * units.degC\n",
"u = (np.array(u, dtype=float) * units('m/s')).to('knots')\n",
"v = (np.array(v, dtype=float) * units('m/s')).to('knots')\n",
"w = np.sqrt(u**2 + v**2)\n",
"\n",
"print(\"Using \" + str(len(levels)) + \" levels between \" + \n",
" str(\"%.1f\" % max(p)) + \" and \" + str(\"%.1f\" % min(p)) + \"MB\")"
2018-10-11 20:33:23 -06:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
2018-10-14 13:17:01 -06:00
"## Skew-T/Log-P"
2018-10-11 20:33:23 -06:00
]
},
{
"cell_type": "code",
2018-10-15 08:25:13 -06:00
"execution_count": 4,
2018-10-11 20:33:23 -06:00
"metadata": {},
"outputs": [
{
"data": {
2023-05-17 15:35:11 -06:00
"image/png": "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
2018-10-11 20:33:23 -06:00
"text/plain": [
"<Figure size 864x1008 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.rcParams['figure.figsize'] = (12, 14)\n",
2018-10-14 13:17:01 -06:00
"\n",
"# Skew-T\n",
"skew = SkewT(rotation=45)\n",
"skew.plot(p, t, 'r', linewidth=2)\n",
"skew.plot(p, d, 'g', linewidth=2)\n",
"skew.plot_barbs(p, u, v)\n",
"skew.plot_dry_adiabats()\n",
"skew.plot_moist_adiabats()\n",
"skew.plot_mixing_lines(linestyle=':')\n",
"\n",
"skew.ax.set_ylim(1000, np.min(p))\n",
"skew.ax.set_xlim(-50, 40)\n",
"\n",
"# Title\n",
"plt.title( model + \" (\" + str(point) + \") \" + str(time.getRefTime()))\n",
"\n",
"# Hodograph\n",
2018-10-11 20:33:23 -06:00
"ax_hod = inset_axes(skew.ax, '40%', '40%', loc=2)\n",
2018-10-14 13:17:01 -06:00
"h = Hodograph(ax_hod, component_range=max(w.magnitude))\n",
2018-10-11 20:33:23 -06:00
"h.add_grid(increment=20)\n",
2018-10-14 13:17:01 -06:00
"h.plot_colormapped(u, v, w)\n",
"\n",
"# Dotted line at 0C isotherm\n",
"l = skew.ax.axvline(0, color='c', linestyle='-', linewidth=1)\n",
"\n",
2018-10-11 20:33:23 -06:00
"plt.show()"
]
2018-10-15 08:25:13 -06:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Model Sounding Comparison"
]
},
{
"cell_type": "code",
2018-10-15 16:29:13 -06:00
"execution_count": 5,
2023-05-17 15:35:11 -06:00
"metadata": {
"scrolled": false
},
2018-10-15 08:25:13 -06:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2023-05-17 15:35:11 -06:00
"Using RAP13 forecast time 2023-05-17 20:00:00\n",
"Found surface record at 833.8MB\n",
"Using 30 levels between 833.8 and 100.0MB\n"
2018-10-15 08:25:13 -06:00
]
},
{
"data": {
2023-05-17 15:35:11 -06:00
"image/png": "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
2018-10-15 08:25:13 -06:00
"text/plain": [
"<Figure size 864x1008 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2023-05-17 15:35:11 -06:00
"Using GFS20 forecast time 2023-05-17 12:00:00\n",
"Found surface record at 839.9MB\n",
"Using 22 levels between 839.9 and 100.0MB\n"
2018-10-15 08:25:13 -06:00
]
},
{
"data": {
2023-05-17 15:35:11 -06:00
"image/png": "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
2018-10-15 08:25:13 -06:00
"text/plain": [
"<Figure size 864x1008 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2023-05-17 15:35:11 -06:00
"Using NAM40 forecast time 2023-05-17 18:00:00\n",
"Found surface record at 829.4MB\n",
"Using 32 levels between 829.4 and 50.0MB\n"
2018-10-15 08:25:13 -06:00
]
},
{
"data": {
2023-05-17 15:35:11 -06:00
"image/png": "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
2018-10-15 08:25:13 -06:00
"text/plain": [
"<Figure size 864x1008 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
2023-05-17 15:35:11 -06:00
"models = [\"RAP13\", \"GFS20\", \"NAM40\"]\n",
2018-10-15 08:25:13 -06:00
"parms = ['T','DpT','uW','vW']\n",
"\n",
"for modelName in models:\n",
" timeReq = DataAccessLayer.newDataRequest(\"grid\")\n",
" timeReq.setLocationNames(modelName)\n",
" cycles = DataAccessLayer.getAvailableTimes(timeReq, True)\n",
" times = DataAccessLayer.getAvailableTimes(timeReq)\n",
" fcstRun = DataAccessLayer.getForecastRun(cycles[-1], times)\n",
" print(\"Using \" + modelName + \" forecast time \" + str(fcstRun[0]))\n",
" \n",
" p,t,d,u,v = [],[],[],[],[]\n",
" use_parms = ['T','DpT','uW','vW','P']\n",
" use_level = \"0.0FHAG\"\n",
" \n",
" sndObject = ModelSounding.getSounding(modelName, use_parms, \n",
" [use_level], point, timeRange=[fcstRun[0]])\n",
" if len(sndObject) > 0:\n",
" for time in sndObject._dataDict:\n",
" p.append(float(sndObject._dataDict[time][use_level]['P']))\n",
" t.append(float(sndObject._dataDict[time][use_level]['T']))\n",
" d.append(float(sndObject._dataDict[time][use_level]['DpT']))\n",
" u.append(float(sndObject._dataDict[time][use_level]['uW']))\n",
" v.append(float(sndObject._dataDict[time][use_level]['vW']))\n",
" print(\"Found surface record at \" + \"%.1f\" % p[0] + \"MB\")\n",
" else:\n",
" raise ValueError(\"sndObject returned empty for query [\" \n",
" + ', '.join(str(x) for x in (modelName, use_parms, point, use_level)) +\"]\")\n",
" \n",
" # Get isobaric levels with our requested parameters\n",
" levelReq = DataAccessLayer.newDataRequest(\"grid\", envelope=point)\n",
" levelReq.setLocationNames(modelName)\n",
" levelReq.setParameters('T','DpT','uW','vW')\n",
" availableLevels = DataAccessLayer.getAvailableLevels(levelReq)\n",
" # Clean levels list of unit string (MB, FHAG, etc.)\n",
" levels = []\n",
" for lvl in availableLevels:\n",
" name=str(lvl)\n",
" if 'MB' in name and '_' not in name:\n",
" # If this level is above (less than in mb) our 0.0FHAG record\n",
" if float(name.replace('MB','')) < p[0]:\n",
" levels.append(lvl)\n",
" \n",
" # Get Sounding\n",
" sndObject = ModelSounding.getSounding(modelName, parms, levels, point, \n",
" timeRange=[fcstRun[0]])\n",
" if not len(sndObject) > 0:\n",
" raise ValueError(\"sndObject returned empty for query [\" \n",
" + ', '.join(str(x) for x in (modelName, parms, point, levels)) +\"]\")\n",
" for time in sndObject._dataDict:\n",
" for lvl in sndObject._dataDict[time].levels():\n",
" for parm in sndObject._dataDict[time][lvl].parameters():\n",
" if parm == \"T\":\n",
" t.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == \"DpT\":\n",
" d.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == 'uW':\n",
" u.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == 'vW':\n",
" v.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" else:\n",
" print(\"WHAT IS THIS\")\n",
" print(sndObject._dataDict[time][lvl][parm])\n",
" # Pressure is our requested level rather than a returned parameter\n",
" p.append(float(lvl.replace('MB','')))\n",
"\n",
" # convert to numpy.array()\n",
" p = np.array(p, dtype=float)\n",
" t = (np.array(t, dtype=float) - 273.15) * units.degC\n",
" d = (np.array(d, dtype=float) - 273.15) * units.degC\n",
" u = (np.array(u, dtype=float) * units('m/s')).to('knots')\n",
" v = (np.array(v, dtype=float) * units('m/s')).to('knots')\n",
" w = np.sqrt(u**2 + v**2)\n",
"\n",
" print(\"Using \" + str(len(levels)) + \" levels between \" + \n",
" str(\"%.1f\" % max(p)) + \" and \" + str(\"%.1f\" % min(p)) + \"MB\")\n",
"\n",
" # Skew-T\n",
" plt.rcParams['figure.figsize'] = (12, 14)\n",
" skew = SkewT(rotation=45)\n",
" skew.plot(p, t, 'r', linewidth=2)\n",
" skew.plot(p, d, 'g', linewidth=2)\n",
" skew.plot_barbs(p, u, v)\n",
" skew.plot_dry_adiabats()\n",
" skew.plot_moist_adiabats()\n",
" skew.plot_mixing_lines(linestyle=':')\n",
" skew.ax.set_ylim(1000, 100)\n",
" skew.ax.set_xlim(-50, 40)\n",
" # Title\n",
" plt.title( modelName + \" (\" + str(point) + \") \" + str(time.getRefTime()))\n",
" # Hodograph\n",
" ax_hod = inset_axes(skew.ax, '40%', '40%', loc=2)\n",
" h = Hodograph(ax_hod, component_range=max(w.magnitude))\n",
" h.add_grid(increment=20)\n",
" h.plot_colormapped(u, v, w)\n",
" # Dotted line at 0C isotherm\n",
" l = skew.ax.axvline(0, color='c', linestyle='-', linewidth=1)\n",
" plt.show()"
]
2023-05-17 15:35:11 -06:00
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
2018-10-11 20:33:23 -06:00
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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",
2023-05-17 15:35:11 -06:00
"version": "3.9.5"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
2018-10-11 20:33:23 -06:00
}
},
"nbformat": 4,
"nbformat_minor": 1
}