Example #1
0
def test_coriolis_force():
    """Test basic coriolis force calculation."""
    lat = np.array([-90., -30., 0., 30., 90.]) * units.degrees
    cor = coriolis_parameter(lat)
    values = np.array([-1.4584232E-4, -.72921159E-4, 0, .72921159E-4,
                       1.4584232E-4]) * units('s^-1')
    assert_almost_equal(cor, values, 7)
Example #2
0
def calcgw_gfs(v, lat, lon):
    height, lats, lons = v.data(lat1=lat - gw_gfs_margin_deg,
                                lat2=lat + gw_gfs_margin_deg,
                                lon1=lon - gw_gfs_margin_deg,
                                lon2=lon + gw_gfs_margin_deg)
    i = np.searchsorted(lats[:, 0], lat)
    if abs(lats[i + 1, 0] - lat) < abs(lats[i, 0] - lat):
        i = i + 1
    j = np.searchsorted(lons[0, :], lon)
    if abs(lons[0, i + 1] - lon) < abs(lons[0, i] - lon):
        j = j + 1
    #print('level', v.level, 'height', height[i,j], lats[i,j], lons[i,j])

    # Set up some constants based on our projection, including the Coriolis parameter and
    # grid spacing, converting lon/lat spacing to Cartesian
    f = mpcalc.coriolis_parameter(np.deg2rad(lats)).to('1/s')
    dx, dy = mpcalc.lat_lon_grid_deltas(lons, lats)
    res_km = (dx[i, j] + dy[i, j]).magnitude / 2000.

    # Smooth height data. Sigma=1.5 for gfs 0.5deg
    height = ndimage.gaussian_filter(height, sigma=1.5 * 50 / res_km, order=0)

    # In MetPy 0.5, geostrophic_wind() assumes the order of the dimensions is (X, Y),
    # so we need to transpose from the input data, which are ordered lat (y), lon (x).
    # Once we get the components,transpose again so they match our original data.
    geo_wind_u, geo_wind_v = mpcalc.geostrophic_wind(height * units.m, f, dx,
                                                     dy)

    return height[i, j], geo_wind_u[i, j], geo_wind_v[i, j]
Example #3
0
def test_coriolis_force():
    """Test basic coriolis force calculation."""
    lat = np.array([-90., -30., 0., 30., 90.]) * units.degrees
    cor = coriolis_parameter(lat)
    values = np.array([-1.4584232E-4, -.72921159E-4, 0, .72921159E-4,
                       1.4584232E-4]) * units('s^-1')
    assert_almost_equal(cor, values, 7)
