import math import numpy as np import pylab as pl # most of the code adapted from pywrfplot # http://code.google.com/p/pywrfplot/ # purpose: plot raw data of Temperature and Dewpoint in skewT-log(p)-diagram skewness = 37.5 # Defines the ranges of the plot, do not confuse with P_bot and P_top P_b = 105000. P_t = 10000. dp = 100. plevs = np.arange(P_b,P_t-1,-dp) T_zero = 273.15 # P_top must be the same as what is used in the WRF simulation P_top = 10**4 P_bot = 10**5 L = 2.501e6 # latent heat of vaporization R = 287.04 # gas constant air Rv = 461.5 # gas constant vapor eps = R/Rv cp = 1005. cv = 718. kappa = (cp-cv)/cp g = 9.81 # constants used to calculate moist adiabatic lapse rate # See formula 3.16 in Rogers&Yau a = 2./7. b = eps*L*L/(R*cp) c = a*L/R def SkewTPlot(): pl.figure() _isotherms() _isobars() _dry_adiabats() _moist_adiabats() _plot_data() pl.axis([-40,50,P_b,P_t]) pl.xlabel('Temperatur ($^{\circ}\! C$)') xticks = np.arange(-40,51,5) pl.xticks(xticks,['' if tick%10!=0 else str(tick) for tick in xticks]) pl.ylabel('Pressure (hPa)') yticks = np.arange(P_bot,P_t-1,-10**4) pl.yticks(yticks,yticks/100) pl.show() pl.close() pl.clf() def _skewnessTerm(P): return skewness * np.log(P_bot/P) def _isotherms(): for temp in np.arange(-100,50,10): pl.semilogy(temp + _skewnessTerm(plevs), plevs, basey=math.e, \ color = ('blue'), \ linestyle=('solid' if temp == 0 else 'dashed'), linewidth = .5) def _isobars(): for n in np.arange(P_bot,P_t-1,-10**4): pl.plot([-40,50], [n,n], color = 'black', linewidth = .5) def _dry_adiabats(): for tk in T_zero+np.arange(-30,210,10): dry_adiabat = tk * (plevs/P_bot)**kappa - T_zero + _skewnessTerm(plevs) pl.semilogy(dry_adiabat, plevs, basey=math.e, color = 'brown', \ linestyle='dashed', linewidth = .5) def es(T): """Returns saturation vapor pressure (Pascal) at temperature T (Celsius) Formula 2.17 in Rogers&Yau""" return 611.2*np.exp(17.67*T/(T+243.5)) def gamma_s(T,p): """Calculates moist adiabatic lapse rate for T (Celsius) and p (Pa) Note: We calculate dT/dp, not dT/dz See formula 3.16 in Rogers&Yau for dT/dz, but this must be combined with the dry adiabatic lapse rate (gamma = g/cp) and the inverse of the hydrostatic equation (dz/dp = -RT/pg)""" esat = es(T) wsat = eps*esat/(p-esat) # Rogers&Yau 2.18 numer = a*(T+T_zero) + c*wsat denom = p * (1 + b*wsat/((T+T_zero)**2)) return numer/denom # Rogers&Yau 3.16 def _moist_adiabats(): ps = [p for p in plevs if p<=P_bot] for temp in np.concatenate((np.arange(-40.,10.1,5.),np.arange(12.5,45.1,2.5))): moist_adiabat = [] for p in ps: temp -= dp*gamma_s(temp,p) moist_adiabat.append(temp + _skewnessTerm(p)) pl.semilogy(moist_adiabat, ps, basey=math.e, color = 'green', \ linestyle = 'dashed', linewidth = .5) def _plot_data(): p,h,T,Td = np.loadtxt('/Users/daniel/tmp/soundingdata.txt',usecols=range(0,4),unpack=True) pl.semilogy(T+ _skewnessTerm(p*100),p*100,basey=math.e, color=('black'),linestyle=('solid'),linewidth= 1.5) pl.semilogy(Td+ _skewnessTerm(p*100),p*100,basey=math.e, color=('black'),linestyle=('solid'),linewidth= 1.5) return 1 SkewTPlot()