Exemple #1
0
    def plot(self, ax):

        # Get global u/v wind data
        ug, vg = self.chart.get_data(self.gfs_vars, apply_domain=False)

        # Get level coordinates for U/V wind components
        ug_lv_coord = gfs_utils.get_level_coord(ug, self.level_units)
        vg_lv_coord = gfs_utils.get_level_coord(vg, self.level_units)

        # Constrain to specified level(s)
        ugc = gfs_utils.get_coord_constraint(ug_lv_coord.name(), self.level)
        ug = ug.extract(ugc)

        vgc = gfs_utils.get_coord_constraint(vg_lv_coord.name(), self.level)
        vg = vg.extract(vgc)

        # Apply smoothing
        ug_data = wrf_smooth2d(ug.data, 6)
        ug.data = ug_data.data
        vg_data = wrf_smooth2d(vg.data, 6)
        vg.data = vg_data.data

        # Set up windspharm wind vector object
        w = VectorWind(ug, vg)
        xi = w.vorticity()
        div = w.divergence()

        # Constrain to specified domain
        domain_constraint = gfs_utils.get_domain_constraint(self.chart.domain)
        xi = xi.extract(domain_constraint)
        div = div.extract(domain_constraint)

        # Calculate strain S following Schielicke et al 2016
        u_x, u_y = w.gradient(ug)
        v_x, v_y = w.gradient(vg)

        D_h = u_x + v_y  # horizontal divergence
        Def = u_x - v_y  # stretching deformation
        Def_s = u_y + v_x  # shearing deformation

        ss = D_h**2 + Def**2 + Def_s**2
        ss = ss.extract(domain_constraint)

        S = np.sqrt(ss.data) / math.sqrt(2)

        # Okubo-Weiss parameter
        # vorticity - (div + strain)
        okw = (div + S) - xi

        # Set mask to inspect O-W parameter in relevant region i.e. < 20N
        self.set_coord_mask(lat_max=20)

        # Define mask for O-W parameter
        mask = self.coord_mask | (okw.data < self.thres)

        # Apply mask
        okw_masked = iris.util.mask_cube(okw, mask)

        ax.contourf(self.lon, self.lat, okw_masked.data, **self.options)
Exemple #2
0
    def plot(self, ax):

        # Get global u/v wind data
        ug, vg = self.chart.get_data(self.gfs_vars, apply_domain=False)

        # Get level coordinates for U/V wind components
        ug_lv_coord = gfs_utils.get_level_coord(ug, self.level_units)
        vg_lv_coord = gfs_utils.get_level_coord(vg, self.level_units)

        # Constrain to specified level(s)
        ugc = gfs_utils.get_coord_constraint(ug_lv_coord.name(), self.level)
        ug = ug.extract(ugc)

        vgc = gfs_utils.get_coord_constraint(vg_lv_coord.name(), self.level)
        vg = vg.extract(vgc)

        # Apply smoothing
        ug_data = wrf_smooth2d(ug.data, 6)
        ug.data = ug_data.data
        vg_data = wrf_smooth2d(vg.data, 6)
        vg.data = vg_data.data

        # Set up windspharm wind vector object
        w = VectorWind(ug, vg)

        # Get divergence
        div = w.divergence()

        # Constrain to specified domain
        domain_constraint = gfs_utils.get_domain_constraint(self.chart.domain)
        div = div.extract(domain_constraint)

        # Mask absolute values below threshold
        div_masked = np.ma.masked_where(
            np.abs(div.data) < self.thres, div.data)

        # Set norm to match centre of colour scale to zero value
        self.options['norm'] = mcolors.TwoSlopeNorm(vmin=np.min(div_masked),
                                                    vcenter=0,
                                                    vmax=np.max(div_masked))

        ax.contourf(self.lon, self.lat, div_masked, **self.options)
Exemple #3
0
mpl.rcParams['mathtext.default'] = 'regular'


# Read zonal and meridional wind components from file using the iris module.
# The components are in separate files. We catch warnings here because the
# files are not completely CF compliant.
with warnings.catch_warnings():
    warnings.simplefilter('ignore', UserWarning)
    uwnd = iris.load_cube(example_data_path('uwnd_mean.nc'))
    vwnd = iris.load_cube(example_data_path('vwnd_mean.nc'))
uwnd.coord('longitude').circular = True
vwnd.coord('longitude').circular = True

# Create a VectorWind instance to handle the computations.
w = VectorWind(uwnd, vwnd)

# Compute components of rossby wave source: absolute vorticity, divergence,
# irrotational (divergent) wind components, gradients of absolute vorticity.
eta = w.absolutevorticity()
div = w.divergence()
uchi, vchi = w.irrotationalcomponent()
etax, etay = w.gradient(eta)
etax.units = 'm**-1 s**-1'
etay.units = 'm**-1 s**-1'

# Combine the components to form the Rossby wave source term.
S = eta * -1. * div - (uchi * etax + vchi * etay)
S.coord('longitude').attributes['circular'] = True

