Example #1
0
def thetae( altimiter, tpc, tdc ):
  theta = thermo.theta( altimiter, tpc )
  hpa = 33.8639 * altimiter
  tdk = tdc + 273.15
  tpk = tpc + 273.15
  func2 = ( -1*5420 )/tdk
  e = ( 2.53 * pow( 10,11 ) ) * np.exp( func2 )
  e_hpa = e / 100
  mixr = ( ( 0.622 * e_hpa )/( hpa - e_hpa ) )
  thetae = theta*np.exp( ( ( 2.50 * pow( 10, 6 ) ) * mixr )/( 1005 * tpk ) )
  return thetae
Example #2
0
def thetae(altimiter, tpc, tdc):
    theta = thermo.theta(altimiter, tpc)
    hpa = 33.8639 * altimiter
    tdk = tdc + 273.15
    tpk = tpc + 273.15
    func2 = (-1 * 5420) / tdk
    e = (2.53 * pow(10, 11)) * np.exp(func2)
    e_hpa = e / 100
    mixr = ((0.622 * e_hpa) / (hpa - e_hpa))
    thetae = theta * np.exp(((2.50 * pow(10, 6)) * mixr) / (1005 * tpk))
    return thetae
Example #3
0
def make_skewT(tmin, tmax, pmax, pmin, skew=30.):
    #make a blank skewT diagram
    clf()
    #get a dense range of p, t0 to contour
    yplot = linspace(1050, 100, 100)
    xplot = linspace(-50, 50, 100)
    xplot, yplot = meshgrid(xplot, yplot)
    
    #lay down a reference grid that labels xplot,yplot points 
    #in the new (skewT-lnP) coordinate system .
    # Each value of the temp matrix holds the actual (data) temperature
    # label (in deg C)  of the xplot, yplot coordinate pairs
    #note that we don't have to transform the y coordinate
    #it's still the pressure

    #use the real (data) value to get the potential temperature
    T = xplot + skew*log(0.001*yplot)
    Tk = T + 273.15 #convert from C to K for use in thermo functios
    p = yplot*100. #convert from hPa to Pa

    th = thermo.theta(p, Tk) #theta labels

    #add the mixing ratio
    rstar = thermo.r_star(p, Tk)  #wsat labels

    #saturated adiabat, so Tdew=Tk
    thetaeVals = thermo.theta_e(p, Tk, rstar, 0.)    
    
    tempLabels = arange(-140., 50., 10.)
    con1 = contour(xplot, yplot, T, levels = tempLabels, colors = 'k', linewidths=.5)
    ax = gca()
    ax.set_yscale('log')
    lines = arange(100., 1100., 100.)
    yticks(lines, ['100','200','300','400','500','600','700','800','900','1000'])
    for line in lines:
        axhline(line, ls=':', color='k', linewidth=.5)
    thetaLabels = arange(200., 380., 10.)
    con2 = contour(xplot, yplot, th, levels = thetaLabels, colors='b', linewidths=.5)
    #rsLabels = [.1,.2,.4,.6, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 40]
    #con3 = contour(xplot, yplot, rstar*1.e3, levels=rsLabels, colors='g', linewidths=.5)
    #thetaeLabels = linspace(200,400,21)
    #con4 = contour(xplot, yplot, thetaeVals, levels = thetaeLabels, colors='r', linewidths=.5)
    axis([tmin, tmax, pmax, pmin])
    clabel(con1, inline = False, fmt = '%1.0f')
    clabel(con2, inline = False, fmt = '%1.0f')
    #clabel(con3, inline = False, fmt = '%1.1f')
    #clabel(con4, inline = False, fmt = '%1.0f')
    title('skew T - lnp chart')
    ylabel('pressure (hPa)')
    xlabel('temperature (black, degrees C)')
