awips2/cave/com.raytheon.viz.avnconfig/localization/aviation/python/RadLtgThread.py
Max Schenkelberg 6f60751ec6 Issue #2033 moved avnfps and text workstation files into respective plugins.
Change-Id: If95cb839ad81ca2a842ff7f6926847ac3928d8f2

Former-commit-id: 77e1a4d8f5237e5fae930c1e00589c752f8b3738
2013-08-15 12:21:43 -05:00

196 lines
6.7 KiB
Python

##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
#
# Name:
# RadLtgThread.py
# GFS1-NHD:A7818.0000-SCRIPT;1.8
#
# Status:
# DELIVERED
#
# History:
# Revision 1.8 (DELIVERED)
# Created: 06-JUL-2005 18:16:41 TROJAN
# spr 6548
#
# Revision 1.7 (DELIVERED)
# Created: 07-MAY-2005 11:37:26 OBERFIEL
# Added Item Header Block
#
# Revision 1.6 (DELIVERED)
# Created: 28-APR-2005 19:30:44 TROJAN
# spr 6816
#
# Revision 1.5 (DELIVERED)
# Created: 18-APR-2005 17:32:21 OBERFIEL
# Changes to support gamin
#
# Revision 1.4 (DELIVERED)
# Created: 11-MAR-2005 15:55:31 TROJAN
# spr 6717
#
# Revision 1.3 (DELIVERED)
# Created: 15-FEB-2005 13:47:37 TROJAN
# spr 6650
#
# Revision 1.2 (APPROVED)
# Created: 30-SEP-2004 20:22:11 TROJAN
# stdr 873
#
# Revision 1.1 (APPROVED)
# Created: 01-JUL-2004 14:44:14 OBERFIEL
# date and time created -2147483647/-2147483648/-2147481748
# -2147483648:-2147483648:-2147483648 by oberfiel
#
# Change Document History:
# 1:
# Change Document: GFS1-NHD_SPR_6548
# Action Date: 09-AUG-2005 14:09:33
# Relationship Type: In Response to
# Status: CLOSED
# Title: AvnFPS: Data acquistion change in OB6
#
#
# RadLtgThread.py
# server for NCEP radar based lightning probability forecast
# Author: George Trojan, SAIC/MDL, October 2003
# last update: 05/27/05
import logging, math, os, Queue, re, time
import Numeric
import Scientific.IO.NetCDF
import Avn, AvnParser
_Pattern = re.compile(r'[0-9]{8}_[0-9]{4}.multi')
_Logger = logging.getLogger(__name__)
###############################################################################
class Server(object):
WaitTime = 60 # time between reads (seconds)
_Dest = os.path.join('data', 'rltg', 'data')
def __init__(self, inqueue, outqueue, info):
self.inqueue = inqueue
self.outqueue = outqueue
self.name = info['name']
self.datapath = info['source']
self.map = {}
def __getSites(self):
ids = AvnParser.getAllSiteIds()
self.sitelist = []
for ident in ids['taf']:
info = AvnParser.getTafSiteCfg(ident)
if info is None:
continue
d = {'id': ident, \
'lat': float(info['geography']['lat']), \
'lon': float(info['geography']['lon'])}
self.sitelist.append(d)
if not self.sitelist:
_Logger.debug('Cannot get site list')
raise SystemExit
def __getMapParms(self, fh):
if fh.projName != 'LAMBERT_CONFORMAL':
raise ValueError, 'Unsupported projection %s' % fh.projName
latC = math.radians(fh.centralLat[0])
lat1 = math.radians(fh.rotation[0])
if latC != lat1:
raise ValueError('Unsupported projection %s with 2 parallels' \
% fh.projName)
self.map = {'xmin': fh.xMin[0], 'xmax': fh.xMax[0], \
'ymin': fh.yMin[0], 'ymax': fh.yMax[0]}
self.map['n'] = math.cos(math.pi/2.0-latC)
self.map['lonC'] = math.radians(fh.centralLon[0])
self.map['nx'] = fh.dimensions['x']
self.map['ny'] = fh.dimensions['y']
def __getPoint(self, lat, lon):
r = math.tan((math.pi/2.0-math.radians(lat))/2.0)**self.map['n']
tau = (math.radians(lon)-self.map['lonC'])*self.map['n']
nx = (self.map['nx']-1)/(self.map['xmax']-self.map['xmin'])* \
(math.sin(tau)*r-self.map['xmin'])
ny = (self.map['ny']-1)/(self.map['ymin']-self.map['ymax'])* \
(-math.cos(tau)*r-self.map['ymax'])
return int(nx+1.0), int(ny+1.0)
def __readNetCDF(self, filename):
try:
fh = Scientific.IO.NetCDF.NetCDFFile(filename)
except IOError:
# bad or nonexistent file
_Logger.error('Error accessing %s', path)
return
_Logger.info('Processing file %s', filename)
self.__getMapParms(fh)
validtime = fh.variables['validTime'][0]
llvar = fh.variables['image']
for site in self.sitelist:
nx, ny = self.__getPoint(site['lat'], site['lon'])
if nx < 0 or nx >= self.map['nx'] or \
ny < 0 or ny >= self.map['ny']:
site['prob'] = -1
else:
v = llvar[0][ny][nx]
if v >= 0:
site['prob'] = v/2.0
else:
site['prob'] = (256.0+v)/2.0
fh.close()
data = ['Time\t%.0f\n' % validtime]
for site in self.sitelist:
p = site['prob']
if p >= 0:
line = '%s\t%.0f\n' % (site['id'], p)
data.append(line)
_Logger.debug(line[:-1])
file(self._Dest, 'w').writelines(data)
self.outqueue.put(Avn.Bunch(src=self.name, ident='ALL'))
def paths(self):
return [self.datapath]
def run(self):
self.__getSites()
while True:
lasttime = time.time()
flist = []
# optimization
while True:
try:
code, fname, direct = self.inqueue.get(True, 6)
if code == 0: # end thread
_Logger.info('Got exit request')
raise SystemExit
if _Pattern.match(fname) and (direct, fname) not in flist:
flist.append((direct, fname))
except Queue.Empty:
pass
if time.time() > lasttime + self.WaitTime:
break
if flist:
try:
flist.sort()
self.__readNetCDF(os.path.join(*flist[-1]))
except Exception:
_Logger.exception('Unexpected error')
break