This page demonstrates Python tips and tricks that I use in my everyday programming as an atmospheric science graduate student.
-Brian Blaylock

Showing posts with label WRF. Show all posts
Showing posts with label WRF. Show all posts

Tuesday, June 14, 2016

WRF Browser for Windows

Again, not a python post, but some good news for WRF modelers who use Windows PCs.


Introducing WRF Browser, a Windows application you can load and view WRF output and netcdf variables on a map or export to CSV. http://www.enviroware.com/WRF_Browser/
A few tips unique to my needs:
1) I like to look at terrain and land use fields. This is especially nice when you can do this on Google Earth. You'll need to create your own colormap, or as they call it "ColorRamp". Follow the directions in the online manual for creating a custom colormap. I've made one called MODIS_21_Landuse.pg and put it in the directory C:\ProgramData\Enviroware\WRF_Browser\ColorRamps\ 

This matches my Python ColorMap for MODIS land use

1         0 102   0 255

2         0 102  51 255
3        51 204  51 255
4        51 204 102 255
5        51 153  51 255
6        76 178   0 255
7       209 104  31 255
8       188 181 105 255
9       255 214   0 255
10        0 255   0 255
11        0 255 255 255
12      255 255   0 255
13      255   0   0 255
14      178 230  77 255
15      255 255 255 255
16      233 233 179 255
17      127 178 255 255
18      219  20  59 255
19      247 127  80 255
20      232 150 122 255
21        0   0 224 255



The KML output looks like this...
This is the same land use scheme used in the HRRR model, except that the Size of the Great Salt Lake has been modified to it's present day lake level.
One thing I notice is that urban sprawl in the southern end of Utah County in Spanish Fork (my hometown), Salem, and Payson is not captured in the MODIS land use categories. This may have some small effects on how well the HRRR produces forecasts in these cities (as far as I can tell, land use and surface characteristics for a city is a minor issue with the HRRR compared to it's other problems).

Monday, May 23, 2016

Edit netCDF files with Photoshop

http://home.chpc.utah.edu/~u0553130/Brian_Blaylock/lake_surgery.html#PHOTO

I always thought it would be nice if I could load a netCDF file into photoshop and make changes to fields with the paint brush and pencil tool.
Well, now you can, with this three step process using Python (this only works with landuse or categorical data sets so far).
This is a work in progress and will get more attention after I defend my thesis, but it's a really handy concept.
  1. Convert a netCDF array into a bitmap image netcdf_to_bitmap.py.
  2. Open image in PhotoShop and use the pencil tool to change colors (i.e. land use categories). Save image as bitmap.
  3. Open the modified land use image in Python bitmap_to_netcdf.py. and extract the colors as categories. Save array into the WRF netCDF file

Below you can see that I added more lake and urban area using the pencil tool to the WRF landuse array.

Friday, April 8, 2016

Python: WRF convert data on a staggered grid to mass point.

WRF output data has variables on a staggered grid (edges of grid boxes) and variables at a mass point (center of grid box). Sometimes it's necessary to convert the variables on a staggered grid to the mass points so you can plot U and V winds on the same latitude. Here are simple functions to convert the U and V variables on a staggered grid to the mass point grid.

https://github.com/blaylockbk/Ute_WRF/blob/master/functions/stagger_to_mass.py

Below is an explanation of how the function works...








Thursday, August 13, 2015

Quick WRF Plot

Plotting WRF Data in python without NetCDF4:

Scrapped this code from places on line. Reads in netcdf data with scipy. Plots specific humidity with the lake mask outlined on top. See blog post here for details on the plot.



# Brian Blaylock
#
# Plotting WRF netCDF output
# Parts and Pieces of this code is from Luke Madaus (University of Washington)


import sys,getopt
#from netCDF4 import Dataset # use scipy instead
from scipy.io import netcdf
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import os
from datetime import datetime, timedelta
import coltbls as coltbls
from mpl_toolkits.basemap import Basemap
from matplotlib.colors import LinearSegmentedColormap
from mpl_toolkits.axes_grid import make_axes_locatable
import matplotlib.axes as maxes


# Running Script example:
# $ python my_WRF_map.py wrfout_d0x_YYYY-MM-DD_HH:MM:SS

# Open file in a netCDF reader
directory = ''
wrf_file_name = 'M11KS3~E.NC' #NC files are named differently in a windows system
nc = netcdf.netcdf_file(wrf_file_name,'r')

# Grab these variables for now
landmask = nc.variables['LANDMASK'] # HRRR metgrid landmask




#-------------------------------------------
# BEGIN ACTUAL PROCESSING HERE
#-------------------------------------------

# x_dim and y_dim are the x and y dimensions of the model
# domain in gridpoints
x_dim = nc.dimensions['west_east']
y_dim = nc.dimensions['south_north']

# Get the grid spacing
dx = float(nc.DX)
dy = float(nc.DY)

width_meters = dx * (x_dim - 1) #Domain Width
height_meters = dy * (y_dim - 1) #Domain Height

cen_lat = float(nc.CEN_LAT)
cen_lon = float(nc.CEN_LON)
truelat1 = float(nc.TRUELAT1)
truelat2 = float(nc.TRUELAT2)
standlon = float(nc.STAND_LON)

# Draw the base map behind it with the lats and
# lons calculated earlier
m = Basemap(resolution='i',projection='lcc',\
width=width_meters,height=height_meters,\
lat_0=cen_lat,lon_0=cen_lon,lat_1=truelat1,\
lat_2=truelat2)

# This sets the standard grid point structure at full resolution
# Converts WRF lat and long to the maps x an y coordinate
x,y = m(nc.variables['XLONG_M'][0],nc.variables['XLAT_M'][0])


# This sets a thinn-ed out grid point structure for plotting
# wind barbs at the interval specified in "thin"
thin = 5
x_th,y_th = m(nc.variables['XLONG_M'][0,::thin,::thin],\
nc.variables['XLAT_M'][0,::thin,::thin])

# Set universal figure margins
width = 10
height = 8

plt.figure(figsize=(width,height))
plt.rc("figure.subplot", left = .001) #gets rid of white space in plot
plt.rc("figure.subplot", right = .999)
plt.rc("figure.subplot", bottom = .001)
plt.rc("figure.subplot", top = .999)

F = plt.gcf() # Gets the current figure

m.drawstates(color='k', linewidth=1.25)
m.drawcoastlines(color='k')
m.drawcountries(color='k', linewidth=1.25)

height = nc.variables['HGT_M'][0,:,:]
landmask = nc.variables['LANDMASK'][0,:,:]
spechumd = nc.variables['SPECHUMD'][0][0,:,:]

plt.figure(1)
plt.title("HRRR Land Mask and Specific Humidity\nAugust 10, 2015 23:00z")
plt.pcolormesh(x,y,landmask)
plt.pcolormesh(x,y,spechumd*1000, cmap = plt.cm.cool)
cbar_loc = plt.colorbar()
cbar_loc.ax.set_ylabel('Specific Humidity g/kg')
plt.contour(x,y,landmask, [0,1], linewidths=1, colors="k")
#plt.contour(x,y,height)

xs,ys = m(-111.97,40.78) #buffr sounding coordinates
plt.scatter(xs,ys, s=70, c='w')







plt.show()