Example #4
0
def make_skewT(tmin, tmax, pmax, pmin, skew=30.):
    #make a blank skewT diagram
    clf()
    #get a dense range of p, t0 to contour
    yplot = linspace(1050, 100, 100)
    xplot = linspace(-50, 50, 100)
    xplot, yplot = meshgrid(xplot, yplot)

    #lay down a reference grid that labels xplot,yplot points
    #in the new (skewT-lnP) coordinate system .
    # Each value of the temp matrix holds the actual (data) temperature
    # label (in deg C)  of the xplot, yplot coordinate pairs
    #note that we don't have to transform the y coordinate
    #it's still the pressure

    #use the real (data) value to get the potential temperature
    T = xplot + skew * log(0.001 * yplot)
    Tk = T + 273.15  #convert from C to K for use in thermo functios
    p = yplot * 100.  #convert from hPa to Pa

    th = thermo.theta(p, Tk)  #theta labels

    #add the mixing ratio
    rstar = thermo.r_star(p, Tk)  #wsat labels

    #saturated adiabat, so Tdew=Tk
    thetaeVals = thermo.theta_e(p, Tk, rstar, 0.)

    tempLabels = arange(-140., 50., 10.)
    con1 = contour(xplot,
                   yplot,
                   T,
                   levels=tempLabels,
                   colors='k',
                   linewidths=.5)
    ax = gca()
    ax.set_yscale('log')
    lines = arange(100., 1100., 100.)
    yticks(lines, [
        '100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'
    ])
    for line in lines:
        axhline(line, ls=':', color='k', linewidth=.5)
    thetaLabels = arange(200., 380., 10.)
    con2 = contour(xplot,
                   yplot,
                   th,
                   levels=thetaLabels,
                   colors='b',
                   linewidths=.5)
    rsLabels = [.1, .2, .4, .6, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 40]
    con3 = contour(xplot,
                   yplot,
                   rstar * 1.e3,
                   levels=rsLabels,
                   colors='g',
                   linewidths=.5)
    thetaeLabels = linspace(200, 400, 21)
    con4 = contour(xplot,
                   yplot,
                   thetaeVals,
                   levels=thetaeLabels,
                   colors='r',
                   linewidths=.5)
    axis([tmin, tmax, pmax, pmin])
    clabel(con1, inline=False, fmt='%1.0f')
    clabel(con2, inline=False, fmt='%1.0f')
    clabel(con3, inline=False, fmt='%1.1f')
    clabel(con4, inline=False, fmt='%1.0f')
    title('skew T - lnp chart')
    ylabel('pressure (hPa)')
    xlabel('temperature (black, degrees C)')
