notebook and build updates pre-release 0.9.4

This commit is contained in:
mjames-upc 2016-05-24 15:29:46 -05:00
parent df8ee6e885
commit 254411e5e7
45 changed files with 724 additions and 3804 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
.ipynb_checkpoints
docs/build/
*.pyc

View file

@ -37,8 +37,8 @@ sys.path.insert(0, os.path.abspath('../..'))
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode'
# 'notebook_gen_sphinxext'
'sphinx.ext.viewcode',
'notebook_gen_sphinxext'
]
# Add any paths that contain templates here, relative to this directory.

View file

@ -1,3 +0,0 @@
=========
Dev Guide
=========

View file

@ -1,269 +0,0 @@
==========================
Grid Levels and Parameters
==========================
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Grid Levels and Parameters.ipynb>`_
List Available Parameters for a Grid Name
-----------------------------------------
.. code:: python
from awips.dataaccess import DataAccessLayer
# Select HRRR
DataAccessLayer.changeEDEXHost("edex.unidata.ucar.edu")
request = DataAccessLayer.newDataRequest()
request.setDatatype("grid")
request.setLocationNames("GFS40")
# Print parm list
available_parms = DataAccessLayer.getAvailableParameters(request)
available_parms.sort()
for parm in available_parms:
print parm
.. parsed-literal::
AV
BLI
CAPE
CFRZR6hr
CICEP6hr
CIn
CP6hr
CRAIN6hr
CSNOW6hr
GH
P
P6hr
PMSL
PVV
PW
RH
SLI
T
TP6hr
VSS
WEASD
WGH
uW
vW
List Available Levels for Parameter
-----------------------------------
.. code:: python
# Set parm to u-wind
request.setParameters("uW")
# Print level list
available_levels = DataAccessLayer.getAvailableLevels(request)
available_levels.sort()
for level in available_levels:
print level
.. parsed-literal::
1000.0MB
950.0MB
925.0MB
900.0MB
875.0MB
850.0MB
825.0MB
800.0MB
775.0MB
725.0MB
600.0MB
575.0MB
0.0_30.0BL
60.0_90.0BL
90.0_120.0BL
0.5PV
2.0PV
30.0_60.0BL
1.0PV
750.0MB
120.0_150.0BL
975.0MB
700.0MB
675.0MB
650.0MB
625.0MB
550.0MB
525.0MB
500.0MB
450.0MB
400.0MB
300.0MB
250.0MB
200.0MB
150.0MB
100.0MB
0.0TROP
1.5PV
150.0_180.0BL
350.0MB
10.0FHAG
0.0MAXW
Construct Wind Field from U and V Components
--------------------------------------------
.. code:: python
import numpy
from metpy.units import units
# Set level for u-wind
request.setLevels("10.0FHAG")
t = DataAccessLayer.getAvailableTimes(request)
# Select last time for u-wind
response = DataAccessLayer.getGridData(request, [t[-1]])
data_uw = response[-1]
lons,lats = data_uw.getLatLonCoords()
# Select v-wind
request.setParameters("vW")
# Select last time for v-wind
response = DataAccessLayer.getGridData(request, [t[-1]])
data_uv = response[-1]
# Print
print 'Time :', t[-1]
print 'Model:', data_uv.getLocationName()
print 'Unit :', data_uv.getUnit()
print 'Parms :', data_uw.getParameter(), data_uv.getParameter()
print data_uv.getRawData().shape
# Calculate total wind speed
spd = numpy.sqrt( data_uw.getRawData()**2 + data_uv.getRawData()**2 )
spd = spd * units.knot
print "windArray =", spd
data = data_uw
.. parsed-literal::
Time : 2016-04-20 18:00:00 (240)
Model: GFS40
Unit : m*sec^-1
Parms : vW vW
(185, 129)
windArray = [[ 1.47078204 1.69705617 0.69296461 ..., 9.390378 9.14996147 8.55599213] [ 8.23072243 8.20243835 8.31557465 ..., 1.48492408 0.56568539 0.39597979] [ 0.49497473 0.52325904 0.1979899 ..., 2.67286372 2.63043714 2.65872145] ..., [ 2.17788887 2.20617294 2.13546252 ..., 1.01823378 0.62225395 0.39597979] [ 0.02828427 0.8768124 1.51320839 ..., 6.47709799 6.68922997 6.84479332] [ 6.92964649 7.02864122 6.98621511 ..., 0.91923875 1.24450791 1.28693426]] knot
Plotting a Grid with Basemap
----------------------------
Using **matplotlib**, **numpy**, and **basemap**:
.. code:: python
%matplotlib inline
import matplotlib.tri as mtri
import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy
from mpl_toolkits.basemap import Basemap, cm
import numpy as np
from numpy import linspace, transpose
from numpy import meshgrid
plt.figure(figsize=(12, 12), dpi=100)
map = Basemap(projection='cyl',
resolution = 'c',
llcrnrlon = lons.min(), llcrnrlat = lats.min(),
urcrnrlon =lons.max(), urcrnrlat = lats.max()
)
map.drawcoastlines()
map.drawstates()
map.drawcountries()
#
# We have to reproject our grid, see https://stackoverflow.com/questions/31822553/m
#
x = linspace(0, map.urcrnrx, data.getRawData().shape[1])
y = linspace(0, map.urcrnry, data.getRawData().shape[0])
xx, yy = meshgrid(x, y)
ngrid = len(x)
rlons = np.repeat(np.linspace(np.min(lons), np.max(lons), ngrid),
ngrid).reshape(ngrid, ngrid)
rlats = np.repeat(np.linspace(np.min(lats), np.max(lats), ngrid),
ngrid).reshape(ngrid, ngrid).T
tli = mtri.LinearTriInterpolator(mtri.Triangulation(lons.flatten(),
lats.flatten()), spd.flatten())
rdata = tli(rlons, rlats)
#cs = map.contourf(rlons, rlats, rdata, latlon=True)
cs = map.contourf(rlons, rlats, rdata, latlon=True, vmin=0, vmax=20, cmap='BuPu')
# Add colorbar
cbar = map.colorbar(cs,location='bottom',pad="5%")
cbar.set_label("Wind Speed (Knots)")
# Show plot
plt.show()
.. image:: Grid Levels and Parameters_files/Grid Levels and Parameters_7_0.png
or use **pcolormesh** rather than **contourf**
.. code:: python
plt.figure(figsize=(12, 12), dpi=100)
map = Basemap(projection='cyl',
resolution = 'c',
llcrnrlon = lons.min(), llcrnrlat = lats.min(),
urcrnrlon =lons.max(), urcrnrlat = lats.max()
)
map.drawcoastlines()
map.drawstates()
map.drawcountries()
cs = map.pcolormesh(rlons, rlats, rdata, latlon=True, vmin=0, vmax=20, cmap='BuPu')
.. image:: Grid Levels and Parameters_files/Grid Levels and Parameters_9_0.png
Plotting a Grid with Cartopy
----------------------------
.. code:: python
import os
import matplotlib.pyplot as plt
import numpy as np
import iris
import cartopy.crs as ccrs
from cartopy import config
lon,lat = data.getLatLonCoords()
plt.figure(figsize=(12, 12), dpi=100)
ax = plt.axes(projection=ccrs.PlateCarree())
cs = plt.contourf(rlons, rlats, rdata, 60, transform=ccrs.PlateCarree(), vmin=0, vmax=20, cmap='BuPu')
ax.coastlines()
ax.gridlines()
# add colorbar
cbar = plt.colorbar(orientation='horizontal')
cbar.set_label("Wind Speed (Knots)")
plt.show()
.. image:: Grid Levels and Parameters_files/Grid Levels and Parameters_11_0.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

View file

@ -1,335 +0,0 @@
============
Gridded Data
============
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Gridded_Data.ipynb>`_
EDEX Grid Inventory
-------------------
.. code:: python
from awips.dataaccess import DataAccessLayer
# Set host
DataAccessLayer.changeEDEXHost("edex-cloud.unidata.ucar.edu")
# Init data request
request = DataAccessLayer.newDataRequest()
# Set datatype
request.setDatatype("grid")
# Get a list of all available models
available_grids = DataAccessLayer.getAvailableLocationNames(request)
# Sort
available_grids.sort()
for grid in available_grids:
print grid
.. parsed-literal::
AUTOSPE
AVN211
AVN225
DGEX
ECMF-Global
ECMF1
ECMF10
ECMF11
ECMF12
ECMF2
ECMF3
ECMF4
ECMF5
ECMF6
ECMF7
ECMF8
ECMF9
ESTOFS
ETA
FFG-ALR
FFG-FWR
FFG-KRF
FFG-MSR
FFG-ORN
FFG-RHA
FFG-RSA
FFG-TAR
FFG-TIR
FFG-TUA
GFS
GFS40
GFSGuide
GFSLAMP5
GribModel:9:151:172
HFR-EAST_6KM
HFR-EAST_PR_6KM
HFR-US_EAST_DELAWARE_1KM
HFR-US_EAST_FLORIDA_2KM
HFR-US_EAST_NORTH_2KM
HFR-US_EAST_SOUTH_2KM
HFR-US_EAST_VIRGINIA_1KM
HFR-US_HAWAII_1KM
HFR-US_HAWAII_2KM
HFR-US_HAWAII_6KM
HFR-US_WEST_500M
HFR-US_WEST_CENCAL_2KM
HFR-US_WEST_LOSANGELES_1KM
HFR-US_WEST_LOSOSOS_1KM
HFR-US_WEST_NORTH_2KM
HFR-US_WEST_SANFRAN_1KM
HFR-US_WEST_SOCAL_2KM
HFR-US_WEST_WASHINGTON_1KM
HFR-WEST_6KM
HPCGuide
HPCqpf
HPCqpfNDFD
HRRR
LAMP2p5
MPE-Local-ORN
MPE-Local-RHA
MPE-Local-RSA
MPE-Local-TAR
MPE-Local-TIR
MPE-Mosaic-MSR
MPE-Mosaic-ORN
MPE-Mosaic-RHA
MPE-Mosaic-TAR
MPE-Mosaic-TIR
MRMS_1000
NAM12
NAM40
NCWF
NOHRSC-SNOW
NamDNG
NamDNG5
QPE-ALR
QPE-Auto-TUA
QPE-FWR
QPE-KRF
QPE-MSR
QPE-RFC-RSA
QPE-RFC-STR
QPE-TIR
QPE-TUA
QPE-XNAV-ALR
QPE-XNAV-FWR
QPE-XNAV-KRF
QPE-XNAV-MSR
QPE-XNAV-RHA
QPE-XNAV-SJU
QPE-XNAV-TAR
QPE-XNAV-TIR
QPE-XNAV-TUA
RAP13
RAP40
RCM
RFCqpf
RTMA
RTMA5
UKMET-Global
UKMET37
UKMET38
UKMET39
UKMET40
UKMET41
UKMET42
UKMET43
UKMET44
URMA25
estofsPR
fnmocWave
**LocationNames** is different for different plugins - radar is icao -
satellite is sector
Requesting a Grid
-----------------
.. code:: python
# Grid request
request.setLocationNames('RAP40')
request.setParameters("RH")
request.setLevels("850MB")
# Get available times
t = DataAccessLayer.getAvailableTimes(request)
# Select last available time [-1]
response = DataAccessLayer.getGridData(request, [t[0]])
data = response[0]
lon,lat = data.getLatLonCoords()
# Print info
print 'Time :', t[-1]
print 'Model:', data.getLocationName()
print 'Unit :', data.getUnit()
print 'Parm :', data.getParameter()
# Print data array
print data.getRawData().shape
print data.getRawData()
print "lat array =", lat
print "lon array =", lon
.. parsed-literal::
Time : 2016-02-23 15:00:00 (12)
Model: RAP40
Unit : %
Parm : RH
(151, 113)
[[ 93.05456543 93.05456543 87.05456543 ..., 73.05456543 72.05456543
71.05456543]
[ 70.05456543 70.05456543 67.05456543 ..., 69.05456543 46.05456924
37.05456924]
[ 40.05456924 56.05456924 68.05456543 ..., 51.05456924 73.05456543
74.05456543]
...,
[ 65.05456543 62.05456924 63.05456924 ..., 67.05456543 65.05456543
46.05456924]
[ 48.05456924 59.05456924 62.05456924 ..., 4.05456877 5.05456877
5.05456877]
[ 7.05456877 8.05456829 10.05456829 ..., 91.05456543 95.05456543
95.05456543]]
lat array = [[ 54.24940109 54.35071945 54.45080566 ..., 57.9545517 57.91926193
57.88272858]
[ 57.84495163 57.80593109 57.76566696 ..., 58.07667542 58.08861542
58.09931183]
[ 58.10876846 58.11697769 58.12394714 ..., 56.40270996 56.46187973
56.51980972]
...,
[ 19.93209648 19.89832115 19.86351395 ..., 20.054636 20.06362152
20.07156372]
[ 20.0784626 20.08431816 20.08912849 ..., 18.58354759 18.63155174
18.67854691]
[ 18.72453308 18.76950836 18.81346893 ..., 17.49624634 17.42861557
17.36001205]]
lon array = [[-139.83120728 -139.32348633 -138.81448364 ..., -79.26060486
-78.70166016 -78.14326477]
[ -77.58544922 -77.02822876 -76.47161865 ..., -100.70157623
-100.13801575 -99.57427216]
[ -99.01037598 -98.44634247 -97.88218689 ..., -121.69165039
-121.15060425 -120.60871887]
...,
[ -82.65139008 -82.26644897 -81.88170624 ..., -98.52494049
-98.13802338 -97.75105286]
[ -97.36403656 -96.97698212 -96.58989716 ..., -113.07767487
-112.69831085 -112.31866455]
[-111.93874359 -111.5585556 -111.17810822 ..., -69.85433197
-69.48160553 -69.10926819]]
Plotting a Grid with Basemap
----------------------------
Using **matplotlib**, **numpy**, and **basemap**:
.. code:: python
import matplotlib.tri as mtri
import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy
from mpl_toolkits.basemap import Basemap, cm
import numpy as np
from numpy import linspace, transpose
from numpy import meshgrid
plt.figure(figsize=(12, 12), dpi=100)
lons,lats = data.getLatLonCoords()
map = Basemap(projection='cyl',
resolution = 'c',
llcrnrlon = lons.min(), llcrnrlat = lats.min(),
urcrnrlon =lons.max(), urcrnrlat = lats.max()
)
map.drawcoastlines()
map.drawstates()
map.drawcountries()
#
# We have to reproject our grid, see https://stackoverflow.com/questions/31822553/m
#
x = linspace(0, map.urcrnrx, data.getRawData().shape[1])
y = linspace(0, map.urcrnry, data.getRawData().shape[0])
xx, yy = meshgrid(x, y)
ngrid = len(x)
rlons = np.repeat(np.linspace(np.min(lons), np.max(lons), ngrid),
ngrid).reshape(ngrid, ngrid)
rlats = np.repeat(np.linspace(np.min(lats), np.max(lats), ngrid),
ngrid).reshape(ngrid, ngrid).T
tli = mtri.LinearTriInterpolator(mtri.Triangulation(lons.flatten(),
lats.flatten()), data.getRawData().flatten())
rdata = tli(rlons, rlats)
cs = map.contourf(rlons, rlats, rdata, latlon=True, vmin=0, vmax=100, cmap='YlGn')
# add colorbar.
cbar = map.colorbar(cs,location='bottom',pad="5%")
cbar.set_label(data.getParameter() + data.getUnit() )
# Show plot
plt.show()
.. image:: Gridded_Data_files/Gridded_Data_5_0.png
or use **pcolormesh** rather than **contourf**
.. code:: python
plt.figure(figsize=(12, 12), dpi=100)
map = Basemap(projection='cyl',
resolution = 'c',
llcrnrlon = lons.min(), llcrnrlat = lats.min(),
urcrnrlon =lons.max(), urcrnrlat = lats.max()
)
map.drawcoastlines()
map.drawstates()
map.drawcountries()
cs = map.pcolormesh(rlons, rlats, rdata, latlon=True, vmin=0, vmax=100, cmap='YlGn')
.. image:: Gridded_Data_files/Gridded_Data_7_0.png
Plotting a Grid with Cartopy
----------------------------
.. code:: python
import os
import matplotlib.pyplot as plt
import numpy as np
import iris
import cartopy.crs as ccrs
from cartopy import config
lon,lat = data.getLatLonCoords()
plt.figure(figsize=(12, 12), dpi=100)
ax = plt.axes(projection=ccrs.PlateCarree())
cs = plt.contourf(rlons, rlats, rdata, 60, transform=ccrs.PlateCarree(), vmin=0, vmax=100, cmap='YlGn')
ax.coastlines()
ax.gridlines()
# add colorbar
cbar = plt.colorbar(orientation='horizontal')
cbar.set_label(data.getParameter() + data.getUnit() )
plt.show()
.. image:: Gridded_Data_files/Gridded_Data_9_0.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 KiB

