Ejemplo n.º 1
0
def calc_sounding_stats(_z, _th, _p, _qv):
    T = met.T(_th, _p)  # T (K)
    pcl = met.CAPE(_z, _p, T, _qv, 1)  # CAPE
    mupcl = met.CAPE(_z, _p, T, _qv, 2)  # MUCAPE
    mlpcl = met.CAPE(_z, _p, T, _qv, 3)  # MLCAPE

    return (pcl, mupcl, mlpcl)
Ejemplo n.º 2
0
def plot_sounding_data(filename, output):
    """Plot SkewT from a WRF / CM1 compatible sounding data file
    
        :param filename: The name of the file to open.
        :type filename: str
        :param output: The name of the file to output plot
        :type output: str

        The datafile is the same format as used in sounding initalization
        files for WRF and CM1. 
        
        The format is:
        1 line header with surface pressure (mb), theta (K) and qv (g/kg)
        n number of lines with z (m), theta (K), qv (g/kg), u (m/s), v(m/s)

        """
    # load first line of file
    with open(filename, 'r') as f:
        surface = f.readline()

    p0, th0, qv0 = surface.split()

    # load rest of file
    _z, _th, _qv, _u, _v = np.loadtxt(filename, unpack=True, skiprows=1)

    # create arrays with one more z index for surface values
    nk = len(_z) + 1
    z = np.empty(nk, np.float32)
    th = np.empty(nk, np.float32)
    qv = np.empty(nk, np.float32)
    u = np.empty(nk, np.float32)
    v = np.empty(nk, np.float32)
    p = np.empty(nk, np.float32)

    # copy the arrays, leaving room at the surface
    z[1:nk] = _z
    th[1:nk] = _th
    qv[1:nk] = _qv / 1000.
    u[1:nk] = _u
    v[1:nk] = _v

    # assign surface values
    z[0] = 0.
    th[0] = float(th0)
    qv[0] = float(qv0) / 1000.
    u[0] = 1.75 * u[1] - u[2] + 0.25 * u[3]
    v[0] = 1.75 * v[1] - v[2] + 0.25 * v[3]
    p[0] = float(p0) * 100.

    # integrate pressure, assume hydrostatic
    # dp = -rho*g*dz
    for k in np.arange(1, nk):
        p[k] = p[k - 1] * np.exp(
            (metconst.g * (z[k - 1] - z[k])) / (metconst.Rd * met.T(
                (th[k] + th[k - 1]) / 2., p[k - 1])))

    #for k in np.arange(nk):
    #    print(z[k], p[k], th[k], qv[k], u[k], v[k])

    plot(None, z, th, p, qv, u, v, output, title="input sounding")
Ejemplo n.º 3
0
def draw_dry_adiabat(axes):
    """Plot dry adiabats on axes

    :parameter axes: The axes to draw on
    :type axes: :py:class:`matplotlib.axes`

    This function calculates dry adiabats
    and plots these lines.  Adiabats are calculated 
    every 10 K
    """
    for T in dry_adiabats:
        dry_adiabat = met.T(T + met.T00,
                            plevs_plot) - met.T00 + skew(plevs_plot)
        if (T % 10 == 0):
            axes.semilogy(dry_adiabat,
                          plevs_plot,
                          basey=math.e,
                          color=lc_major,
                          linewidth=lw_major)
        else:
            axes.semilogy(dry_adiabat,
                          plevs_plot,
                          basey=math.e,
                          color=lc_minor,
                          linewidth=lw_minor)

    for T in np.arange(-20, 150, 10):
        p = (600. - 3.5 * T) * 100.
        x = met.T(T + met.T00, p) - met.T00 + skew(p)
        x1 = met.T(T + met.T00,
                   p + .5 * dp_plot) - met.T00 + skew(p + .5 * dp_plot)
        x2 = met.T(T + met.T00,
                   p - .5 * dp_plot) - met.T00 + skew(p - .5 * dp_plot)
        dx = x2 - x1
        theta = math.atan2(-dp_plot, -dx) * 180 / math.pi + 37
        label(x, p / 100, str(T), 'black', theta, axes)