Example #5
0
    def Surface(self, **kwargs):  ## Here begins the METAR decoder
        self.DatDict = {}  ## this will serve as the intermediate dictionary for sorting
        self.RESULT = {}  ## this is the result dictionary
        self.count = 0  ## will be used to tell us how many stations were not found
        stations = self.StationDict
        cycle = kwargs.get("cycle", self.cycle)
        file = urllib.urlopen("http://metfs1.agron.iastate.edu/data/text/sao/" + cycle + ".sao")
        text = (
            file.read()
            .replace("\n", "")
            .replace("\x03", "")
            .replace("\x03\x01", "")
            .replace("\r", "")
            .strip()
            .split("=")
        )

        ## process the text
        for line in text:
            if line.startswith("METAR"):
                line = line.strip("METAR")
            if (
                line.startswith("K") == False
                and line.startswith("C") == False
                and line.startswith("M") == False
                and line.startswith("P") == False
            ):  ## ignore lines with no metar station
                continue
            else:
                stn_key = line[:4]  ## grab the station identifies, i.e. KBNA
                try:
                    ## repeat observations are filtered by choosing the longest list of observations
                    if len(self.DatDict[stn_key].split()) < len(line[4:].split()):
                        self.DatDict[stn_key] = line[4:]
                except:
                    ## if no observation, initialize it in the dictionary
                    self.DatDict[stn_key] = line[4:]

        for stn in self.DatDict.keys():
            if not stn in stations:
                self.count += 1  ## count the stations missing from the file
                continue
            stndat = self.DatDict[stn]
            if re.search("([0-9][0-9][0-9])([0-9][0-9])(G[0-9][0-9]KT)", stndat):
                ## These various regular expressions search for patterns
                ## that correspond with a certain type of data
                windat = re.search("([0-9][0-9][0-9])([0-9][0-9])(G[0-9][0-9]KT)", stndat).group()
                self.wdir = int(windat[:3])
                self.wspd = int(windat[3:-5])
                self.gust = int(windat[-4:-2])
            elif re.search("([0-9][0-9][0-9])([0-9][0-9]KT)", stndat):
                windat = re.search("([0-9][0-9][0-9])([0-9][0-9])KT", stndat).group()
                self.wdir = int(windat[:3])
                self.wspd = int(windat[3:-2])
                self.gust = np.nan
            else:
                self.wdir = np.nan
                self.wspd = np.nan
                self.gust = np.nan
            if re.search(
                "\s(M[0-9][0-9])/(M[0-9][0-9])\s|\s([0-9][0-9])/(M[0-9][0-9])\s|\s(M[0-9][0-9])/(NIL)\s|\s([0-9][0-9])/(NIL)\s|\s([0-9][0-9])/([0-9][0-9])\s",
                stndat,
            ):
                self.tempdat = (
                    re.search(
                        "\s(M[0-9][0-9])/(M[0-9][0-9])\s|\s([0-9][0-9])/(M[0-9][0-9])\s|\s(M[0-9][0-9])/(NIL)\s|\s([0-9][0-9])/(NIL)\s|\s([0-9][0-9])/([0-9][0-9])\s",
                        stndat,
                    )
                    .group()
                    .replace("M", "-")
                    .split("/")
                )
                self.tempdat[0] = int(self.tempdat[0])
                self.tempdat[1] = int(self.tempdat[1])
            else:
                self.tempdat = [np.nan, np.nan]
            if re.search("SLP[0-9][0-9][0-9]", stndat):
                self.slpdat = re.search("SLP[0-9][0-9][0-9]", stndat).group().replace("SLP", "")
                if int(self.slpdat) <= 500:
                    self.slpdat = 1000 + int(self.slpdat[:2]) + int(self.slpdat[2]) / 10
                elif int(self.slpdat) > 500:
                    self.slpdat = 900 + int(self.slpdat[:2]) + int(self.slpdat[2]) / 10
            else:
                self.slpdat = np.nan
            if re.search("A[0-9][0-9][0-9][0-9]", stndat):
                self.altdat = re.search("A[0-9][0-9][0-9][0-9]", stndat).group().strip("A")
                self.altdat = int(self.altdat[:2]) + float(self.altdat[2:]) / 100
            else:
                self.altdat = np.nan
            if re.search("[0-9][0-9]SM|[0-9]SM", stndat):
                self.vis = re.search("[0-9][0-9]SM|[0-9]SM", stndat).group().replace("SM", "")
            else:
                self.vis = np.nan
            if re.search("\s(P[0-9][0-9][0-9][0-9])", stndat):
                self.precip = re.search("\s(P[0-9][0-9][0-9][0-9])", stndat).group().replace("P", "")
                self.precip = float(str(self.precip)[:2] + "." + str(self.precip)[3:])
            else:
                self.precip = np.nan
            self.RESULT[stn] = {}
            self.RESULT[stn]["TMPC"] = self.tempdat[0]
            self.RESULT[stn]["TMPF"] = self.tempdat[0] * 1.8 + 32
            self.RESULT[stn]["DWPC"] = self.tempdat[1]
            self.RESULT[stn]["DWPF"] = self.tempdat[1] * 1.8 + 32
            self.RESULT[stn]["THTA"] = therm.theta(self.altdat, self.tempdat[0])
            self.RESULT[stn]["MIXR"] = therm.mixingratio(self.altdat, self.tempdat[0], self.tempdat[1])
            self.RESULT[stn]["THTE"] = therm.thetae(self.altdat, self.tempdat[0], self.tempdat[1])
            self.RESULT[stn]["RELH"] = therm.relhumid(self.tempdat[0], self.tempdat[1])
            self.RESULT[stn]["WDIR"] = self.wdir
            self.RESULT[stn]["WSPD"] = self.wspd
            self.RESULT[stn]["GUST"] = self.gust
            self.RESULT[stn]["VWIN"] = vect.VWIN(self.wdir, self.wspd)
            self.RESULT[stn]["UWIN"] = vect.UWIN(self.wdir, self.wspd)
            self.RESULT[stn]["UMET"] = vect.UMET(self.wdir, self.wspd)
            self.RESULT[stn]["VMET"] = vect.VMET(self.wdir, self.wspd)
            self.RESULT[stn]["PRES"] = self.slpdat
            self.RESULT[stn]["ALTI"] = self.altdat
            self.RESULT[stn]["VISI"] = self.vis
            self.RESULT[stn]["PCPN"] = self.precip
        file.close()
        return self.RESULT