View file

@ -1,112 +0,0 @@
===================================
NEXRAD Level 3 Plot with Matplotlib
===================================
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/NEXRAD_Level_3_Plot_with_Matplotlib.ipynb>`_
NEXRAD Level 3 Plot with Matplotlib
===================================
.. code:: python
%matplotlib inline
from awips.dataaccess import DataAccessLayer
from awips import ThriftClient, RadarCommon
from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.radar.request import GetRadarDataRecordRequest
from datetime import datetime
from datetime import timedelta
import matplotlib.pyplot as plt
import numpy as np
from numpy import ma
# use metpy for color table
from metpy.plots import ctables
# Set EDEX server and radar site
DataAccessLayer.changeEDEXHost("edex.unidata.ucar.edu")
request = DataAccessLayer.newDataRequest()
request.setDatatype("radar")
request.setLocationNames("klzk")
datatimes = DataAccessLayer.getAvailableTimes(request)
# Get last available time
timerange = datatimes[-1].validPeriod
dateTimeStr = str(datatimes[-1])
# Buffer length in seconds
buffer = 60
dateTime = datetime.strptime(dateTimeStr, "%Y-%m-%d %H:%M:%S")
beginRange = dateTime - timedelta(0, buffer)
endRange = dateTime + timedelta(0, buffer)
timerange = TimeRange(beginRange, endRange)
print "using time",dateTimeStr
print "buffer by",buffer
print "using range",timerange
client = ThriftClient.ThriftClient(edex)
request = GetRadarDataRecordRequest()
request.setRadarId(site)
request.setPrimaryElevationAngle("0.5")
request.setTimeRange(timerange)
fig, axes = plt.subplots(1, 2, figsize=(15, 8))
for v, ctable, ax in zip((94, 99), ('NWSReflectivity', 'NWSVelocity'), axes):
request.setProductCode(v)
response = client.sendRequest(request)
if response.getData():
for record in response.getData():
idra = record.getHdf5Data()
rdat,azdat,depVals,threshVals = RadarCommon.get_hdf5_data(idra)
dim = rdat.getDimension()
yLen,xLen = rdat.getSizes()
array = rdat.getByteData()
# get data for azimuth angles if we have them.
if azdat :
azVals = azdat.getFloatData()
az = np.array(RadarCommon.encode_radial(azVals))
dattyp = RadarCommon.get_data_type(azdat)
az = np.append(az,az[-1])
print "found",v,record.getDataTime()
header = RadarCommon.get_header(record, format, xLen, yLen, azdat, "description")
rng = np.linspace(0, xLen, xLen + 1)
xlocs = rng * np.sin(np.deg2rad(az[:, np.newaxis]))
ylocs = rng * np.cos(np.deg2rad(az[:, np.newaxis]))
multiArray = np.reshape(array, (-1, xLen))
data = ma.array(multiArray)
data[data==0] = ma.masked
# Plot the data
norm, cmap = ctables.registry.get_with_steps(ctable, 16, 16)
ax.pcolormesh(xlocs, ylocs, data, norm=norm, cmap=cmap)
ax.set_aspect('equal', 'datalim')
multp = 100*(2*xLen/460)
ax.set_xlim(-multp,multp)
ax.set_ylim(-multp,multp)
# This is setting x/ylim on gate/pixel and not km
plt.show()
.. parsed-literal::
using time 2016-04-11 23:02:22
buffer by 60
using range (Apr 11 16 23:01:22 , Apr 11 16 23:03:22 )
found 94 2016-04-11 23:02:22
found 99 2016-04-11 23:02:22
.. image:: NEXRAD_Level_3_Plot_with_Matplotlib_files/NEXRAD_Level_3_Plot_with_Matplotlib_1_1.png

View file

@ -1,134 +0,0 @@
==============================
Plotting a Sounding with MetPy
==============================
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Plotting_a_Sounding_with_MetPy.ipynb>`_
Plotting a Sounding with MetPy
==============================
.. code:: python
%matplotlib inline
from awips.dataaccess import DataAccessLayer
import matplotlib.tri as mtri
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import numpy as np
from metpy.calc import get_wind_components, lcl, dry_lapse, parcel_profile
from metpy.plots import SkewT, Hodograph
from metpy.units import units, concatenate
plt.rcParams['figure.figsize'] = (12, 14)
# Set EDEX host
DataAccessLayer.changeEDEXHost("edex.unidata.ucar.edu")
request = DataAccessLayer.newDataRequest()
# Data type bufrua
request.setDatatype("bufrua")
# Parameters
request.setParameters("tpMan","tdMan","prMan","htMan","wdMan","wsMan")
# Station ID (name doesn't work yet)
request.setLocationNames("72469")
datatimes = DataAccessLayer.getAvailableTimes(request)
# Get most recent record
response = DataAccessLayer.getGeometryData(request,times=datatimes[-1].validPeriod)
# Initialize data arrays
tpMan,tdMan,prMan,htMan,wdMan,wsMan = [],[],[],[],[],[]
# Build ordered arrays
for ob in response:
print float(ob.getString("prMan")), float(ob.getString("wsMan"))
tpMan.append(float(ob.getString("tpMan")))
tdMan.append(float(ob.getString("tdMan")))
prMan.append(float(ob.getString("prMan")))
htMan.append(float(ob.getString("htMan")))
wdMan.append(float(ob.getString("wdMan")))
wsMan.append(float(ob.getString("wsMan")))
# we can use units.* here...
T = np.array(tpMan)-273.15
Td = np.array(tdMan)-273.15
p = np.array(prMan)/100
height = np.array(htMan)
direc = np.array(wdMan)
spd = np.array(wsMan)
u, v = get_wind_components(spd, np.deg2rad(direc))
p = p * units.mbar
T = T * units.degC
Td = Td * units.degC
spd = spd * units.knot
direc = direc * units.deg
# Create a skewT plot
skew = SkewT()
# Plot the data using normal plotting functions, in this case using
# log scaling in Y, as dictated by the typical meteorological plot
skew.plot(p, T, 'r')
skew.plot(p, Td, 'g')
skew.plot_barbs(p, u, v)
skew.ax.set_ylim(1000, 100)
skew.ax.set_xlim(-40, 60)
# Calculate LCL height and plot as black dot
l = lcl(p[0], T[0], Td[0])
lcl_temp = dry_lapse(concatenate((p[0], l)), T[0])[-1].to('degC')
skew.plot(l, lcl_temp, 'ko', markerfacecolor='black')
# Calculate full parcel profile and add to plot as black line
prof = parcel_profile(p, T[0], Td[0]).to('degC')
skew.plot(p, prof, 'k', linewidth=2)
# Example of coloring area between profiles
skew.ax.fill_betweenx(p, T, prof, where=T>=prof, facecolor='blue', alpha=0.4)
skew.ax.fill_betweenx(p, T, prof, where=T<prof, facecolor='red', alpha=0.4)
# An example of a slanted line at constant T -- in this case the 0 isotherm
l = skew.ax.axvline(0, color='c', linestyle='--', linewidth=2)
# Draw hodograph
ax_hod = inset_axes(skew.ax, '40%', '40%', loc=3)
h = Hodograph(ax_hod, component_range=80.)
h.add_grid(increment=20)
h.plot_colormapped(u, v, spd)
# Show the plot
plt.show()
.. parsed-literal::
83900.0 1.5
100000.0 -9999998.0
92500.0 -9999998.0
85000.0 -9999998.0
70000.0 0.5
50000.0 6.09999990463
40000.0 3.0
30000.0 7.69999980927
25000.0 16.8999996185
20000.0 7.19999980927
15000.0 10.1999998093
10000.0 13.8000001907
7000.0 9.19999980927
5000.0 7.69999980927
3000.0 5.59999990463
2000.0 6.59999990463
1000.0 10.8000001907
700.0 5.09999990463
500.0 -9999.0
300.0 -9999.0
200.0 -9999.0
100.0 -9999.0
.. image:: Plotting_a_Sounding_with_MetPy_files/Plotting_a_Sounding_with_MetPy_1_1.png

View file