Example #4
0
def calcgw_wrf(f, lat, lon, levels, tidx=0):
    # MFDataset removes the time dimension from XLAT, XLONG
    xlat = f.variables['XLAT']
    xlslice = (0, ) * (len(xlat.shape) - 2) + (slice(None), slice(None))
    xlat = xlat[xlslice]
    xlong = f.variables['XLONG'][xlslice]

    (iy, ix), area, (iby, ibx) = get_wrf_dims(f, lat, lon, xlat, xlong)
    areat = (tidx, ) + area
    areatz = (tidx, slice(None)) + area
    #print('wrf coords', lat, lon, xlat[iy,ix], xlong[iy,ix])
    #print(xlat[area][iby,ibx], xlong[area][iby,ibx], areat)

    # load area
    hgt = (f.variables['PH'][areatz] + f.variables['PHB'][areatz]) / 9.81
    hgtu = (hgt[:-1] + hgt[1:]) * .5
    pres = f.variables['P'][areatz] + f.variables['PB'][areatz]
    terrain = f.variables['HGT'][areat]

    # find suitable pressure levels
    yminpres, xminpres = np.unravel_index(pres[0].argmin(), pres[0].shape)
    pres1 = pres[0, yminpres, xminpres] - 1.

    aglpt = hgtu[:, iby, ibx] - terrain[iby, ibx]
    pres0 = pres[np.searchsorted(aglpt, levels[-1]), iby, ibx]
    # plevels = np.arange(pres1, min(pres0, pres1)-1, -1000.)
    plevels = np.arange(pres1, min(pres0, pres1) - 1000, -1000.)  # !!!!

    # interpolate wrf into pressure levels
    phgt = log_interpolate_1d(plevels, pres, hgtu, axis=0)

    # Set up some constants based on our projection, including the Coriolis parameter and
    # grid spacing, converting lon/lat spacing to Cartesian
    coriol = mpcalc.coriolis_parameter(np.deg2rad(xlat[area])).to('1/s')

    # lat_lon_grid_deltas doesn't work under py2, but for WRF grid it is still
    # not very accurate, better use direct values.
    #dx, dy = mpcalc.lat_lon_grid_deltas(xlong[area], xlat[area])
    dx = f.DX * units.m
    dy = f.DY * units.m

    # Smooth height data. Sigma=1.5 for gfs 0.5deg
    res_km = f.DX / 1000.

    ug = np.zeros(plevels.shape, 'f8')
    vg = np.zeros(plevels.shape, 'f8')
    for i in range(len(plevels)):
        sh = ndimage.gaussian_filter(phgt[i, :, :],
                                     sigma=1.5 * 50 / res_km,
                                     order=0)
        #        ugl, vgl = mpcalc.geostrophic_wind(sh * units.m, coriol, dx, dy) # bug1
        ugl, vgl = mpcalc.geostrophic_wind(sh * units.m, dx, dy,
                                           np.deg2rad(xlat[area]))
        ug[i] = ugl[iby, ibx].magnitude
        vg[i] = vgl[iby, ibx].magnitude

    return phgt[:, iby, ibx], ug, vg
Example #5
0
def test_coriolis_force(array_type):
    """Test basic coriolis force calculation."""
    mask = [False, True, False, True, False]
    lat = array_type([-90., -30., 0., 30., 90.], 'degrees', mask=mask)
    cor = coriolis_parameter(lat)
    values = array_type(
        [-1.4584232E-4, -.72921159E-4, 0, .72921159E-4, 1.4584232E-4],
        's^-1',
        mask=mask)
    assert_array_almost_equal(cor, values, 7)
    def getParameters(self):
        self.lambda_z = (self.alt[-1] - self.alt[0]) * 2
        self.m = 2 * np.pi / self.lambda_z
        #phi = eps[4]    #orientation of ellipse
        print("PHIIII", self.phi)
        rot = np.array([[np.cos(self.phi), -np.sin(self.phi)],
                        [np.sin(self.phi), np.cos(self.phi)]])
        #print("ROTATION:", rot)
        #print("SIZE OF ROT:", rot.shape)
        uv = np.array([self.u, self.v])
        uvrot = np.matmul(rot, uv)
        urot = uvrot[0, :]
        dT = np.diff(self.temp)
        #print("Diferential Temperature:", dT)
        dz = np.diff(self.alt)
        wf = (2 * self.a) / (2 * self.b)  #long axis / short axis
        print("WFFFFFFFFFFFF", wf)
        bvMean = np.mean(self.bv2)
        coriolisFreq = mpcalc.coriolis_parameter(latitudeOfAnalysis)
        #print("Coriolis Parameter:", coriolisFreq)
        intrinsicFreq = coriolisFreq.magnitude * wf  #need to assign units to output from ellipse fitting to ensure dimensional accuracy
        k_h = np.sqrt((coriolisFreq.magnitude**2 * self.m**2) / abs(bvMean) *
                      (wf**2 - 1))  #horizontal wavenumber
        print("KHHHHHHHHHHHHHHHHHHHHHHHHH", k_h)
        intrinsicHorizPhaseSpeed = intrinsicFreq / k_h
        k_h_2 = np.sqrt((intrinsicFreq**2 - coriolisFreq.magnitude**2) *
                        (self.m**2 / abs(bvMean)))
        int2 = intrinsicFreq / k_h_2
        dTdz = dT / dz
        eta = np.mean(dTdz / urot[0:-1])

        if eta < 0:
            self.phi -= np.pi

        self.altOfDetection = np.mean(self.alt)

        #print("m: {}, lz: {}, h: {}, bv{}".format(self.m, self.lambda_z, intrinsicHorizPhaseSpeed, bvMean))
        #return altitude of detection, latitude, longitude, vertical wavelength,horizontal wavenumber, intrinsic horizontal phase speed, axial ratio l/s
        return [
            self.altOfDetection, self.lat[0], self.long[0], self.lambda_z, k_h,
            intrinsicHorizPhaseSpeed, wf
        ]