# Pick out the field for December at 200 hPa.
Exemple #4
0
from windspharm.examples import example_data_path


# Read zonal and meridional wind components from file using the iris module.
# The components are in separate files. We catch warnings here because the
# files are not completely CF compliant.
with warnings.catch_warnings():
    warnings.simplefilter('ignore', UserWarning)
    uwnd = iris.load_cube(example_data_path('uwnd_mean.nc'))
    vwnd = iris.load_cube(example_data_path('vwnd_mean.nc'))
uwnd.coord('longitude').circular = True
vwnd.coord('longitude').circular = True

# Create a VectorWind instance to handle the computation of streamfunction and
# velocity potential.
w = VectorWind(uwnd, vwnd)

# Compute the streamfunction and velocity potential.
sf, vp = w.sfvp()

# Pick out the field for December.
time_constraint = iris.Constraint(month='Dec')
add_month(sf, 'time', name='month')
add_month(vp, 'time', name='month')
sf_dec = sf.extract(time_constraint)
vp_dec = vp.extract(time_constraint)

# Plot streamfunction.
clevs = [-120, -100, -80, -60, -40, -20, 0, 20, 40, 60, 80, 100, 120]
ax = plt.subplot(111, projection=ccrs.PlateCarree(central_longitude=180))
fill_sf = iplt.contourf(sf_dec * 1e-06, clevs, cmap=plt.cm.RdBu_r,
Exemple #5
0
from windspharm.iris import VectorWind
from windspharm.examples import example_data_path

# Read zonal and meridional wind components from file using the iris module.
# The components are in separate files. We catch warnings here because the
# files are not completely CF compliant.
with warnings.catch_warnings():
    warnings.simplefilter('ignore', UserWarning)
    uwnd = iris.load_cube(example_data_path('uwnd_mean.nc'))
    vwnd = iris.load_cube(example_data_path('vwnd_mean.nc'))
uwnd.coord('longitude').circular = True
vwnd.coord('longitude').circular = True

# Create a VectorWind instance to handle the computations.
w = VectorWind(uwnd, vwnd)

# Compute components of rossby wave source: absolute vorticity, divergence,
# irrotational (divergent) wind components, gradients of absolute vorticity.
eta = w.absolutevorticity()
div = w.divergence()
uchi, vchi = w.irrotationalcomponent()
etax, etay = w.gradient(eta)
etax.units = 'm**-1 s**-1'
etay.units = 'm**-1 s**-1'

# Combine the components to form the Rossby wave source term.
S = eta * -1. * div - (uchi * etax + vchi * etay)
S.coord('longitude').attributes['circular'] = True

# Pick out the field for December at 200 hPa.
Exemple #6
0
from windspharm.iris import VectorWind
from windspharm.examples import example_data_path

# Read zonal and meridional wind components from file using the iris module.
# The components are in separate files. We catch warnings here because the
# files are not completely CF compliant.
with warnings.catch_warnings():
    warnings.simplefilter('ignore', UserWarning)
    uwnd = iris.load_cube(example_data_path('uwnd_mean.nc'))
    vwnd = iris.load_cube(example_data_path('vwnd_mean.nc'))
uwnd.coord('longitude').circular = True
vwnd.coord('longitude').circular = True

# Create a VectorWind instance to handle the computation of streamfunction and
# velocity potential.
w = VectorWind(uwnd, vwnd)

# Compute the streamfunction and velocity potential.
sf, vp = w.sfvp()

# Pick out the field for December.
time_constraint = iris.Constraint(month='Dec')
add_month(sf, 'time', name='month')
add_month(vp, 'time', name='month')
sf_dec = sf.extract(time_constraint)
vp_dec = vp.extract(time_constraint)

# Plot streamfunction.
clevs = [-120, -100, -80, -60, -40, -20, 0, 20, 40, 60, 80, 100, 120]
ax = plt.subplot(111, projection=ccrs.PlateCarree(central_longitude=180))
fill_sf = iplt.contourf(sf_dec * 1e-06,
Exemple #7
0
mons = 6
lag = 0
max_i = 35 + lag
max_f = max_i + mons
min_i = 11 + lag
min_f = min_i + mons

plt.clf()
plt.ion()

lsmask = iris.load_cube(ncfile_path + 'lsmask.nc')[0,0,::]
lsmask.coord('latitude').guess_bounds()
lsmask.coord('longitude').guess_bounds()
# landmask = ~(ma.make_mask(lsmask.data.copy()) + np.zeros(temp_plv.shape)).astype(bool) # mask sea, show land
# seamask = (ma.make_mask(lsmask.data.copy()) + np.zeros(temp_plv.shape)).astype(bool) # mask land, show sea
uv = VectorWind(u,v)
uv_div = uv.divergence()
psi = uv.streamfunction()

plev_b = 300
plev_t = 850

uv_uptrop_max = ta.iristropave(uv_div,plev_bottom=500,plev_top=200)[max_i:max_f,::].collapsed('time',iris.analysis.MEAN)
uv_midtrop_max = ta.iristropave(uv_div,plev_bottom=850,plev_top=500)[max_i:max_f,::].collapsed('time',iris.analysis.MEAN)
uv_lowtrop_max = ta.iristropave(uv_div,plev_bottom=1000,plev_top=850)[max_i:max_f,::].collapsed('time',iris.analysis.MEAN)

u_uptrop_max = ta.iristropave(u,plev_bottom=500,plev_top=200)[max_i:max_f,::].collapsed('time',iris.analysis.MEAN)
u_midtrop_max = ta.iristropave(u,plev_bottom=850,plev_top=500)[max_i:max_f,::].collapsed('time',iris.analysis.MEAN)
u_lowtrop_max = ta.iristropave(u,plev_bottom=1000,plev_top=850)[max_i:max_f,::].collapsed('time',iris.analysis.MEAN)
v_uptrop_max = ta.iristropave(v,plev_bottom=500,plev_top=200)[max_i:max_f,::].collapsed('time',iris.analysis.MEAN)
v_midtrop_max = ta.iristropave(v,plev_bottom=850,plev_top=500)[max_i:max_f,::].collapsed('time',iris.analysis.MEAN)
Exemple #8
0
    def plot(self, ax):

        # Get global u/v wind data
        ug, vg = self.chart.get_data(self.gfs_vars, apply_domain=False)

        # Get level coordinates for U/V wind components
        ug_lv_coord = gfs_utils.get_level_coord(ug, self.level_units)
        vg_lv_coord = gfs_utils.get_level_coord(vg, self.level_units)

        # Constrain to specified level(s)
        ugc = gfs_utils.get_coord_constraint(ug_lv_coord.name(), self.level)
        ug = ug.extract(ugc)

        vgc = gfs_utils.get_coord_constraint(vg_lv_coord.name(), self.level)
        vg = vg.extract(vgc)

        # Apply smoothing
        ug_data = wrf_smooth2d(ug.data, 6)
        ug.data = ug_data.data
        vg_data = wrf_smooth2d(vg.data, 6)
        vg.data = vg_data.data

        # Set up windspharm wind vector object
        w = VectorWind(ug, vg)

        # Get nondivergent component of wind
        upsi, vpsi = w.nondivergentcomponent()
        Vpsi = VectorWind(upsi, vpsi)

        # Partition streamfunction vorticity into curvature and shear
        # components

        # Bell and Keyser 1993 Appendix equation A.3b
        # Relative curvature vorticity:
        # V dalpha/ds = 1/V^2[u^2 dv/dx - v^2 du/dy - uv(du/dx - dv/dy)]

        dupsi_dx, dupsi_dy = Vpsi.gradient(upsi)
        dvpsi_dx, dvpsi_dy = Vpsi.gradient(vpsi)
        ws = Vpsi.magnitude()

        vrt = (upsi**2 * dvpsi_dx - vpsi**2 * dupsi_dy - upsi * vpsi *
               (dupsi_dx - dvpsi_dy)) / ws**2

        # Calculate advection of non-divergent curvature vorticity
        dvrt_dx, dvrt_dy = Vpsi.gradient(vrt)
        advec = -1 * (upsi * dvrt_dx + vpsi * dvrt_dy)

        # Second order advection term needed for masking
        dadv_dx, dadv_dy = Vpsi.gradient(advec)
        advec2 = upsi * dadv_dx + vpsi * dadv_dy

        # Apply domain constraint
        domain_constraint = gfs_utils.get_domain_constraint(self.chart.domain)
        upsi = upsi.extract(domain_constraint)
        vrt = vrt.extract(domain_constraint)
        advec = advec.extract(domain_constraint)
        advec2 = advec2.extract(domain_constraint)

        # Masking rules from Berry & Thorncroft 2007, Table 1

        # A1. Mask streamfunction curvature vorticity to exclude AEW
        # ridges axes or weak systems (BT2007: K1T = 0.5 * 10^-5 s^-1)
        K1T = 1.5 * 10**-5  # s^-1
        m1t = vrt.data <= K1T  # mask for troughs
        m1r = vrt.data >= -K1T  # mask for ridges

        # A2. Remove "pseudoridge" axes in nondivergent flow that is
        # highly cyclonically curved
        K2T = 0  # m s^-3
        m2 = advec2.data <= K2T

        # A3. Removes trough axes in westerly flow
        K3T = 0  # m s^-1
        m3 = upsi.data >= K3T

        trough_mask = m1t | m2 | m3
        ridge_mask = m1r | ~m2 | m3

        troughs = self.apply_size_mask(trough_mask, advec.data)
        ridges = self.apply_size_mask(ridge_mask, advec.data)

        # Plot troughs and ridges
        ax.contour(self.lon, self.lat, troughs, levels=0, **self.options)
        ax.contour(self.lon,
                   self.lat,
                   ridges,
                   levels=0,
                   **self.options,
                   linestyles="dotted")