@ -1,213 +0,0 @@
===========
Surface Obs
===========
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Surface_Obs.ipynb>`_
.. code:: python
from awips.dataaccess import DataAccessLayer
# Set host
DataAccessLayer.changeEDEXHost("edex.unidata.ucar.edu")
# Init data request
request = DataAccessLayer.newDataRequest()
request.setDatatype("obs")
request.setLocationNames("KBJC")
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
# "presWeather","skyCover","skyLayerBase"
# are multi-dimensional... deal with these later
request.setParameters(
"stationName",
"timeObs",
"wmoId",
"autoStationType",
"elevation",
"reportType",
"temperature",
"tempFromTenths",
"dewpoint",
"dpFromTenths",
"windDir",
"windSpeed",
"windGust",
"visibility",
"altimeter",
"seaLevelPress",
"pressChange3Hour",
"pressChangeChar",
"maxTemp24Hour",
"minTemp24Hour",
"precip1Hour",
"precip3Hour",
"precip6Hour",
"precip24Hour"
)
response = DataAccessLayer.getGeometryData(request,times=time)
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())
#getParameters
print ob.getString("stationName"), "from", ob.getDataTime().getRefTime()
print "stationName is",ob.getString("stationName")
print "timeObs is",ob.getString("timeObs")
print "wmoId is",ob.getString("wmoId")
print "autoStationType is",ob.getString("autoStationType")
print "elevation is",ob.getString("elevation")
print "reportType is",ob.getString("reportType")
print "temperature is",ob.getString("temperature")
print "tempFromTenths is",ob.getString("tempFromTenths")
print "dewpoint is",ob.getString("dewpoint")
print "dpFromTenths is",ob.getString("dpFromTenths")
print "windDir is",ob.getString("windDir")
print "windSpeed is",ob.getString("windSpeed")
print "windGust is",ob.getString("windGust")
print "visibility is",ob.getString("visibility")
print "altimeter is",ob.getString("altimeter")
print "seaLevelPress is",ob.getString("seaLevelPress")
print "pressChange3Hour is",ob.getString("pressChange3Hour")
print "pressChangeChar is",ob.getString("pressChangeChar")
print "maxTemp24Hour is",ob.getString("maxTemp24Hour")
print "minTemp24Hour is",ob.getString("minTemp24Hour")
print "precip1Hour is",ob.getString("precip1Hour")
print "precip3Hour is",ob.getString("precip3Hour")
print "precip6Hour is",ob.getString("precip6Hour")
print "precip24Hour is",ob.getString("precip24Hour")
.. code:: python
# multi-dimensional present WX
request = DataAccessLayer.newDataRequest()
request.setDatatype("obs")
request.setLocationNames("KBJC")
request.setParameters("presWeather")
response = DataAccessLayer.getGeometryData(request,times=time)
for ob in response:
print "getParameters is",ob.getParameters()
print ob.getString("presWeather")
# multi-dimensional Sky Condition
request.setParameters("skyCover", "skyLayerBase")
response = DataAccessLayer.getGeometryData(request,times=time)
for ob in response:
print ob.getString("skyCover")
print ob.getString("skyLayerBase")
Synop/Marine
------------
.. code:: python
from awips.dataaccess import DataAccessLayer
DataAccessLayer.changeEDEXHost("edex.unidata.ucar.edu")
request = DataAccessLayer.newDataRequest()
request.setDatatype("sfcobs")
request.setLocationNames("72421") # Covington, Kentucky (KCVG)
request.setParameters("stationId","timeObs","elevation","reportType",
"wx_present","visibility","seaLevelPress","stationPress",
"pressChange3Hour","pressChangeChar","temperature",
"dewpoint","seaSurfaceTemp","wetBulb","windDir",
"windSpeed","equivWindSpeed10m","windGust","precip1Hour",
"precip6Hour","precip24Hour" )
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
response = DataAccessLayer.getGeometryData(request,times=time)
print response
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())
Profiler
--------
.. code:: python
MULTI_DIM_PARAMS = set(['vComponent', 'uComponent', 'peakPower',
'levelMode', 'uvQualityCode', 'consensusNum',
'HorizSpStdDev', 'wComponent', 'height',
'VertSpStdDev'])
request = DataAccessLayer.newDataRequest("profiler")
request.setParameters('numProfLvls', 'elevation', 'windDirSfc', 'validTime',
'windSpeedSfc', 'pressure', 'submode', 'relHumidity',
'profilerId', 'rainRate', 'temperature')
request.getParameters().extend(MULTI_DIM_PARAMS)
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
response = DataAccessLayer.getGeometryData(request,times=time)
print response
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())
ACARS
-----
.. code:: python
request = DataAccessLayer.newDataRequest("acars")
request.setParameters("tailNumber", "receiver", "pressure", "flightPhase",
"rollAngleQuality", "temp", "windDirection", "windSpeed",
"humidity", "mixingRatio", "icing")
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
response = DataAccessLayer.getGeometryData(request,times=time)
print response
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())
AIREP
-----
.. code:: python
request = DataAccessLayer.newDataRequest("airep")
request.setParameters("id", "flightLevel", "temp", "windDirection", "windSpeed",
"flightWeather", "flightHazard", "flightConditions")
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
response = DataAccessLayer.getGeometryData(request,times=time)
print response
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())
PIREP
-----
.. code:: python
MULTI_DIM_PARAMS = set(["hazardType",
"turbType", "turbBaseHeight", "turbTopHeight",
"iceType", "iceBaseHeight", "iceTopHeight",
"skyCover1", "skyCover2", "skyBaseHeight", "skyTopHeight"
])
request = DataAccessLayer.newDataRequest("pirep")
request.setParameters('id', 'flightLevel', 'temp', 'windDirection', 'windSpeed',
'horzVisibility', 'aircraftType', 'weatherGroup')
request.getParameters().extend(MULTI_DIM_PARAMS)
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
response = DataAccessLayer.getGeometryData(request,times=time)
print response
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())

View file

@ -1,144 +0,0 @@
===========================
Surface Obs Plot with MetPy
===========================
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Surface_Obs_Plot_with_MetPy.ipynb>`_
Based on the MetPy example `"Station Plot with
Layout" <http://metpy.readthedocs.org/en/latest/examples/generated/Station_Plot_with_Layout.html>`_
.. code:: python
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from awips.dataaccess import DataAccessLayer
from metpy.calc import get_wind_components
from metpy.cbook import get_test_data
from metpy.plots import StationPlot, StationPlotLayout, simple_layout
from metpy.units import units
# Initialize
DataAccessLayer.changeEDEXHost("edex.unidata.ucar.edu")
data,latitude,longitude,stationName,temperature,dewpoint,seaLevelPress,windDir,windSpeed = [],[],[],[],[],[],[],[],[]
request = DataAccessLayer.newDataRequest()
request.setDatatype("obs")
#
# we need to set one station to query latest time. this is hack-y and should be fixed
# because when you DON'T set a location name, you tend to get a single observation
# that came in a second ago, so your "latest data for the last time for all stations"
# data array consists of one village in Peru and time-matching is suspect right now.
#
# So here take a known US station (OKC) and hope/assume that a lot of other stations
# are also reporting (and that this is a 00/20/40 ob).
#
request.setLocationNames("KOKC")
datatimes = DataAccessLayer.getAvailableTimes(request)
# Get most recent time for location
time = datatimes[0].validPeriod
# "presWeather","skyCover","skyLayerBase"
# are multi-dimensional(??) and returned seperately (not sure why yet)... deal with those later
request.setParameters("presWeather","skyCover", "skyLayerBase","stationName","temperature","dewpoint","windDir","windSpeed",
"seaLevelPress","longitude","latitude")
request.setLocationNames()
response = DataAccessLayer.getGeometryData(request,times=time)
print time
PRES_PARAMS = set(["presWeather"])
SKY_PARAMS = set(["skyCover", "skyLayerBase"])
# Build ordered arrays
wx,cvr,bas=[],[],[]
for ob in response:
#print ob.getParameters()
if set(ob.getParameters()) & PRES_PARAMS :
wx.append(ob.getString("presWeather"))
continue
if set(ob.getParameters()) & SKY_PARAMS :
cvr.append(ob.getString("skyCover"))
bas.append(ob.getNumber("skyLayerBase"))
continue
latitude.append(float(ob.getString("latitude")))
longitude.append(float(ob.getString("longitude")))
#stationName.append(ob.getString("stationName"))
temperature.append(float(ob.getString("temperature")))
dewpoint.append(float(ob.getString("dewpoint")))
seaLevelPress.append(float(ob.getString("seaLevelPress")))
windDir.append(float(ob.getString("windDir")))
windSpeed.append(float(ob.getString("windSpeed")))
print len(wx)
print len(temperature)
# Convert
data = dict()
data['latitude'] = np.array(latitude)
data['longitude'] = np.array(longitude)
data['air_temperature'] = np.array(temperature)* units.degC
data['dew_point_temperature'] = np.array(dewpoint)* units.degC
#data['air_pressure_at_sea_level'] = np.array(seaLevelPress)* units('mbar')
u, v = get_wind_components(np.array(windSpeed) * units('knots'),
np.array(windDir) * units.degree)
data['eastward_wind'], data['northward_wind'] = u, v
# Convert the fraction value into a code of 0-8, which can be used to pull out
# the appropriate symbol
#data['cloud_coverage'] = (8 * data_arr['cloud_fraction']).astype(int)
# Map weather strings to WMO codes, which we can use to convert to symbols
# Only use the first symbol if there are multiple
#wx_text = make_string_list(data_arr['weather'])
#wx_codes = {'':0, 'HZ':5, 'BR':10, '-DZ':51, 'DZ':53, '+DZ':55,
# '-RA':61, 'RA':63, '+RA':65, '-SN':71, 'SN':73, '+SN':75}
#data['present_weather'] = [wx_codes[s.split()[0] if ' ' in s else s] for s in wx]
# Set up the map projection
import cartopy.crs as ccrs
import cartopy.feature as feat
from matplotlib import rcParams
rcParams['savefig.dpi'] = 255
proj = ccrs.LambertConformal(central_longitude=-95, central_latitude=35,
standard_parallels=[35])
state_boundaries = feat.NaturalEarthFeature(category='cultural',
name='admin_1_states_provinces_lines',
scale='110m', facecolor='none')
# Create the figure
fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(1, 1, 1, projection=proj)
# Add map elements
ax.add_feature(feat.LAND, zorder=-1)
ax.add_feature(feat.OCEAN, zorder=-1)
ax.add_feature(feat.LAKES, zorder=-1)
ax.coastlines(resolution='110m', zorder=2, color='black')
ax.add_feature(state_boundaries)
ax.add_feature(feat.BORDERS, linewidth='2', edgecolor='black')
ax.set_extent((-118, -73, 23, 50))
# Start the station plot by specifying the axes to draw on, as well as the
# lon/lat of the stations (with transform). We also the fontsize to 12 pt.
stationplot = StationPlot(ax, data['longitude'], data['latitude'],
transform=ccrs.PlateCarree(), fontsize=12)
# The layout knows where everything should go, and things are standardized using
# the names of variables. So the layout pulls arrays out of `data` and plots them
# using `stationplot`.
simple_layout.plot(stationplot, data)
.. parsed-literal::
(Apr 10 16 12:52:00 , Apr 10 16 12:52:00 )
425
85
.. image:: Surface_Obs_Plot_with_MetPy_files/Surface_Obs_Plot_with_MetPy_1_1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 753 KiB

View file

@ -1,3 +0,0 @@
=========
Dev Guide
=========

View file