Example #7
0
def 500hPa_GFS_vorticity(lon_west, lon_east, lat_south, lat_north):
       LATEST_DATA.variables('Geopotential_height_isobaric', 'u-component_of_wind_isobaric', 'v-component_of_wind_isobaric').add_lonlat()
       LATEST_DATA.lonlat_box(lon_west, lon_east, lat_south, lat_north)
       LATEST_DATA.vertical_level(50000)
       DATA = NCSS_DATA.get_data(LATEST_DATA)
       DTIME = DATA.variables['Geopotential_height_isobaric'].dimensions[0]
       DLAT = DATA.variables['Geopotential_height_isobaric'].dimensions[2]
       DLON = DATA.variables['Geopotential_height_isobaric'].dimensions[3]
       LAT = DATA.variables[DLAT][:]
       LON = DATA.variables[DLON][:]
       TIMES = DATA.variables[DTIME]
       VTIMES = num2date(TIMES[:], TIMES.units)
       H500 = DATA.variables['Geopotential_height_isobaric'][0, 0, :, :]
       U500 = DATA.variables['u-component_of_wind_isobaric'][0, 0, :, :]*units('m/s')
       V500 = DATA.variables['v-component_of_wind_isobaric'][0, 0, :, :]*units('m/s')
       DTIME = DATA.variables['Geopotential_height_isobaric'].dimensions[:]
       f = mpcalc.coriolis_parameter(np.deg2rad(LAT)).to(units('1/sec'))
       DX, DY = mpcalc.lat_lon_grid_spacing(LON, LAT)
       VORT500 = mpcalc.vorticity(U500, V500, DX, DY, dim_order='YX')
       VORT500 = (VORT500*(units('1/s'))) 
Example #8
0
def geostr_met(array_2d_geoheight, array_1d_lat, array_1d_lon) :
    
    '''

    Calculate Geostrophic wind map (2d) from 2d array area.
    https://unidata.github.io/python-gallery/examples/Ageostrophic_Wind_Example.html
    
    Parameters
    ----------
    array_2d_geoheight : read numpy array [m]
    array_1d_lat : read numpy array [deg]
    array_1d_lon : read numpy array [deg]

    Returns
    -------
    array_2d : return interplated and extrapolated 2d array

    '''
    
    
    import numpy as np
    import metpy.calc as mpcalc
    from metpy.units import units
    
    
    # Combine 1D latitude and longitudes into a 2D grid of locations
    lon_2d, lat_2d = np.meshgrid(array_1d_lon, array_1d_lat)
    
    # Set up some constants based on our projection, including the Coriolis parameter and
    # grid spacing, converting lon/lat spacing to Cartesian
    f = mpcalc.coriolis_parameter(np.deg2rad(lat_2d)).to('1/s')
    dx, dy = mpcalc.lat_lon_grid_deltas(lon_2d + 360, lat_2d)
    dx, dy = np.array(dx), np.array(dy)
    dy *= -1
    
    # In MetPy 0.5, geostrophic_wind() assumes the order of the dimensions is (X, Y),
    # so we need to transpose from the input data, which are ordered lat (y), lon (x).
    # Once we get the components,transpose again so they match our original data.
    geo_wind_u, geo_wind_v = mpcalc.geostrophic_wind(array_2d_geoheight.data * units.m, f, dx, dy)
    
    return(geo_wind_u, geo_wind_v)