Example #6
0
    def Surface(self, **kwargs):  ## Here begins the METAR decoder
        self.DatDict = {
        }  ## this will serve as the intermediate dictionary for sorting
        self.RESULT = {}  ## this is the result dictionary
        self.count = 0  ## will be used to tell us how many stations were not found
        stations = self.StationDict
        cycle = kwargs.get('cycle', self.cycle)
        file = urllib.urlopen(
            'http://metfs1.agron.iastate.edu/data/text/sao/' + cycle + '.sao')
        text = file.read().replace('\n', '').replace('\x03', '').replace(
            '\x03\x01', '').replace('\r', '').strip().split('=')

        ## process the text
        for line in text:
            if line.startswith('METAR'):
                line = line.strip('METAR')
            if line.startswith('K') == False and line.startswith(
                    'C'
            ) == False and line.startswith('M') == False and line.startswith(
                    'P') == False:  ## ignore lines with no metar station
                continue
            else:
                stn_key = line[:4]  ## grab the station identifies, i.e. KBNA
                try:
                    ## repeat observations are filtered by choosing the longest list of observations
                    if len(self.DatDict[stn_key].split()) < len(
                            line[4:].split()):
                        self.DatDict[stn_key] = line[4:]
                except:
                    ## if no observation, initialize it in the dictionary
                    self.DatDict[stn_key] = line[4:]

        for stn in self.DatDict.keys():
            if not stn in stations:
                self.count += 1  ## count the stations missing from the file
                continue
            stndat = self.DatDict[stn]
            if re.search('([0-9][0-9][0-9])([0-9][0-9])(G[0-9][0-9]KT)',
                         stndat):
                ## These various regular expressions search for patterns
                ## that correspond with a certain type of data
                windat = re.search(
                    '([0-9][0-9][0-9])([0-9][0-9])(G[0-9][0-9]KT)',
                    stndat).group()
                self.wdir = int(windat[:3])
                self.wspd = int(windat[3:-5])
                self.gust = int(windat[-4:-2])
            elif re.search('([0-9][0-9][0-9])([0-9][0-9]KT)', stndat):
                windat = re.search('([0-9][0-9][0-9])([0-9][0-9])KT',
                                   stndat).group()
                self.wdir = int(windat[:3])
                self.wspd = int(windat[3:-2])
                self.gust = np.nan
            else:
                self.wdir = np.nan
                self.wspd = np.nan
                self.gust = np.nan
            if re.search(
                    '\s(M[0-9][0-9])/(M[0-9][0-9])\s|\s([0-9][0-9])/(M[0-9][0-9])\s|\s(M[0-9][0-9])/(NIL)\s|\s([0-9][0-9])/(NIL)\s|\s([0-9][0-9])/([0-9][0-9])\s',
                    stndat):
                self.tempdat = re.search(
                    '\s(M[0-9][0-9])/(M[0-9][0-9])\s|\s([0-9][0-9])/(M[0-9][0-9])\s|\s(M[0-9][0-9])/(NIL)\s|\s([0-9][0-9])/(NIL)\s|\s([0-9][0-9])/([0-9][0-9])\s',
                    stndat).group().replace('M', '-').split('/')
                self.tempdat[0] = int(self.tempdat[0])
                self.tempdat[1] = int(self.tempdat[1])
            else:
                self.tempdat = [np.nan, np.nan]
            if re.search('SLP[0-9][0-9][0-9]', stndat):
                self.slpdat = re.search('SLP[0-9][0-9][0-9]',
                                        stndat).group().replace('SLP', '')
                if int(self.slpdat) <= 500:
                    self.slpdat = 1000 + int(
                        self.slpdat[:2]) + int(self.slpdat[2]) / 10
                elif int(self.slpdat) > 500:
                    self.slpdat = 900 + int(
                        self.slpdat[:2]) + int(self.slpdat[2]) / 10
            else:
                self.slpdat = np.nan
            if re.search('A[0-9][0-9][0-9][0-9]', stndat):
                self.altdat = re.search('A[0-9][0-9][0-9][0-9]',
                                        stndat).group().strip('A')
                self.altdat = int(
                    self.altdat[:2]) + float(self.altdat[2:]) / 100
            else:
                self.altdat = np.nan
            if re.search('[0-9][0-9]SM|[0-9]SM', stndat):
                self.vis = re.search('[0-9][0-9]SM|[0-9]SM',
                                     stndat).group().replace('SM', '')
            else:
                self.vis = np.nan
            if re.search('\s(P[0-9][0-9][0-9][0-9])', stndat):
                self.precip = re.search('\s(P[0-9][0-9][0-9][0-9])',
                                        stndat).group().replace('P', '')
                self.precip = float(
                    str(self.precip)[:2] + '.' + str(self.precip)[3:])
            else:
                self.precip = np.nan
            self.RESULT[stn] = {}
            self.RESULT[stn]['TMPC'] = self.tempdat[0]
            self.RESULT[stn]['TMPF'] = self.tempdat[0] * 1.8 + 32
            self.RESULT[stn]['DWPC'] = self.tempdat[1]
            self.RESULT[stn]['DWPF'] = self.tempdat[1] * 1.8 + 32
            self.RESULT[stn]['THTA'] = therm.theta(self.altdat,
                                                   self.tempdat[0])
            self.RESULT[stn]['MIXR'] = therm.mixingratio(
                self.altdat, self.tempdat[0], self.tempdat[1])
            self.RESULT[stn]['THTE'] = therm.thetae(self.altdat,
                                                    self.tempdat[0],
                                                    self.tempdat[1])
            self.RESULT[stn]['RELH'] = therm.relhumid(self.tempdat[0],
                                                      self.tempdat[1])
            self.RESULT[stn]['WDIR'] = self.wdir
            self.RESULT[stn]['WSPD'] = self.wspd
            self.RESULT[stn]['GUST'] = self.gust
            self.RESULT[stn]['VWIN'] = vect.VWIN(self.wdir, self.wspd)
            self.RESULT[stn]['UWIN'] = vect.UWIN(self.wdir, self.wspd)
            self.RESULT[stn]['UMET'] = vect.UMET(self.wdir, self.wspd)
            self.RESULT[stn]['VMET'] = vect.VMET(self.wdir, self.wspd)
            self.RESULT[stn]['PRES'] = self.slpdat
            self.RESULT[stn]['ALTI'] = self.altdat
            self.RESULT[stn]['VISI'] = self.vis
            self.RESULT[stn]['PCPN'] = self.precip
        file.close()
        return self.RESULT