@ -1,269 +0,0 @@
==========================
Grid Levels and Parameters
==========================
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Grid_Levels_and_Parameters.ipynb>`_
List Available Parameters for a Grid Name
-----------------------------------------
.. code:: python
from awips.dataaccess import DataAccessLayer
# Select HRRR
DataAccessLayer.changeEDEXHost("edex-cloud.unidata.ucar.edu")
request = DataAccessLayer.newDataRequest()
request.setDatatype("grid")
request.setLocationNames("GFS40")
# Print parm list
available_parms = DataAccessLayer.getAvailableParameters(request)
available_parms.sort()
for parm in available_parms:
print parm
.. parsed-literal::
AV
BLI
CAPE
CFRZR6hr
CICEP6hr
CIn
CP6hr
CRAIN6hr
CSNOW6hr
GH
P
P6hr
PMSL
PVV
PW
RH
SLI
T
TP6hr
VSS
WEASD
WGH
uW
vW
List Available Levels for Parameter
-----------------------------------
.. code:: python
# Set parm to u-wind
request.setParameters("uW")
# Print level list
available_levels = DataAccessLayer.getAvailableLevels(request)
available_levels.sort()
for level in available_levels:
print level
.. parsed-literal::
1000.0MB
950.0MB
925.0MB
900.0MB
875.0MB
850.0MB
825.0MB
800.0MB
775.0MB
725.0MB
600.0MB
575.0MB
0.0_30.0BL
60.0_90.0BL
90.0_120.0BL
0.5PV
2.0PV
30.0_60.0BL
1.0PV
750.0MB
120.0_150.0BL
975.0MB
700.0MB
675.0MB
650.0MB
625.0MB
550.0MB
525.0MB
500.0MB
450.0MB
400.0MB
300.0MB
250.0MB
200.0MB
150.0MB
100.0MB
0.0TROP
1.5PV
150.0_180.0BL
350.0MB
10.0FHAG
0.0MAXW
Construct Wind Field from U and V Components
--------------------------------------------
.. code:: python
import numpy
from metpy.units import units
# Set level for u-wind
request.setLevels("10.0FHAG")
t = DataAccessLayer.getAvailableTimes(request)
# Select last time for u-wind
response = DataAccessLayer.getGridData(request, [t[-1]])
data_uw = response[-1]
lons,lats = data_uw.getLatLonCoords()
# Select v-wind
request.setParameters("vW")
# Select last time for v-wind
response = DataAccessLayer.getGridData(request, [t[-1]])
data_uv = response[-1]
# Print
print 'Time :', t[-1]
print 'Model:', data_uv.getLocationName()
print 'Unit :', data_uv.getUnit()
print 'Parms :', data_uw.getParameter(), data_uv.getParameter()
print data_uv.getRawData().shape
# Calculate total wind speed
spd = numpy.sqrt( data_uw.getRawData()**2 + data_uv.getRawData()**2 )
spd = spd * units.knot
print "windArray =", spd
data = data_uw
.. parsed-literal::
Time : 2016-04-20 18:00:00 (240)
Model: GFS40
Unit : m*sec^-1
Parms : vW vW
(185, 129)
windArray = [[ 1.47078204 1.69705617 0.69296461 ..., 9.390378 9.14996147 8.55599213] [ 8.23072243 8.20243835 8.31557465 ..., 1.48492408 0.56568539 0.39597979] [ 0.49497473 0.52325904 0.1979899 ..., 2.67286372 2.63043714 2.65872145] ..., [ 2.17788887 2.20617294 2.13546252 ..., 1.01823378 0.62225395 0.39597979] [ 0.02828427 0.8768124 1.51320839 ..., 6.47709799 6.68922997 6.84479332] [ 6.92964649 7.02864122 6.98621511 ..., 0.91923875 1.24450791 1.28693426]] knot
Plotting a Grid with Basemap
----------------------------
Using **matplotlib**, **numpy**, and **basemap**:
.. code:: python
%matplotlib inline
import matplotlib.tri as mtri
import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy
from mpl_toolkits.basemap import Basemap, cm
import numpy as np
from numpy import linspace, transpose
from numpy import meshgrid
plt.figure(figsize=(12, 12), dpi=100)
map = Basemap(projection='cyl',
resolution = 'c',
llcrnrlon = lons.min(), llcrnrlat = lats.min(),
urcrnrlon =lons.max(), urcrnrlat = lats.max()
)
map.drawcoastlines()
map.drawstates()
map.drawcountries()
#
# We have to reproject our grid, see https://stackoverflow.com/questions/31822553/m
#
x = linspace(0, map.urcrnrx, data.getRawData().shape[1])
y = linspace(0, map.urcrnry, data.getRawData().shape[0])
xx, yy = meshgrid(x, y)
ngrid = len(x)
rlons = np.repeat(np.linspace(np.min(lons), np.max(lons), ngrid),
ngrid).reshape(ngrid, ngrid)
rlats = np.repeat(np.linspace(np.min(lats), np.max(lats), ngrid),
ngrid).reshape(ngrid, ngrid).T
tli = mtri.LinearTriInterpolator(mtri.Triangulation(lons.flatten(),
lats.flatten()), spd.flatten())
rdata = tli(rlons, rlats)
#cs = map.contourf(rlons, rlats, rdata, latlon=True)
cs = map.contourf(rlons, rlats, rdata, latlon=True, vmin=0, vmax=20, cmap='BuPu')
# Add colorbar
cbar = map.colorbar(cs,location='bottom',pad="5%")
cbar.set_label("Wind Speed (Knots)")
# Show plot
plt.show()
.. image:: Grid_Levels_and_Parameters_files/Grid_Levels_and_Parameters_7_0.png
or use **pcolormesh** rather than **contourf**
.. code:: python
plt.figure(figsize=(12, 12), dpi=100)
map = Basemap(projection='cyl',
resolution = 'c',
llcrnrlon = lons.min(), llcrnrlat = lats.min(),
urcrnrlon =lons.max(), urcrnrlat = lats.max()
)
map.drawcoastlines()
map.drawstates()
map.drawcountries()
cs = map.pcolormesh(rlons, rlats, rdata, latlon=True, vmin=0, vmax=20, cmap='BuPu')
.. image:: Grid_Levels_and_Parameters_files/Grid_Levels_and_Parameters_9_0.png
Plotting a Grid with Cartopy
----------------------------
.. code:: python
import os
import matplotlib.pyplot as plt
import numpy as np
import iris
import cartopy.crs as ccrs
from cartopy import config
lon,lat = data.getLatLonCoords()
plt.figure(figsize=(12, 12), dpi=100)
ax = plt.axes(projection=ccrs.PlateCarree())
cs = plt.contourf(rlons, rlats, rdata, 60, transform=ccrs.PlateCarree(), vmin=0, vmax=20, cmap='BuPu')
ax.coastlines()
ax.gridlines()
# add colorbar
cbar = plt.colorbar(orientation='horizontal')
cbar.set_label("Wind Speed (Knots)")
plt.show()
.. image:: Grid_Levels_and_Parameters_files/Grid_Levels_and_Parameters_11_0.png

View file

@ -1,335 +0,0 @@
============
Gridded Data
============
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Gridded_Data.ipynb>`_
EDEX Grid Inventory
-------------------
.. code:: python
from awips.dataaccess import DataAccessLayer
# Set host
DataAccessLayer.changeEDEXHost("edex-cloud.unidata.ucar.edu")
# Init data request
request = DataAccessLayer.newDataRequest()
# Set datatype
request.setDatatype("grid")
# Get a list of all available models
available_grids = DataAccessLayer.getAvailableLocationNames(request)
# Sort
available_grids.sort()
for grid in available_grids:
print grid
.. parsed-literal::
AUTOSPE
AVN211
AVN225
DGEX
ECMF-Global
ECMF1
ECMF10
ECMF11
ECMF12
ECMF2
ECMF3
ECMF4
ECMF5
ECMF6
ECMF7
ECMF8
ECMF9
ESTOFS
ETA
FFG-ALR
FFG-FWR
FFG-KRF
FFG-MSR
FFG-ORN
FFG-RHA
FFG-RSA
FFG-TAR
FFG-TIR
FFG-TUA
GFS
GFS40
GFSGuide
GFSLAMP5
GribModel:9:151:172
HFR-EAST_6KM
HFR-EAST_PR_6KM
HFR-US_EAST_DELAWARE_1KM
HFR-US_EAST_FLORIDA_2KM
HFR-US_EAST_NORTH_2KM
HFR-US_EAST_SOUTH_2KM
HFR-US_EAST_VIRGINIA_1KM
HFR-US_HAWAII_1KM
HFR-US_HAWAII_2KM
HFR-US_HAWAII_6KM
HFR-US_WEST_500M
HFR-US_WEST_CENCAL_2KM
HFR-US_WEST_LOSANGELES_1KM
HFR-US_WEST_LOSOSOS_1KM
HFR-US_WEST_NORTH_2KM
HFR-US_WEST_SANFRAN_1KM
HFR-US_WEST_SOCAL_2KM
HFR-US_WEST_WASHINGTON_1KM
HFR-WEST_6KM
HPCGuide
HPCqpf
HPCqpfNDFD
HRRR
LAMP2p5
MPE-Local-ORN
MPE-Local-RHA
MPE-Local-RSA
MPE-Local-TAR
MPE-Local-TIR
MPE-Mosaic-MSR
MPE-Mosaic-ORN
MPE-Mosaic-RHA
MPE-Mosaic-TAR
MPE-Mosaic-TIR
MRMS_1000
NAM12
NAM40
NCWF
NOHRSC-SNOW
NamDNG
NamDNG5
QPE-ALR
QPE-Auto-TUA
QPE-FWR
QPE-KRF
QPE-MSR
QPE-RFC-RSA
QPE-RFC-STR
QPE-TIR
QPE-TUA
QPE-XNAV-ALR
QPE-XNAV-FWR
QPE-XNAV-KRF
QPE-XNAV-MSR
QPE-XNAV-RHA
QPE-XNAV-SJU
QPE-XNAV-TAR
QPE-XNAV-TIR
QPE-XNAV-TUA
RAP13
RAP40
RCM
RFCqpf
RTMA
RTMA5
UKMET-Global
UKMET37
UKMET38
UKMET39
UKMET40
UKMET41
UKMET42
UKMET43
UKMET44
URMA25
estofsPR
fnmocWave
**LocationNames** is different for different plugins - radar is icao -
satellite is sector
Requesting a Grid
-----------------
.. code:: python
# Grid request
request.setLocationNames('RAP40')
request.setParameters("RH")
request.setLevels("850MB")
# Get available times
t = DataAccessLayer.getAvailableTimes(request)
# Select last available time [-1]
response = DataAccessLayer.getGridData(request, [t[0]])
data = response[0]
lon,lat = data.getLatLonCoords()
# Print info
print 'Time :', t[-1]
print 'Model:', data.getLocationName()
print 'Unit :', data.getUnit()
print 'Parm :', data.getParameter()
# Print data array
print data.getRawData().shape
print data.getRawData()
print "lat array =", lat
print "lon array =", lon
.. parsed-literal::
Time : 2016-02-23 15:00:00 (12)
Model: RAP40
Unit : %
Parm : RH
(151, 113)
[[ 93.05456543 93.05456543 87.05456543 ..., 73.05456543 72.05456543
71.05456543]
[ 70.05456543 70.05456543 67.05456543 ..., 69.05456543 46.05456924
37.05456924]
[ 40.05456924 56.05456924 68.05456543 ..., 51.05456924 73.05456543
74.05456543]
...,
[ 65.05456543 62.05456924 63.05456924 ..., 67.05456543 65.05456543
46.05456924]
[ 48.05456924 59.05456924 62.05456924 ..., 4.05456877 5.05456877
5.05456877]
[ 7.05456877 8.05456829 10.05456829 ..., 91.05456543 95.05456543
95.05456543]]
lat array = [[ 54.24940109 54.35071945 54.45080566 ..., 57.9545517 57.91926193
57.88272858]
[ 57.84495163 57.80593109 57.76566696 ..., 58.07667542 58.08861542
58.09931183]
[ 58.10876846 58.11697769 58.12394714 ..., 56.40270996 56.46187973
56.51980972]
...,
[ 19.93209648 19.89832115 19.86351395 ..., 20.054636 20.06362152
20.07156372]
[ 20.0784626 20.08431816 20.08912849 ..., 18.58354759 18.63155174
18.67854691]
[ 18.72453308 18.76950836 18.81346893 ..., 17.49624634 17.42861557
17.36001205]]
lon array = [[-139.83120728 -139.32348633 -138.81448364 ..., -79.26060486
-78.70166016 -78.14326477]
[ -77.58544922 -77.02822876 -76.47161865 ..., -100.70157623
-100.13801575 -99.57427216]
[ -99.01037598 -98.44634247 -97.88218689 ..., -121.69165039
-121.15060425 -120.60871887]
...,
[ -82.65139008 -82.26644897 -81.88170624 ..., -98.52494049
-98.13802338 -97.75105286]
[ -97.36403656 -96.97698212 -96.58989716 ..., -113.07767487
-112.69831085 -112.31866455]
[-111.93874359 -111.5585556 -111.17810822 ..., -69.85433197
-69.48160553 -69.10926819]]
Plotting a Grid with Basemap
----------------------------
Using **matplotlib**, **numpy**, and **basemap**:
.. code:: python
import matplotlib.tri as mtri
import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy
from mpl_toolkits.basemap import Basemap, cm
import numpy as np
from numpy import linspace, transpose
from numpy import meshgrid
plt.figure(figsize=(12, 12), dpi=100)
lons,lats = data.getLatLonCoords()
map = Basemap(projection='cyl',
resolution = 'c',
llcrnrlon = lons.min(), llcrnrlat = lats.min(),
urcrnrlon =lons.max(), urcrnrlat = lats.max()
)
map.drawcoastlines()
map.drawstates()
map.drawcountries()
#
# We have to reproject our grid, see https://stackoverflow.com/questions/31822553/m
#
x = linspace(0, map.urcrnrx, data.getRawData().shape[1])
y = linspace(0, map.urcrnry, data.getRawData().shape[0])
xx, yy = meshgrid(x, y)
ngrid = len(x)
rlons = np.repeat(np.linspace(np.min(lons), np.max(lons), ngrid),
ngrid).reshape(ngrid, ngrid)
rlats = np.repeat(np.linspace(np.min(lats), np.max(lats), ngrid),
ngrid).reshape(ngrid, ngrid).T
tli = mtri.LinearTriInterpolator(mtri.Triangulation(lons.flatten(),
lats.flatten()), data.getRawData().flatten())
rdata = tli(rlons, rlats)
cs = map.contourf(rlons, rlats, rdata, latlon=True, vmin=0, vmax=100, cmap='YlGn')
# add colorbar.
cbar = map.colorbar(cs,location='bottom',pad="5%")
cbar.set_label(data.getParameter() + data.getUnit() )
# Show plot
plt.show()
.. image:: Gridded_Data_files/Gridded_Data_5_0.png
or use **pcolormesh** rather than **contourf**
.. code:: python
plt.figure(figsize=(12, 12), dpi=100)
map = Basemap(projection='cyl',
resolution = 'c',
llcrnrlon = lons.min(), llcrnrlat = lats.min(),
urcrnrlon =lons.max(), urcrnrlat = lats.max()
)
map.drawcoastlines()
map.drawstates()
map.drawcountries()
cs = map.pcolormesh(rlons, rlats, rdata, latlon=True, vmin=0, vmax=100, cmap='YlGn')
.. image:: Gridded_Data_files/Gridded_Data_7_0.png
Plotting a Grid with Cartopy
----------------------------
.. code:: python
import os
import matplotlib.pyplot as plt
import numpy as np
import iris
import cartopy.crs as ccrs
from cartopy import config
lon,lat = data.getLatLonCoords()
plt.figure(figsize=(12, 12), dpi=100)
ax = plt.axes(projection=ccrs.PlateCarree())
cs = plt.contourf(rlons, rlats, rdata, 60, transform=ccrs.PlateCarree(), vmin=0, vmax=100, cmap='YlGn')
ax.coastlines()
ax.gridlines()
# add colorbar
cbar = plt.colorbar(orientation='horizontal')
cbar.set_label(data.getParameter() + data.getUnit() )
plt.show()
.. image:: Gridded_Data_files/Gridded_Data_9_0.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 KiB

View file