Example #9
0
def test_coriolis_warning():
    """Test that warning is raise when latitude larger than pi radians."""
    with pytest.warns(UserWarning):
        coriolis_parameter(50)
    with pytest.warns(UserWarning):
        coriolis_parameter(-50)
Example #10
0
#
# Nearly all of the calculations in `metpy.calc` will accept DataArrays by converting them
# into their corresponding unit arrays. While this may often work without any issues, we must
# keep in mind that because the calculations are working with unit arrays and not DataArrays:
#
# - The calculations will return unit arrays rather than DataArrays
# - Broadcasting must be taken care of outside of the calculation, as it would only recognize
#   dimensions by order, not name
#
# Also, some of the units used in CF conventions (such as 'degrees_north') are not recognized
# by pint, so we must implement a workaround.
#
# As an example, we calculate geostropic wind at 500 hPa below:

lat, lon = xr.broadcast(y, x)
f = mpcalc.coriolis_parameter(lat.values * units.degrees)
dx, dy = mpcalc.lat_lon_grid_deltas(lon.values, lat.values)
heights = data['height'].loc[time[0]].loc[{vertical.name: 500.}]
u_geo, v_geo = mpcalc.geostrophic_wind(heights, f, dx, dy, dim_order='yx')
print(u_geo)
print(v_geo)

#########################################################################
# Plotting
# --------
#
# Like most meteorological data, we want to be able to plot these data. DataArrays can be used
# like normal numpy arrays in plotting code, or we can use some of xarray's plotting
# functionality.
#
# (More detail beyond the following can be found at `xarray's plotting reference
Example #11
0
# T = lifting_300hPa_trough(parameter='temp')

# Digging Trough
# Z = digging_300hPa_trough(parameter='hght')
# T = digging_300hPa_trough(parameter='temp')

######################################################################
# Set geographic parameters for analytic grid to then
#

lats = np.linspace(35, 50, 101)
lons = np.linspace(260, 290, 101)
lon, lat = np.meshgrid(lons, lats)

# Calculate Geostrophic Wind from Analytic Heights
f = mpcalc.coriolis_parameter(lat * units('degrees'))
dx, dy = mpcalc.lat_lon_grid_deltas(lons, lats)
ugeo, vgeo = mpcalc.geostrophic_wind(Z * units.meter,
                                     f,
                                     dx,
                                     dy,
                                     dim_order='yx')

# Get the wind direction for each point
wdir = mpcalc.wind_direction(ugeo, vgeo)

# Compute the Gradient Wind via an approximation
dydx = mpcalc.first_derivative(Z, delta=dx, axis=1)
d2ydx2 = mpcalc.first_derivative(dydx, delta=dx, axis=1)
R = ((1 + dydx.m**2)**(3. / 2.)) / d2ydx2.m
Example #12
0
ureg = UnitRegistry()
lats_p = lats * ureg.deg
lons_p = lons * ureg.deg

#lats_p.dims = units.deg
#lons_p.dims = units.deg

phi, theta = np.meshgrid(lons, lats) * ureg.deg

#f = 2.*7.2921e-5*np.sin(theta*np.pi/180.)/ureg.second

#dy = dy*units.meters
#dx = dx*units.meters

#print(dx.dim, dy)
f = mpcalc.coriolis_parameter(theta)
#f, lons = cartopy.util.add_cyclic_point(f, coord=lon, axis=1)

dx, dy = mpcalc.lat_lon_grid_deltas(phi, theta)

print(f.shape)
#f = np.repeat(f, 129, axis=1 )
print(dx.shape)

