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": [
2018-10-15 16:29:13 -06:00
"Using NAM40 forecast time 2018-10-15 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": [
2018-10-15 16:29:13 -06:00
"Found surface record at 836.4MB\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": [
2018-10-15 16:29:13 -06:00
"Using 32 levels between 836.4 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": {
2018-10-15 16:29:13 -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,
2018-10-15 08:25:13 -06:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2018-10-15 16:29:13 -06:00
"Using CMC forecast time 2018-10-15 12:00:00\n",
"Found surface record at 848.6MB\n",
"Using 19 levels between 848.6 and 50.0MB\n"
2018-10-15 08:25:13 -06:00
]
},
{
"data": {
2018-10-15 16:29:13 -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": [
2018-10-15 16:29:13 -06:00
"Using GFS20 forecast time 2018-10-15 18:00:00\n",
"Found surface record at 848.1MB\n",
"Using 22 levels between 848.1 and 100.0MB\n"
2018-10-15 08:25:13 -06:00
]
},
{
"data": {
2018-10-15 16:29:13 -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": [
2018-10-15 16:29:13 -06:00
"Using NAM40 forecast time 2018-10-15 18:00:00\n",
"Found surface record at 837.7MB\n",
"Using 32 levels between 837.7 and 50.0MB\n"
2018-10-15 08:25:13 -06:00
]
},
{
"data": {
2018-10-15 16:29:13 -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": [
2018-10-15 16:29:13 -06:00
"models = [\"CMC\", \"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()"
]
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",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 1
}