Ejemplo n.º 4
0
def plot_sounding(axes, z, th, p, qv, u=None, v=None):
    """Plot sounding data

  This plots temperature, dewpoint and wind data on a Skew-T/Log-P plot.
  This will also plot derived values such as wetbulb temperature and
  label the surface based LCL, LFC and EL.

  :parameter z: height values (1D array)
  :parameter th: potential temperature at z heights (1D array)
  :parameter p: pressure at z heights (1D array)
  :parameter qv: water vapor mixing ratio at z heights (1D array)
  :parameter u: U component of wind at z heights (1D array)
  :parameter v: V component of wind at z heights (1D array)
  :paramter axes: The axes instance to draw on
  """
    # calculate Temperature and dewpoint
    T = met.T(th, p) - met.T00  # T (C)
    Td = met.Td(p, qv) - met.T00  # Td (C)

    # calculate wetbulb temperature
    Twb = np.empty(len(z), np.float32)  # Twb (C)
    for zlvl in range(len(z)):
        Twb[zlvl] = met.Twb(z, p, th, qv, z[zlvl])

    # Get surface parcel CAPE and temperature / height profiles
    pcl = met.CAPE(z, p, T + met.T00, qv, 1)  # CAPE
    T_parcel = pcl['t_p'] - met.T00  # parcel T (C)
    T_vparcel = pcl['tv_p'] - met.T00  # parcel Tv (C)
    T_venv = met.T(pcl['thv_env'], pcl['pp']) - met.T00  # Env Tv (C)

    # plot Temperature, dewpoint, wetbulb and lifted surface parcel profiles on skew axes
    axes.semilogy(T + skew(p),
                  p,
                  basey=math.e,
                  color=linecolor_T,
                  linewidth=linewidth_T)
    axes.semilogy(Td + skew(p),
                  p,
                  basey=math.e,
                  color=linecolor_Td,
                  linewidth=linewidth_Td)
    axes.semilogy(T_parcel + skew(pcl['pp']),
                  pcl['pp'],
                  basey=math.e,
                  color=linecolor_Parcel_T,
                  linewidth=linewidth_Parcel_T)
    axes.semilogy(Twb + skew(p),
                  p,
                  basey=math.e,
                  color=linecolor_Twb,
                  linewidth=linewidth_Twb)

    # plot virtual temperature of environment and lifted parcel
    axes.semilogy(T_venv + skew(pcl['pp']),
                  pcl['pp'],
                  basey=math.e,
                  color=linecolor_Tve,
                  linewidth=linewidth_Tve,
                  linestyle=linestyle_Tve)
    axes.semilogy(T_vparcel + skew(pcl['pp']),
                  pcl['pp'],
                  basey=math.e,
                  color=linecolor_Tvp,
                  linewidth=linewidth_Tvp,
                  linestyle=linestyle_Tvp)

    # Add labels for levels based on surface parcel
    #debug print(pcl['lfcprs'], pcl['lclprs'], pcl['elprs'], pcl['ptops'])
    if (pcl['lfcprs'] > 0):
        label_m(Tmax - .5, pcl['lfcprs'], '--LFC', axes)
    if (pcl['lclprs'] > 0):
        label_m(Tmax - .5, pcl['lclprs'], '--LCL', axes)
    if (pcl['elprs'] > 0):
        label_m(Tmax - .5, pcl['elprs'], '--EL', axes)
    if (pcl['ptops'] > 0):
        label_m(Tmax - .5, pcl['ptops'], '--TOPS', axes)

    # plot labels for std heights
    for plvl in plevs_std:
        zlvl = pymeteo.interp.interp_height(z, p, plvl)
        label_m(Tmin - .5, plvl, str(int(zlvl)), axes)

    # plot wind barbs on left side of plot.  move this?  right side?
    if (u is not None and v is not None):
        #draw_wind_line(axes)
        for i in np.arange(0, len(z), 2):
            if (p[i] > pt_plot):
                plt.barbs(Tmin + 4, p[i], u[i], v[i], length=5, linewidth=.5)