#lat, lon = xr.broadcast(lats_p, lons_p)
heights = geopot * ureg.hPa
heights = xr.DataArray(geopot[0, :, :] * units['hPa'],
                       dims=("lat", "lon"),
                       coords={
                           "lon": lons_p,
                           "lat": lats_p
hght_500 = ds.variables['Geopotential_height_isobaric'][0, lev_500, :, :]
hght_500 = ndimage.gaussian_filter(hght_500, sigma=3, order=0) * units.meter

uwnd_500 = units('m/s') * ds.variables['u-component_of_wind_isobaric'][
    0, lev_500, :, :]
vwnd_500 = units('m/s') * ds.variables['v-component_of_wind_isobaric'][
    0, lev_500, :, :]

#######################################
# Begin Data Calculations
# -----------------------

dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat)

f = mpcalc.coriolis_parameter(np.deg2rad(lat)).to(units('1/sec'))

avor = mpcalc.vorticity(uwnd_500, vwnd_500, dx, dy, dim_order='yx') + f

avor = ndimage.gaussian_filter(avor, sigma=3, order=0) * units('1/s')

vort_adv = mpcalc.advection(avor, [uwnd_500, vwnd_500], (dx, dy),
                            dim_order='yx') * 1e9

#######################################
# Map Creation
# ------------

# Set up Coordinate System for Plot and Transforms
dproj = ds.variables['LambertConformal_Projection']
globe = ccrs.Globe(ellipse='sphere',
Example #14
0
#
# Nearly all of the calculations in `metpy.calc` will accept DataArrays by converting them
# into their corresponding unit arrays. While this may often work without any issues, we must
# keep in mind that because the calculations are working with unit arrays and not DataArrays:
#
# - The calculations will return unit arrays rather than DataArrays
# - Broadcasting must be taken care of outside of the calculation, as it would only recognize
#   dimensions by order, not name
#
# Also, some of the units used in CF conventions (such as 'degrees_north') are not recognized
# by pint, so we must implement a workaround.
#
# As an example, we calculate geostropic wind at 500 hPa below:

lat, lon = xr.broadcast(y, x)
f = mpcalc.coriolis_parameter(lat.values * units.degrees)
dx, dy = mpcalc.lat_lon_grid_deltas(lon.values, lat.values)
heights = data['height'].loc[time[0]].loc[{vertical.name: 500.}]
u_geo, v_geo = mpcalc.geostrophic_wind(heights, f, dx, dy, dim_order='yx')
print(u_geo)
print(v_geo)

#########################################################################
# Plotting
# --------
#
# Like most meteorological data, we want to be able to plot these data. DataArrays can be used
# like normal numpy arrays in plotting code, or we can use some of xarray's plotting
# functionality.
#
# (More detail beyond the following can be found at `xarray's plotting reference
height = height_var[0, 0, :, :].squeeze()
u_wind = u_wind_var[0, 0, :, :].squeeze() * units('m/s')
v_wind = v_wind_var[0, 0, :, :].squeeze() * units('m/s')

# Convert number of hours since the reference time into an actual date
time = num2date(time_var[:].squeeze(), time_var.units)

# Combine 1D latitude and longitudes into a 2D grid of locations
lon_2d, lat_2d = np.meshgrid(lon, lat)

# Smooth height data
height = ndimage.gaussian_filter(height, sigma=1.5, order=0)

# Set up some constants based on our projection, including the Coriolis parameter and
# grid spacing, converting lon/lat spacing to Cartesian
f = mpcalc.coriolis_parameter(np.deg2rad(lat_2d)).to('1/s')
dx, dy = mpcalc.lat_lon_grid_spacing(lon_2d, lat_2d)
dy *= -1

# In MetPy 0.5, geostrophic_wind() assumes the order of the dimensions is (X, Y),
# so we need to transpose from the input data, which are ordered lat (y), lon (x).
# Once we get the components,transpose again so they match our original data.
geo_wind_u, geo_wind_v = mpcalc.geostrophic_wind(height * units.m, f, dx, dy)
geo_wind_u = geo_wind_u
geo_wind_v = geo_wind_v

# Calculate ageostrophic wind components
ageo_wind_u = u_wind - geo_wind_u
ageo_wind_v = v_wind - geo_wind_v

# Create new figure
Example #16
0
#########################################################################
# Calculations
# ------------
#
# Most of the calculations in `metpy.calc` will accept DataArrays by converting them
# into their corresponding unit arrays. While this may often work without any issues, we must
# keep in mind that because the calculations are working with unit arrays and not DataArrays:
#
# - The calculations will return unit arrays rather than DataArrays
# - Broadcasting must be taken care of outside of the calculation, as it would only recognize
#   dimensions by order, not name
#
# As an example, we calculate geostropic wind at 500 hPa below:

lat, lon = xr.broadcast(y, x)
f = mpcalc.coriolis_parameter(lat)
dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat, initstring=data_crs.proj4_init)
heights = data['height'].loc[time[0]].loc[{vertical.name: 500.}]
u_geo, v_geo = mpcalc.geostrophic_wind(heights, f, dx, dy)
print(u_geo)
print(v_geo)

#########################################################################
# Also, a limited number of calculations directly support xarray DataArrays or Datasets (they
# can accept *and* return xarray objects). Right now, this includes
#
# - Derivative functions
#     - ``first_derivative``
#     - ``second_derivative``
#     - ``gradient``
#     - ``laplacian``
Example #17
0
def test_coriolis_units():
    """Test that coriolis returns units of 1/second."""
    f = coriolis_parameter(50 * units.degrees)
    assert f.units == units('1/second')
Example #18
0
def test_coriolis_warning():
    """Test that warning is raise when latitude larger than pi radians."""
    with pytest.warns(UserWarning):
        coriolis_parameter(50)
    with pytest.warns(UserWarning):
        coriolis_parameter(-50)
Example #19
0
def test_coriolis_units():
    """Test that coriolis returns units of 1/second."""
    f = coriolis_parameter(50 * units.degrees)
    assert f.units == units('1/second')
Example #20
0
#########################################################################
# Calculations
# ------------
#
# Most of the calculations in `metpy.calc` will accept DataArrays by converting them
# into their corresponding unit arrays. While this may often work without any issues, we must
# keep in mind that because the calculations are working with unit arrays and not DataArrays:
#
# - The calculations will return unit arrays rather than DataArrays
# - Broadcasting must be taken care of outside of the calculation, as it would only recognize
#   dimensions by order, not name
#
# As an example, we calculate geostropic wind at 500 hPa below:

lat, lon = xr.broadcast(y, x)
f = mpcalc.coriolis_parameter(lat)
dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat, initstring=data_crs.proj4_init)
heights = data['height'].loc[time[0]].loc[{vertical.name: 500.}]
u_geo, v_geo = mpcalc.geostrophic_wind(heights, f, dx, dy)
print(u_geo)
print(v_geo)

#########################################################################
# Also, a limited number of calculations directly support xarray DataArrays or Datasets (they
# can accept *and* return xarray objects). Right now, this includes
#
# - Derivative functions
#     - ``first_derivative``
#     - ``second_derivative``
#     - ``gradient``
#     - ``laplacian``
"""

#####################################
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.util import add_cyclic_point
import matplotlib
import matplotlib.pyplot as plt
import metpy.calc as mpcalc
from metpy.units import units
import numpy as np

#####################################

lats = np.arange(-90, 91) * units.degrees
coriolis = mpcalc.coriolis_parameter(lats)

#####################################

fig = plt.figure(figsize=(8, 5))
ax = plt.subplot(1, 1, 1)
ax.plot(lats, coriolis)
ax.set_xlabel('Latitude', fontsize=14)
ax.set_ylabel('Coriolis Parameter', fontsize=14)

#####################################

lons = np.arange(0, 360)

coriolis = np.ones((181, 360)) * coriolis[:, np.newaxis]