@ -1,112 +0,0 @@
===================================
NEXRAD Level 3 Plot with Matplotlib
===================================
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/NEXRAD_Level_3_Plot_with_Matplotlib.ipynb>`_
NEXRAD Level 3 Plot with Matplotlib
===================================
.. code:: python
%matplotlib inline
from awips.dataaccess import DataAccessLayer
from awips import ThriftClient, RadarCommon
from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.radar.request import GetRadarDataRecordRequest
from datetime import datetime
from datetime import timedelta
import matplotlib.pyplot as plt
import numpy as np
from numpy import ma
# use metpy for color table
from metpy.plots import ctables
# Set EDEX server and radar site
DataAccessLayer.changeEDEXHost("edex-cloud.unidata.ucar.edu")
request = DataAccessLayer.newDataRequest()
request.setDatatype("radar")
request.setLocationNames("klzk")
datatimes = DataAccessLayer.getAvailableTimes(request)
# Get last available time
timerange = datatimes[-1].validPeriod
dateTimeStr = str(datatimes[-1])
# Buffer length in seconds
buffer = 60
dateTime = datetime.strptime(dateTimeStr, "%Y-%m-%d %H:%M:%S")
beginRange = dateTime - timedelta(0, buffer)
endRange = dateTime + timedelta(0, buffer)
timerange = TimeRange(beginRange, endRange)
print "using time",dateTimeStr
print "buffer by",buffer
print "using range",timerange
client = ThriftClient.ThriftClient(edex)
request = GetRadarDataRecordRequest()
request.setRadarId(site)
request.setPrimaryElevationAngle("0.5")
request.setTimeRange(timerange)
fig, axes = plt.subplots(1, 2, figsize=(15, 8))
for v, ctable, ax in zip((94, 99), ('NWSReflectivity', 'NWSVelocity'), axes):
request.setProductCode(v)
response = client.sendRequest(request)
if response.getData():
for record in response.getData():
idra = record.getHdf5Data()
rdat,azdat,depVals,threshVals = RadarCommon.get_hdf5_data(idra)
dim = rdat.getDimension()
yLen,xLen = rdat.getSizes()
array = rdat.getByteData()
# get data for azimuth angles if we have them.
if azdat :
azVals = azdat.getFloatData()
az = np.array(RadarCommon.encode_radial(azVals))
dattyp = RadarCommon.get_data_type(azdat)
az = np.append(az,az[-1])
print "found",v,record.getDataTime()
header = RadarCommon.get_header(record, format, xLen, yLen, azdat, "description")
rng = np.linspace(0, xLen, xLen + 1)
xlocs = rng * np.sin(np.deg2rad(az[:, np.newaxis]))
ylocs = rng * np.cos(np.deg2rad(az[:, np.newaxis]))
multiArray = np.reshape(array, (-1, xLen))
data = ma.array(multiArray)
data[data==0] = ma.masked
# Plot the data
norm, cmap = ctables.registry.get_with_steps(ctable, 16, 16)
ax.pcolormesh(xlocs, ylocs, data, norm=norm, cmap=cmap)
ax.set_aspect('equal', 'datalim')
multp = 100*(2*xLen/460)
ax.set_xlim(-multp,multp)
ax.set_ylim(-multp,multp)
# This is setting x/ylim on gate/pixel and not km
plt.show()
.. parsed-literal::
using time 2016-04-11 23:02:22
buffer by 60
using range (Apr 11 16 23:01:22 , Apr 11 16 23:03:22 )
found 94 2016-04-11 23:02:22
found 99 2016-04-11 23:02:22
.. image:: NEXRAD_Level_3_Plot_with_Matplotlib_files/NEXRAD_Level_3_Plot_with_Matplotlib_1_1.png

View file

@ -1,134 +0,0 @@
==============================
Plotting a Sounding with MetPy
==============================
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Plotting_a_Sounding_with_MetPy.ipynb>`_
Plotting a Sounding with MetPy
==============================
.. code:: python
%matplotlib inline
from awips.dataaccess import DataAccessLayer
import matplotlib.tri as mtri
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import numpy as np
from metpy.calc import get_wind_components, lcl, dry_lapse, parcel_profile
from metpy.plots import SkewT, Hodograph
from metpy.units import units, concatenate
plt.rcParams['figure.figsize'] = (12, 14)
# Set EDEX host
DataAccessLayer.changeEDEXHost("edex-cloud.unidata.ucar.edu")
request = DataAccessLayer.newDataRequest()
# Data type bufrua
request.setDatatype("bufrua")
# Parameters
request.setParameters("tpMan","tdMan","prMan","htMan","wdMan","wsMan")
# Station ID (name doesn't work yet)
request.setLocationNames("72469")
datatimes = DataAccessLayer.getAvailableTimes(request)
# Get most recent record
response = DataAccessLayer.getGeometryData(request,times=datatimes[-1].validPeriod)
# Initialize data arrays
tpMan,tdMan,prMan,htMan,wdMan,wsMan = [],[],[],[],[],[]
# Build ordered arrays
for ob in response:
print float(ob.getString("prMan")), float(ob.getString("wsMan"))
tpMan.append(float(ob.getString("tpMan")))
tdMan.append(float(ob.getString("tdMan")))
prMan.append(float(ob.getString("prMan")))
htMan.append(float(ob.getString("htMan")))
wdMan.append(float(ob.getString("wdMan")))
wsMan.append(float(ob.getString("wsMan")))
# we can use units.* here...
T = np.array(tpMan)-273.15
Td = np.array(tdMan)-273.15
p = np.array(prMan)/100
height = np.array(htMan)
direc = np.array(wdMan)
spd = np.array(wsMan)
u, v = get_wind_components(spd, np.deg2rad(direc))
p = p * units.mbar
T = T * units.degC
Td = Td * units.degC
spd = spd * units.knot
direc = direc * units.deg
# Create a skewT plot
skew = SkewT()
# Plot the data using normal plotting functions, in this case using
# log scaling in Y, as dictated by the typical meteorological plot
skew.plot(p, T, 'r')
skew.plot(p, Td, 'g')
skew.plot_barbs(p, u, v)
skew.ax.set_ylim(1000, 100)
skew.ax.set_xlim(-40, 60)
# Calculate LCL height and plot as black dot
l = lcl(p[0], T[0], Td[0])
lcl_temp = dry_lapse(concatenate((p[0], l)), T[0])[-1].to('degC')
skew.plot(l, lcl_temp, 'ko', markerfacecolor='black')
# Calculate full parcel profile and add to plot as black line
prof = parcel_profile(p, T[0], Td[0]).to('degC')
skew.plot(p, prof, 'k', linewidth=2)
# Example of coloring area between profiles
skew.ax.fill_betweenx(p, T, prof, where=T>=prof, facecolor='blue', alpha=0.4)
skew.ax.fill_betweenx(p, T, prof, where=T<prof, facecolor='red', alpha=0.4)
# An example of a slanted line at constant T -- in this case the 0 isotherm
l = skew.ax.axvline(0, color='c', linestyle='--', linewidth=2)
# Draw hodograph
ax_hod = inset_axes(skew.ax, '40%', '40%', loc=3)
h = Hodograph(ax_hod, component_range=80.)
h.add_grid(increment=20)
h.plot_colormapped(u, v, spd)
# Show the plot
plt.show()
.. parsed-literal::
83900.0 1.5
100000.0 -9999998.0
92500.0 -9999998.0
85000.0 -9999998.0
70000.0 0.5
50000.0 6.09999990463
40000.0 3.0
30000.0 7.69999980927
25000.0 16.8999996185
20000.0 7.19999980927
15000.0 10.1999998093
10000.0 13.8000001907
7000.0 9.19999980927
5000.0 7.69999980927
3000.0 5.59999990463
2000.0 6.59999990463
1000.0 10.8000001907
700.0 5.09999990463
500.0 -9999.0
300.0 -9999.0
200.0 -9999.0
100.0 -9999.0
.. image:: Plotting_a_Sounding_with_MetPy_files/Plotting_a_Sounding_with_MetPy_1_1.png

View file

@ -1,212 +0,0 @@
===========
Surface Obs
===========
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Surface_Obs.ipynb>`_
.. code:: python
from awips.dataaccess import DataAccessLayer
# Set host
DataAccessLayer.changeEDEXHost("edex-cloud.unidata.ucar.edu")
# Init data request
request = DataAccessLayer.newDataRequest()
request.setDatatype("obs")
request.setLocationNames("KBJC")
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
# "presWeather","skyCover","skyLayerBase"
# are multi-dimensional... deal with these later
request.setParameters(
"stationName",
"timeObs",
"wmoId",
"autoStationType",
"elevation",
"reportType",
"temperature",
"tempFromTenths",
"dewpoint",
"dpFromTenths",
"windDir",
"windSpeed",
"windGust",
"visibility",
"altimeter",
"seaLevelPress",
"pressChange3Hour",
"pressChangeChar",
"maxTemp24Hour",
"minTemp24Hour",
"precip1Hour",
"precip3Hour",
"precip6Hour",
"precip24Hour"
)
response = DataAccessLayer.getGeometryData(request,times=time)
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())
#getParameters
print ob.getString("stationName"), "from", ob.getDataTime().getRefTime()
print "stationName is",ob.getString("stationName")
print "timeObs is",ob.getString("timeObs")
print "wmoId is",ob.getString("wmoId")
print "autoStationType is",ob.getString("autoStationType")
print "elevation is",ob.getString("elevation")
print "reportType is",ob.getString("reportType")
print "temperature is",ob.getString("temperature")
print "tempFromTenths is",ob.getString("tempFromTenths")
print "dewpoint is",ob.getString("dewpoint")
print "dpFromTenths is",ob.getString("dpFromTenths")
print "windDir is",ob.getString("windDir")
print "windSpeed is",ob.getString("windSpeed")
print "windGust is",ob.getString("windGust")
print "visibility is",ob.getString("visibility")
print "altimeter is",ob.getString("altimeter")
print "seaLevelPress is",ob.getString("seaLevelPress")
print "pressChange3Hour is",ob.getString("pressChange3Hour")
print "pressChangeChar is",ob.getString("pressChangeChar")
print "maxTemp24Hour is",ob.getString("maxTemp24Hour")
print "minTemp24Hour is",ob.getString("minTemp24Hour")
print "precip1Hour is",ob.getString("precip1Hour")
print "precip3Hour is",ob.getString("precip3Hour")
print "precip6Hour is",ob.getString("precip6Hour")
print "precip24Hour is",ob.getString("precip24Hour")
.. code:: python
# multi-dimensional present WX
request = DataAccessLayer.newDataRequest()
request.setDatatype("obs")
request.setLocationNames("KBJC")
request.setParameters("presWeather")
response = DataAccessLayer.getGeometryData(request,times=time)
for ob in response:
print "getParameters is",ob.getParameters()
print ob.getString("presWeather")
# multi-dimensional Sky Condition
request.setParameters("skyCover", "skyLayerBase")
response = DataAccessLayer.getGeometryData(request,times=time)
for ob in response:
print ob.getString("skyCover")
print ob.getString("skyLayerBase")
Synop/Marine
------------
.. code:: python
from awips.dataaccess import DataAccessLayer
request = DataAccessLayer.newDataRequest()
request.setDatatype("sfcobs")
request.setLocationNames("72421") # Covington, Kentucky (KCVG)
request.setParameters("stationId","timeObs","elevation","reportType",
"wx_present","visibility","seaLevelPress","stationPress",
"pressChange3Hour","pressChangeChar","temperature",
"dewpoint","seaSurfaceTemp","wetBulb","windDir",
"windSpeed","equivWindSpeed10m","windGust","precip1Hour",
"precip6Hour","precip24Hour" )
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
response = DataAccessLayer.getGeometryData(request,times=time)
print response
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())
Profiler
--------
.. code:: python
MULTI_DIM_PARAMS = set(['vComponent', 'uComponent', 'peakPower',
'levelMode', 'uvQualityCode', 'consensusNum',
'HorizSpStdDev', 'wComponent', 'height',
'VertSpStdDev'])
request = DataAccessLayer.newDataRequest("profiler")
request.setParameters('numProfLvls', 'elevation', 'windDirSfc', 'validTime',
'windSpeedSfc', 'pressure', 'submode', 'relHumidity',
'profilerId', 'rainRate', 'temperature')
request.getParameters().extend(MULTI_DIM_PARAMS)
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
response = DataAccessLayer.getGeometryData(request,times=time)
print response
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())
ACARS
-----
.. code:: python
request = DataAccessLayer.newDataRequest("acars")
request.setParameters("tailNumber", "receiver", "pressure", "flightPhase",
"rollAngleQuality", "temp", "windDirection", "windSpeed",
"humidity", "mixingRatio", "icing")
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
response = DataAccessLayer.getGeometryData(request,times=time)
print response
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())
AIREP
-----
.. code:: python
request = DataAccessLayer.newDataRequest("airep")
request.setParameters("id", "flightLevel", "temp", "windDirection", "windSpeed",
"flightWeather", "flightHazard", "flightConditions")
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
response = DataAccessLayer.getGeometryData(request,times=time)
print response
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())
PIREP
-----
.. code:: python
MULTI_DIM_PARAMS = set(["hazardType",
"turbType", "turbBaseHeight", "turbTopHeight",
"iceType", "iceBaseHeight", "iceTopHeight",
"skyCover1", "skyCover2", "skyBaseHeight", "skyTopHeight"
])
request = DataAccessLayer.newDataRequest("pirep")
request.setParameters('id', 'flightLevel', 'temp', 'windDirection', 'windSpeed',
'horzVisibility', 'aircraftType', 'weatherGroup')
request.getParameters().extend(MULTI_DIM_PARAMS)
datatimes = DataAccessLayer.getAvailableTimes(request)
time = datatimes[-1].validPeriod
response = DataAccessLayer.getGeometryData(request,times=time)
print response
for ob in response:
print "getParameters is",ob.getParameters()
print len(ob.getParameters())

View file

@ -1,144 +0,0 @@
===========================
Surface Obs Plot with MetPy
===========================
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Surface_Obs_Plot_with_MetPy.ipynb>`_
Based on the MetPy example `"Station Plot with
Layout" <http://metpy.readthedocs.org/en/latest/examples/generated/Station_Plot_with_Layout.html>`_
.. code:: python
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from awips.dataaccess import DataAccessLayer
from metpy.calc import get_wind_components
from metpy.cbook import get_test_data
from metpy.plots import StationPlot, StationPlotLayout, simple_layout
from metpy.units import units
# Initialize
DataAccessLayer.changeEDEXHost("edex-cloud.unidata.ucar.edu")
data,latitude,longitude,stationName,temperature,dewpoint,seaLevelPress,windDir,windSpeed = [],[],[],[],[],[],[],[],[]
request = DataAccessLayer.newDataRequest()
request.setDatatype("obs")
#
# we need to set one station to query latest time. this is hack-y and should be fixed
# because when you DON'T set a location name, you tend to get a single observation
# that came in a second ago, so your "latest data for the last time for all stations"
# data array consists of one village in Peru and time-matching is suspect right now.
#
# So here take a known US station (OKC) and hope/assume that a lot of other stations
# are also reporting (and that this is a 00/20/40 ob).
#
request.setLocationNames("KOKC")
datatimes = DataAccessLayer.getAvailableTimes(request)
# Get most recent time for location
time = datatimes[0].validPeriod
# "presWeather","skyCover","skyLayerBase"
# are multi-dimensional(??) and returned seperately (not sure why yet)... deal with those later
request.setParameters("presWeather","skyCover", "skyLayerBase","stationName","temperature","dewpoint","windDir","windSpeed",
"seaLevelPress","longitude","latitude")
request.setLocationNames()
response = DataAccessLayer.getGeometryData(request,times=time)
print time
PRES_PARAMS = set(["presWeather"])
SKY_PARAMS = set(["skyCover", "skyLayerBase"])
# Build ordered arrays
wx,cvr,bas=[],[],[]
for ob in response:
#print ob.getParameters()
if set(ob.getParameters()) & PRES_PARAMS :
wx.append(ob.getString("presWeather"))
continue
if set(ob.getParameters()) & SKY_PARAMS :
cvr.append(ob.getString("skyCover"))
bas.append(ob.getNumber("skyLayerBase"))
continue
latitude.append(float(ob.getString("latitude")))
longitude.append(float(ob.getString("longitude")))
#stationName.append(ob.getString("stationName"))
temperature.append(float(ob.getString("temperature")))
dewpoint.append(float(ob.getString("dewpoint")))
seaLevelPress.append(float(ob.getString("seaLevelPress")))
windDir.append(float(ob.getString("windDir")))
windSpeed.append(float(ob.getString("windSpeed")))
print len(wx)
print len(temperature)
# Convert
data = dict()
data['latitude'] = np.array(latitude)
data['longitude'] = np.array(longitude)
data['air_temperature'] = np.array(temperature)* units.degC
data['dew_point_temperature'] = np.array(dewpoint)* units.degC
#data['air_pressure_at_sea_level'] = np.array(seaLevelPress)* units('mbar')
u, v = get_wind_components(np.array(windSpeed) * units('knots'),
np.array(windDir) * units.degree)
data['eastward_wind'], data['northward_wind'] = u, v
# Convert the fraction value into a code of 0-8, which can be used to pull out
# the appropriate symbol
#data['cloud_coverage'] = (8 * data_arr['cloud_fraction']).astype(int)
# Map weather strings to WMO codes, which we can use to convert to symbols
# Only use the first symbol if there are multiple
#wx_text = make_string_list(data_arr['weather'])
#wx_codes = {'':0, 'HZ':5, 'BR':10, '-DZ':51, 'DZ':53, '+DZ':55,
# '-RA':61, 'RA':63, '+RA':65, '-SN':71, 'SN':73, '+SN':75}
#data['present_weather'] = [wx_codes[s.split()[0] if ' ' in s else s] for s in wx]
# Set up the map projection
import cartopy.crs as ccrs
import cartopy.feature as feat
from matplotlib import rcParams
rcParams['savefig.dpi'] = 255
proj = ccrs.LambertConformal(central_longitude=-95, central_latitude=35,
standard_parallels=[35])
state_boundaries = feat.NaturalEarthFeature(category='cultural',
name='admin_1_states_provinces_lines',
scale='110m', facecolor='none')
# Create the figure
fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(1, 1, 1, projection=proj)
# Add map elements
ax.add_feature(feat.LAND, zorder=-1)
ax.add_feature(feat.OCEAN, zorder=-1)
ax.add_feature(feat.LAKES, zorder=-1)
ax.coastlines(resolution='110m', zorder=2, color='black')
ax.add_feature(state_boundaries)
ax.add_feature(feat.BORDERS, linewidth='2', edgecolor='black')
ax.set_extent((-118, -73, 23, 50))
# Start the station plot by specifying the axes to draw on, as well as the
# lon/lat of the stations (with transform). We also the fontsize to 12 pt.
stationplot = StationPlot(ax, data['longitude'], data['latitude'],
transform=ccrs.PlateCarree(), fontsize=12)
# The layout knows where everything should go, and things are standardized using
# the names of variables. So the layout pulls arrays out of `data` and plots them
# using `stationplot`.
simple_layout.plot(stationplot, data)
.. parsed-literal::
(Apr 10 16 12:52:00 , Apr 10 16 12:52:00 )
425
85
.. image:: Surface_Obs_Plot_with_MetPy_files/Surface_Obs_Plot_with_MetPy_1_1.png

View file

@ -5,6 +5,7 @@
################
.. toctree::
:maxdepth: 1
:glob:
generated/*

View file

@ -11,7 +11,7 @@ Documentation
-------------
.. toctree::
:maxdepth: 2
:maxdepth: 2
install
examples/index

View file

@ -1,464 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"# Dev Guide\n",
"\n",
"The Data Access Framework allows developers to retrieve different types of data without having dependencies on those types of data. It provides a single, unified data type that can be customized by individual implementing plug-ins to provide full functionality pertinent to each data type.\n",
"\n",
"\n",
"## Writing a New Factory\n",
"\n",
"Factories will most often be written in a dataplugin, but should always be written in a\n",
"common plug-in. This will allow for clean dependencies from both CAVE and\n",
"EDEX.\n",
"\n",
"A new plug-ins data access class must implement IDataFactory. For ease of use,\n",
"abstract classes have been created to combine similar methods. Data factories do not\n",
"have to implement both types of data (grid and geometry). They can if they choose,\n",
"but if they choose not to, they should do the following:\n",
"\n",
" throw new UnsupportedOutputTypeException(request.getDatatype(), \"grid\");\n",
"\n",
"This lets the code know that grid type is not supported for this data factory.\n",
"Depending on where the data is coming from, helpers have been written to make\n",
"writing a new data type factory easier. For example, PluginDataObjects can use\n",
"AbstractDataPluginFactory as a start and not have to create everything from scratch.\n",
"\n",
"Each data type is allowed to implement retrieval in any manner that is felt necessary.\n",
"The power of the framework means that the code retrieving data does not have to\n",
"know anything of the underlying retrieval methods, only that it is getting data in \n",
"a certain manner. To see some examples of ways to retrieve data, reference \n",
"**SatelliteGridFactory** and **RadarGridFactory**.\n",
"\n",
"Methods required for implementation:\n",
"\n",
"**public DataTime[] getAvailableTimes(IDataRequest request)**\n",
"\n",
"- This method returns an array of DataTime objects corresponding to what times are available for the data being retrieved, based on the parameters and identifiers being passed in.\n",
" \n",
"**public DataTime[] getAvailableTimes(IDataRequest request, BinOffset binOffset)**\n",
"\n",
"- This method returns available times as above, only with a bin offset applied.\n",
"\n",
"Note: Both of the preceding methods can throw TimeAgnosticDataException exceptions if times do not apply to the data type.\n",
"\n",
"**public IGridData[] getGridData(IDataRequest request, DataTime...times)**\n",
"\n",
"- This method returns IGridData objects (an array) based on the request and times to request for. There can be multiple times or a single time.\n",
"\n",
"**public IGridData[] getGridData(IDataRequest request, TimeRange range)**\n",
"\n",
"- Similar to the preceding method, this returns IGridData objects based on a range of times.\n",
"\n",
"**public IGeometryData[] getGeometryData(IDataRequest request, DataTime times)**\n",
"\n",
"- This method returns IGeometryData objects based on a request and times.\n",
"\n",
"**public IGeometryData[] getGeometryData(IDataRequest request, TimeRange range)**\n",
"\n",
"- Like the preceding method, this method returns IGeometryData objects based on a range of times.\n",
"\n",
"**public String[] getAvailableLocationNames(IDataRequest request)**\n",
"\n",
"- This method returns location names that match the request. If this does not apply to the data type, an IncompatibleRequestException should be thrown.\n",
"\n",
"## Registering the Factory with the Framework\n",
"\n",
"The following needs to be added in a spring file in the plug-in that contains the\n",
"new factory:\n",
"\n",
" <bean id=\"radarGridFactory\"\n",
" class=\"com.raytheon.uf.common.dataplugin.radar.dataaccess.RadarGridFactory\" /> \n",
" <bean factory-bean=\"dataAccessRegistry\" factorymethod=\"register\">\n",
" <constructor-arg value=\"radar\"/>\n",
" <constructor-arg ref=\"radarGridFactory\"/>\n",
" </bean>\n",
" \n",
"This takes the RadarGridFactory and registers it with the registry and allows it to\n",
"be used any time the code makes a request for the data type “radar.”\n",
"\n",
"\n",
"## Retrieving Data Using the Factory \n",
"\n",
"For ease of use and more diverse use, there are multiple interfaces into the Data\n",
"Access Layer. Currently, there is a Python implementation and a Java\n",
"implementation, which have very similar method calls and work in a similar\n",
"manner. Plug-ins that want to use the data access framework to retrieve data\n",
"should include **com.raytheon.uf.common.dataaccess** as a Required Bundle in\n",
"their MANIFEST.MF.\n",
"\n",
"To retrieve data using the Python interface :\n",
"\n",
" from awips.dataaccess import DataAccessLayer\n",
" req = DataAccessLayer.newDataRequest()\n",
" req.setDatatype(\"grid\")\n",
" req.setParameters(\"T\")\n",
" req.setLevels(\"2FHAG\")\n",
" req.addIdentifier(\"info.datasetId\", \"GFS40\")\n",
" times = DataAccessLayer.getAvailableTimes(req)\n",
" data = DataAccessLayer.getGridData(req, times)\n",
" \n",
"To retrieve data using the Java interface :\n",
"\n",
" IDataRequest req = DataAccessLayer.newDataRequest();\n",
" req.setDatatype(\"grid\");\n",
" req.setParameters(\"T\");\n",
" req.setLevels(\"2FHAG\");\n",
" req.addIdentifier(\"info.datasetId\", \"GFS40\");\n",
" DataTime[] times = DataAccessLayer.getAvailableTimes(req)\n",
" IData data = DataAccessLayer.getGridData(req, times);\n",
" \n",
"**newDataRequest()**\n",
"\n",
"- This creates a new data request. Most often this is a DefaultDataRequest, but saves for future implentations as well.\n",
"\n",
"**setDatatype(String)**\n",
"\n",
"- This is the data type being retrieved. This can be found as the value that is registered when creating the new factory (See section above **Registering the Factory with the Framework** [radar in that case]).\n",
"\n",
"**setParameters(String...)**\n",
"\n",
"- This can differ depending on data type. It is most often used as a main difference between products.\n",
"\n",
"**setLevels(String...)**\n",
"\n",
"- This is often used to identify the same products on different mathematical angles, heights, levels, etc.\n",
"\n",
"**addIdentifier(String, String)**\n",
"\n",
"- This differs based on data type, but is often used for more fine-tuned querying.\n",
"\n",
"Both methods return a similar set of data and can be manipulated by their\n",
"respective languages. See DataAccessLayer.py and DataAccessLayer.java for\n",
"more methods that can be called to retrieve data and different parts of the data.\n",
"Because each data type has different parameters, levels, and identifiers, it is best\n",
"to see the actual data type for the available options. If it is undocumented, then the\n",
"best way to identify what parameters are to be used is to reference the code."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Development Background\n",
"\n",
"In support of Hazard Services Raytheon Technical Services is building a generic data access framework that can be called via JAVA or Python. The data access framework code can be found within the AWIPS Baseline in\n",
"\n",
" com.raytheon.uf.common.dataaccess\n",
"\n",
"As of 2016, plugins have been written for grid, radar, satellite, Hydro (SHEF), point data (METAR, SYNOP, Profiler, ACARS, AIREP, PIREP), maps data, and other data types. The Factories for each can be found in the following packages (you may need to look at the development baseline to see these):\n",
"\n",
" com.raytheon.uf.common.dataplugin.grid.dataaccess\n",
" com.raytheon.uf.common.dataplugin.radar.dataaccess\n",
" com.raytheon.uf.common.dataplugin.satellite.dataaccess\n",
" com.raytheon.uf.common.dataplugin.binlightning.dataaccess\n",
" com.raytheon.uf.common.dataplugin.sfc.dataaccess\n",
" com.raytheon.uf.common.dataplugin.sfcobs.dataaccess\n",
" com.raytheon.uf.common.dataplugin.acars.dataaccess\n",
" com.raytheon.uf.common.dataplugin.ffmp.dataaccess\n",
" com.raytheon.uf.common.dataplugin.bufrua.dataaccess\n",
" com.raytheon.uf.common.dataplugin.profiler.dataaccess\n",
" com.raytheon.uf.common.dataplugin.moddelsounding.dataaccess\n",
" com.raytheon.uf.common.dataplugin.ldadmesonet.dataaccess\n",
" com.raytheon.uf.common.dataplugin.binlightning.dataaccess\n",
" com.raytheon.uf.common.dataplugin.gfe.dataaccess\n",
" com.raytheon.uf.common.hydro.dataaccess\n",
" com.raytheon.uf.common.pointdata.dataaccess\n",
" com.raytheon.uf.common.dataplugin.maps.dataaccess\n",
"\n",
"\n",
"Additional data types may be added in the future. To determine what datatypes are supported display the \"type hierarchy\" associated with the classes\n",
"\n",
"**AbstractGridDataPluginFactory**, \n",
"\n",
"**AbstractGeometryDatabaseFactory**, and \n",
"\n",
"**AbstractGeometryTimeAgnosticDatabaseFactory**.\n",
"\n",
"The following content was taken from the design review document which is attached and modified slightly.\n",
"\n",
"## Design/Implementation\n",
"\n",
"The Data Access Framework is designed to provide a consistent interface for requesting and using geospatial data within CAVE or EDEX. Examples of geospatial data are grids, satellite, radar, metars, maps, river gage heights, FFMP basin data, airmets, etc. To allow for convenient use of geospatial data, the framework will support two types of requests: grids and geometries (points, polygons, etc). The framework will also hide implementation details of specific data types from users, making it easier to use data without worrying about how the data objects are structured or retrieved.\n",
"\n",
"A suggested mapping of some current data types to one of the two supported data requests is listed below. This list is not definitive and can be expanded. If a developer can dream up an interpretation of the data in the other supported request type, that support can be added.\n",
"\n",
"Grids\n",
"\n",
"* Grib\n",
"* Satellite\n",
"* Radar\n",
"* GFE\n",
"\n",
"Geometries\n",
"\n",
"* Map (states, counties, zones, etc)\n",
"* Hydro DB (IHFS)\n",
"* Obs (metar)\n",
"* FFMP\n",
"* Hazard\n",
"* Warning\n",
"* CCFP\n",
"* Airmet\n",
"\n",
"The framework is designed around the concept of each data type plugin contributing the necessary code for the framework to support its data. For example, the satellite plugin provides a factory class for interacting with the framework and registers itself as being compatible with the Data Access Framework. This concept is similar to how EDEX in AWIPS II expects a plugin developer to provide a decoder class and record class and register them, but then automatically manages the rest of the ingest process including routing, storing, and alerting on new data. This style of plugin architecture effectively enables the framework to expand its capabilities to more data types without having to alter the framework code itself. This will enable software developers to incrementally add support for more data types as time allows, and allow the framework to expand to new data types as they become available.\n",
"\n",
"The Data Access Framework will not break any existing functionality or APIs, and there are no plans to retrofit existing cosde to use the new API at this time. Ideally code will be retrofitted in the future to improve ease of maintainability. The plugin pecific code that hooks into the framework will make use of existing APIs such as **IDataStore** and **IServerRequest** to complete the requests.\n",
"\n",
"The Data Access Framework can be understood as three parts:\n",
"\n",
"* How users of the framework retrieve and use the data\n",
"* How plugin developers contribute support for new data types\n",
"* How the framework works when it receives a request\n",
"\n",
"## How users of the framework retrieve and use the data\n",
"\n",
"When a user of the framework wishes to request data, they must instantiate a request object and set some of the values on that request. Two request interfaces will be supported, for detailed methods see section \"Detailed Code\" below.\n",
"\n",
"**IDataRequest**\n",
"\n",
"**IGridRequest** extends **IDataRequest**\n",
"\n",
"**IGeometryRequest** extends **IDataRequest**\n",
"\n",
"For the request interfaces, default implementations of **DefaultGridRequest** and **DefaultGeometryRequest** will be provided to handle most cases. However, the use of interfaces allows for custom special cases in the future. If necessary, the developer of a plugin can write their own custom request implementation to handle a special case.\n",
"\n",
"After the request object has been prepared, the user will pass it to the Data Access Layer to receive a data object in return. See the \"Detailed Code\" section below for detailed methods of the Data Access Layer. The Data Access Layer will return one of two data interfaces.\n",
"\n",
"**IData**\n",
"\n",
"**IGridData** extends **IData**\n",
"\n",
"**IGeometryData** extends **IData**\n",
"\n",
"For the data interfaces, the use of interfaces effectively hides the implementation details of specific data types from the user of the framework. For example, the user receives an **IGridData** and knows the data time, grid geometry, parameter, and level, but does not know that the data is actually a **GFEGridData** vs **D2DGridData** vs **SatelliteGridData**. This enables users of the framework to write generic code that can support multiple data types.\n",
"\n",
"For python users of the framework, the interfaces will be very similar with a few key distinctions. Geometries will be represented by python geometries from the open source Shapely project. For grids, the python **IGridData** will have a method for requesting the raw data as a numpy array, and the Data Access Layer will have methods for requesting the latitude coordinates and the longitude coordinates of grids as numpy arrays. The python requests and data objects will be pure python and not JEP PyJObjects that wrap Java objects. A future goal of the Data Access Framework is to provide support to python local apps and therefore enable requests of data outside of CAVE and EDEX to go through the same familiar interfaces. This goal is out of scope for this project but by making the request and returned data objects pure python it will not be a huge undertaking to add this support in the future.\n",
"\n",
"\n",
"## How plugin developers contribute support for new datatypes\n",
"\n",
"When a developer wishes to add support for another data type to the framework, they must implement one or both of the factory interfaces within a common plugin. Two factory interfaces will be supported, for detailed methods see below.\n",
"\n",
"**IDataFactory**\n",
"\n",
"**IGridFactory** extends **IDataFactory**\n",
"\n",
"**IGeometryFactory** extends **IDataFactory**\n",
"\n",
"For some data types, it may be desired to add support for both types of requests. For example, the developer of grid data may want to provide support for both grid requests and geometry requests. In this case the developer would write two separate classes where one implements **IGridFactory** and the other implements **IGeometryFactory**. Furthermore, factories could be stacked on top of one another by having factory implementations call into the Data Access Layer. \n",
"\n",
"For example, a custom factory keyed to \"derived\" could be written for derived parameters, and the implementation of that factory may then call into the Data Access Layer to retrieve “grid” data. In this example the raw data would be retrieved through the **GridDataFactory** while the derived factory then applies the calculations before returning the data.\n",
"\n",
"Implementations do not need to support all methods on the interfaces or all values on the request objects. For example, a developer writing the **MapGeometryFactory** does not need to support **getAvailableTimes()** because map data such as US counties is time agnostic. In this case the method should throw **UnsupportedOperationException** and the javadoc will indicate this. \n",
"\n",
"Another example would be the developer writing **ObsGeometryFactory** can ignore the Level field of the **IDataRequest** as there are not different levels of metar data, it is all at the surface. It is up to the factory writer to determine which methods and fields to support and which to ignore, but the factory writer should always code the factory with the user requesting data in mind. If a user of the framework could reasonably expect certain behavior from the framework based on the request, the factory writer should implement support for that behavior.\n",
"\n",
"Abstract factories will be provided and can be extended to reduce the amount of code a factory developer has to write to complete some common actions that will be used by multiple factories. The factory should be capable of working within either CAVE or EDEX, therefore all of its server specific actions (e.g. database queries) should go through the Request/Handler API by using **IServerRequests**. CAVE can then send the **IServerRequests** to EDEX with **ThriftClient** while EDEX can use the **ServerRequestRouter** to process the **IServerRequests**, making the code compatible regardless of which JVM it is running inside.\n",
"\n",
"Once the factory code is written, it must be registered with the framework as an available factory. This will be done through spring xml in a common plugin, with the xml file inside the res/spring folder of the plugin. Registering the factory will identify the datatype name that must match what users would use as the datatype on the **IDataRequest**, e.g. the word \"satellite\". Registering the factory also indicates to the framework what request types are supported, i.e. grid vs geometry or both.\n",
"\n",
"An example of the spring xml for a satellite factory is provided below:\n",
"\n",
" <bean id=\"satelliteFactory\" \n",
" class=\"com.raytheon.uf.common.dataplugin.satellite.SatelliteFactory\" />\n",
"\n",
" <bean id=\"satelliteFactoryRegistered\" factory-bean=\"dataFactoryRegistry\" factory-method=\"register\">\n",
" <constructor-arg value=\"satellite\" />\n",
" <constructor-arg value=\"com.raytheon.uf.common.dataaccess.grid.IGridRequest\" />\n",
" <constructor-arg value=\"satelliteFactory\" />\n",
" </bean>\n",
"\n",
"## How the framework works when it receives a request\n",
"\n",
"**IDataRequest** requires a datatype to be set on every request. The framework will have a registry of existing factories for each data type (grid and geometry). When the Data Access Layer methods are called, it will first lookup in the registry for the factory that corresponds to the datatype on the **IDataRequest**. If no corresponding factory is found, it will throw an exception with a useful error message that indicates there is no current support for that datatype request. If a factory is found, it will delegate the processing of the request to the factory. The factory will receive the request and process it, returning the result back to the Data Access Layer which then returns it to the caller.\n",
"\n",
"By going through the Data Access Layer, the user is able to retrieve the data and use it without understanding which factory was used, how the factory retrieved the data, or what implementation of data was returned. This effectively frees the framework and users of the framework from any dependencies on any particular data types. Since these dependencies are avoided, the specific **IDataFactory** and **IData** implementations can be altered in the future if necessary and the code making use of the framework will not need to be changed as long as the interfaces continue to be met.\n",
"\n",
"Essentially, the Data Access Framework is a service that provides data in a consistent way, with the service capabilities being expanded by plugin developers who write support for more data types. Note that the framework itself is useless without plugins contributing and registering **IDataFactories**. Once the framework is coded, developers will need to be tasked to add the factories necessary to support the needed data types.\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Request interfaces\n",
"\n",
"Requests and returned data interfaces will exist in both Java and Python. The Java interfaces are listed below and the Python interfaces will match the Java interfaces except where noted. Factories will only be written in Java.\n",
"\n",
"**IDataRequest**\n",
"\n",
"* **void setDatatype(String datatype) **- the datatype name and also the key to which factory will be used. Frequently pluginName such as radar, satellite, gfe, ffmp, etc\n",
"\n",
"* **void addIdentifier(String key, Object value)** - an identifier the factory can use to determine which data to return, e.g. for grib data key \"modelName\" and value “GFS40”\n",
"\n",
"* **void setParameters(String... params)**\n",
"\n",
"* **void setLevels(Level... levels)**\n",
"\n",
"* **String getDatatype()**\n",
"\n",
"* **Map<String, Object> getIdentifiers()**\n",
"\n",
"* **String[] getParameters()**\n",
"\n",
"* **Level[] getLevels()**\n",
"\n",
"* Python Differences\n",
"\n",
"* **Levels** will be represented as **Strings**\n",
"\n",
"**IGridRequest extends IDataRequest**\n",
"\n",
"* **void setStorageRequest(Request request)** - a datastorage request that allows for slab, line, and point requests for faster performance and less data retrieval\n",
"\n",
"* **Request getStorageRequest()**\n",
"\n",
"* Python Differences\n",
"\n",
"* No support for storage requests\n",
"\n",
"**IGeometryRequest extends IDataRequest**\n",
"\n",
"* **void setEnvelope(Envelope env)** - a bounding box envelope to limit the data that is searched through and returned. Not all factories may support this.\n",
"\n",
"* **setLocationNames(String... locationNames) **- a convenience of requesting data by names such as ICAOs, airports, stationIDs, etc\n",
"\n",
"* **Envelope getEnvelope()**\n",
"\n",
"* **String[] getLocationNames()**\n",
"\n",
"* Python Differences\n",
"\n",
"* Envelope methods will use a **shapely.geometry.Polygon** instead of **Envelopes** (shapely has no concept of envelopes and considers them as rectangular polygons)\n",
"\n",
"### **Data Interfaces**\n",
"\n",
"**IData**\n",
"\n",
"* **Object getAttribute(String key)** - **getAttribute** provides a way to get at attributes of the data that the interface does not provide, allowing the user to get more info about the data without adding dependencies on the specific data type plugin\n",
"\n",
"* **DataTime getDataTime()** - some data may return null (e.g. maps)\n",
"\n",
"* **Level getLevel()** - some data may return null\n",
"\n",
"* Python Differences\n",
"\n",
"* **Levels** will be represented by **Strings**\n",
"\n",
"**IGridData extends IData**\n",
"\n",
"* **String getParameter()**\n",
"\n",
"* **GridGeometry2D getGridGeometry()**\n",
"\n",
"* **Unit getUnit()** - some data may return null\n",
"\n",
"* **DataDestination populateData(DataDestination destination)** - How the user gets the raw data by passing in a **DataDestination** such as **FloatArrayWrapper** or **ByteBufferWrapper**. This allows the user to specify the way the raw data of the grid should be structured in memory.\n",
"\n",
"* **DataDestination populateData(DataDestination destination, Unit unit)** - Same as the above method but also attempts to convert the raw data to the specified unit when populating the **DataDestination**.\n",
"\n",
"* Python Differences\n",
"\n",
"* **Units** will be represented by **Strings**\n",
"\n",
"* **populateData() **methods will not exist, instead there will be a **getRawData()** method that returns a numpy array in the native type of the data\n",
"\n",
"**IGeometryData extends IData**\n",
"\n",
"* **Geometry getGeometry()**\n",
"\n",
"* **Set<String> getParameters()** - Gets the list of parameters included in this data\n",
"\n",
"* **String getString(String param)** - Gets the value of the parameter as a String\n",
"\n",
"* **Number getNumber(String param)** - Gets the value of the parameter as a Number\n",
"\n",
"* **Unit getUnit(String param) **- Gets the unit of the parameter, may be null\n",
"\n",
"* **Type getType(String param)** - Returns an enum of the raw type of the parameter, such as Float, Int, or String\n",
"\n",
"* **String getLocationName()** - Returns the location name of the piece of data, typically to correlate if the request was made with locationNames. May be null.\n",
"\n",
"* Python Differences\n",
"\n",
"* **Geometry** will be **shapely.geometry.Geometry**\n",
"\n",
"* **getNumber()** will return the python native number of the data\n",
"\n",
"* **Units** will be represented by **Strings**\n",
"\n",
"* **getType()** will return the python type object\n",
"\n",
"**DataAccessLayer** (in implementation, these methods delegate processing to factories)\n",
"\n",
"* **DataTime[] getAvailableTimes(IDataRequest request)**\n",
"\n",
"* **DataTime[] getAvailableTimes(IDataRequest request, BinOffset binOffset)**\n",
"\n",
"* **IData[] getData(IDataRequest request, DataTime... times)**\n",
"\n",
"* **IData[] getData(IDataRequest request, TimeRange timeRange)**\n",
"\n",
"* **GridGeometry2D getGridGeometry(IGridRequest request)**\n",
"\n",
"* **String[] getAvailableLocationNames(IGeometryRequest request)**\n",
"\n",
"* Python Differences\n",
"\n",
"* No support for **BinOffset**\n",
"\n",
"* **getGridGeometry(IGridRequest)** will be replaced by **getLatCoords(IGridRequest) **and **getLonCoords(IGridRequest) **that will return numpy arrays of the lat or lon of every grid cell\n",
"\n",
"### Factory Interfaces (Java only)\n",
"\n",
"* **IDataFactory<R extends IDataRequest, D extends IData>**\n",
"\n",
"* **DataTime[] getAvailableTimes(R request) **- queries the database and returns the times that match the request. Some factories may not support this (e.g. maps).\n",
"\n",
"* **DataTime[] getAvailableTimes(R request, BinOffset binOffset)** - queries the database with a bin offset and returns the times that match the request. Some factories may not support this.\n",
"\n",
"* **D[] getData(R request, DataTime... times)** - Gets the data that matches the request at the specified times.\n",
"\n",
"* **D[] getData(R request, TimeRange timeRange)** - Gets the data that matches the request and is within the time range.\n",
"\n",
"**IGridDataFactory extends IDataFactory<IGridRequest, IGridData>**\n",
"\n",
"* **GridGeometry2D** **getGeometry(IGridRequest request)** - Returns the grid geometry of the data that matches the request BEFORE making the request. Useful for then making slab or line requests for subsets of the data. Does not support moving grids, but moving grids dont make subset requests either.\n",
"\n",
"**IGeometryDataFactory extends IDataFactory<IGeometryRequest, IGeometryData>**\n",
"\n",
"* **getAvailableLocationNames(IGeometryRequest request)** - Convenience method to retrieve available location names that match a request. Not all factories may support this."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.9"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,14 +1,5 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"# NEXRAD Level 3 Plot with Matplotlib"
]
},
{
"cell_type": "code",
"execution_count": 5,

View file

@ -1,14 +1,5 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"# Plotting a Sounding with MetPy"
]
},
{
"cell_type": "code",
"execution_count": 17,

View file

@ -1,309 +0,0 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from awips.dataaccess import DataAccessLayer\n",
"\n",
"# Set host\n",
"DataAccessLayer.changeEDEXHost(\"edex-cloud.unidata.ucar.edu\")\n",
"# Init data request\n",
"request = DataAccessLayer.newDataRequest()\n",
"request.setDatatype(\"obs\")\n",
"request.setLocationNames(\"KBJC\")\n",
"datatimes = DataAccessLayer.getAvailableTimes(request)\n",
"time = datatimes[-1].validPeriod\n",
"\n",
"# \"presWeather\",\"skyCover\",\"skyLayerBase\"\n",
"# are multi-dimensional... deal with these later\n",
"request.setParameters(\n",
" \"stationName\",\n",
" \"timeObs\",\n",
" \"wmoId\",\n",
" \"autoStationType\",\n",
" \"elevation\",\n",
" \"reportType\",\n",
" \"temperature\",\n",
" \"tempFromTenths\",\n",
" \"dewpoint\",\n",
" \"dpFromTenths\",\n",
" \"windDir\",\n",
" \"windSpeed\",\n",
" \"windGust\",\n",
" \"visibility\",\n",
" \"altimeter\",\n",
" \"seaLevelPress\",\n",
" \"pressChange3Hour\",\n",
" \"pressChangeChar\",\n",
" \"maxTemp24Hour\",\n",
" \"minTemp24Hour\",\n",
" \"precip1Hour\",\n",
" \"precip3Hour\",\n",
" \"precip6Hour\",\n",
" \"precip24Hour\"\n",
")\n",
"\n",
"response = DataAccessLayer.getGeometryData(request,times=time)\n",
"for ob in response:\n",
" print \"getParameters is\",ob.getParameters()\n",
" print len(ob.getParameters())\n",
" #getParameters\n",
" print ob.getString(\"stationName\"), \"from\", ob.getDataTime().getRefTime()\n",
" print \"stationName is\",ob.getString(\"stationName\")\n",
" print \"timeObs is\",ob.getString(\"timeObs\")\n",
" print \"wmoId is\",ob.getString(\"wmoId\")\n",
" print \"autoStationType is\",ob.getString(\"autoStationType\")\n",
" print \"elevation is\",ob.getString(\"elevation\")\n",
" print \"reportType is\",ob.getString(\"reportType\")\n",
" print \"temperature is\",ob.getString(\"temperature\")\n",
" print \"tempFromTenths is\",ob.getString(\"tempFromTenths\")\n",
" print \"dewpoint is\",ob.getString(\"dewpoint\")\n",
" print \"dpFromTenths is\",ob.getString(\"dpFromTenths\")\n",
" print \"windDir is\",ob.getString(\"windDir\")\n",
" print \"windSpeed is\",ob.getString(\"windSpeed\")\n",
" print \"windGust is\",ob.getString(\"windGust\")\n",
" print \"visibility is\",ob.getString(\"visibility\")\n",
" print \"altimeter is\",ob.getString(\"altimeter\")\n",
" print \"seaLevelPress is\",ob.getString(\"seaLevelPress\")\n",
" print \"pressChange3Hour is\",ob.getString(\"pressChange3Hour\")\n",
" print \"pressChangeChar is\",ob.getString(\"pressChangeChar\")\n",
" print \"maxTemp24Hour is\",ob.getString(\"maxTemp24Hour\")\n",
" print \"minTemp24Hour is\",ob.getString(\"minTemp24Hour\")\n",
" print \"precip1Hour is\",ob.getString(\"precip1Hour\")\n",
" print \"precip3Hour is\",ob.getString(\"precip3Hour\")\n",
" print \"precip6Hour is\",ob.getString(\"precip6Hour\")\n",
" print \"precip24Hour is\",ob.getString(\"precip24Hour\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# multi-dimensional present WX\n",
"request = DataAccessLayer.newDataRequest()\n",
"request.setDatatype(\"obs\")\n",
"request.setLocationNames(\"KBJC\")\n",
"request.setParameters(\"presWeather\")\n",
"response = DataAccessLayer.getGeometryData(request,times=time)\n",
"for ob in response:\n",
" print \"getParameters is\",ob.getParameters()\n",
" print ob.getString(\"presWeather\")\n",
"\n",
"\n",
"# multi-dimensional Sky Condition\n",
"request.setParameters(\"skyCover\", \"skyLayerBase\")\n",
"response = DataAccessLayer.getGeometryData(request,times=time)\n",
"for ob in response:\n",
" print ob.getString(\"skyCover\")\n",
" print ob.getString(\"skyLayerBase\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Synop/Marine"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from awips.dataaccess import DataAccessLayer\n",
"\n",
"request = DataAccessLayer.newDataRequest()\n",
"request.setDatatype(\"sfcobs\")\n",
"request.setLocationNames(\"72421\") # Covington, Kentucky (KCVG)\n",
"\n",
"request.setParameters(\"stationId\",\"timeObs\",\"elevation\",\"reportType\",\n",
" \"wx_present\",\"visibility\",\"seaLevelPress\",\"stationPress\",\n",
" \"pressChange3Hour\",\"pressChangeChar\",\"temperature\",\n",
" \"dewpoint\",\"seaSurfaceTemp\",\"wetBulb\",\"windDir\",\n",
" \"windSpeed\",\"equivWindSpeed10m\",\"windGust\",\"precip1Hour\",\n",
" \"precip6Hour\",\"precip24Hour\" )\n",
"\n",
"datatimes = DataAccessLayer.getAvailableTimes(request)\n",
"time = datatimes[-1].validPeriod\n",
"\n",
"response = DataAccessLayer.getGeometryData(request,times=time)\n",
"print response\n",
"for ob in response:\n",
" print \"getParameters is\",ob.getParameters()\n",
" print len(ob.getParameters())\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Profiler"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"MULTI_DIM_PARAMS = set(['vComponent', 'uComponent', 'peakPower', \n",
" 'levelMode', 'uvQualityCode', 'consensusNum', \n",
" 'HorizSpStdDev', 'wComponent', 'height', \n",
" 'VertSpStdDev'])\n",
"\n",
"request = DataAccessLayer.newDataRequest(\"profiler\")\n",
"request.setParameters('numProfLvls', 'elevation', 'windDirSfc', 'validTime', \n",
" 'windSpeedSfc', 'pressure', 'submode', 'relHumidity', \n",
" 'profilerId', 'rainRate', 'temperature')\n",
"request.getParameters().extend(MULTI_DIM_PARAMS)\n",
"\n",
"datatimes = DataAccessLayer.getAvailableTimes(request)\n",
"time = datatimes[-1].validPeriod\n",
"\n",
"response = DataAccessLayer.getGeometryData(request,times=time)\n",
"print response\n",
"for ob in response:\n",
" print \"getParameters is\",ob.getParameters()\n",
" print len(ob.getParameters())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## ACARS"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"request = DataAccessLayer.newDataRequest(\"acars\")\n",
"request.setParameters(\"tailNumber\", \"receiver\", \"pressure\", \"flightPhase\", \n",
" \"rollAngleQuality\", \"temp\", \"windDirection\", \"windSpeed\",\n",
" \"humidity\", \"mixingRatio\", \"icing\")\n",
"datatimes = DataAccessLayer.getAvailableTimes(request)\n",
"time = datatimes[-1].validPeriod\n",
"\n",
"response = DataAccessLayer.getGeometryData(request,times=time)\n",
"print response\n",
"for ob in response:\n",
" print \"getParameters is\",ob.getParameters()\n",
" print len(ob.getParameters())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## AIREP"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"request = DataAccessLayer.newDataRequest(\"airep\")\n",
"request.setParameters(\"id\", \"flightLevel\", \"temp\", \"windDirection\", \"windSpeed\",\n",
" \"flightWeather\", \"flightHazard\", \"flightConditions\")\n",
"\n",
"datatimes = DataAccessLayer.getAvailableTimes(request)\n",
"time = datatimes[-1].validPeriod\n",
"\n",
"response = DataAccessLayer.getGeometryData(request,times=time)\n",
"print response\n",
"for ob in response:\n",
" print \"getParameters is\",ob.getParameters()\n",
" print len(ob.getParameters())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## PIREP"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"MULTI_DIM_PARAMS = set([\"hazardType\", \n",
" \"turbType\", \"turbBaseHeight\", \"turbTopHeight\",\n",
" \"iceType\", \"iceBaseHeight\", \"iceTopHeight\",\n",
" \"skyCover1\", \"skyCover2\", \"skyBaseHeight\", \"skyTopHeight\"\n",
" ])\n",
" \n",
"request = DataAccessLayer.newDataRequest(\"pirep\")\n",
"request.setParameters('id', 'flightLevel', 'temp', 'windDirection', 'windSpeed',\n",
" 'horzVisibility', 'aircraftType', 'weatherGroup')\n",
"request.getParameters().extend(MULTI_DIM_PARAMS)\n",
"\n",
"datatimes = DataAccessLayer.getAvailableTimes(request)\n",
"time = datatimes[-1].validPeriod\n",
"\n",
"response = DataAccessLayer.getGeometryData(request,times=time)\n",
"print response\n",
"for ob in response:\n",
" print \"getParameters is\",ob.getParameters()\n",
" print len(ob.getParameters())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.9"
}
},
"nbformat": 4,
"nbformat_minor": 0
}