awips2/cave/com.raytheon.viz.gfe/python/query/Query.py
2022-05-05 12:34:50 -05:00

229 lines
8.6 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.
##
##
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# Aug 12, 2013 2162 dgilling Add performance logging for
# query evaluation.
########################################################################
import numpy, copy, time, re
from com.raytheon.uf.common.status import PerformanceStatus
from com.raytheon.uf.common.time.util import TimeUtil
PERF_LOG = PerformanceStatus.getHandler("GFE:")
class Query:
def mask(self, wx, query, isreg=0):
# Returns a numeric mask i.e. a grid of 0's and 1's
# where the value is 1 if the given query succeeds
# Arguments:
# wx -- a 2-tuple:
# wxValues : numerical grid of byte values
# keys : list of "ugly strings" where the index of
# the ugly string corresponds to the byte value in
# the wxValues grid.
# query -- a text string representing a query
# isreg -- if 1, the query is treated as a regular expression
# otherwise as a literal string
# Examples:
# # Here we want to treat the query as a regular expression
# PoP = where(self.wxMask(wxTuple, "^Chc:", 1), maximum(40, PoP), PoP)
# # Here we want to treat the query as a literal
# PoP = where(self.wxMask(wxTuple, ":L:") maximum(5, PoP), PoP)
#
rv = numpy.zeros(wx[0].shape, dtype=bool)
if not isreg:
for i in range(len(wx[1])):
if query in wx[1][i]:
rv = numpy.logical_or(rv, numpy.equal(wx[0], i))
else:
r = re.compile(query)
for i in range(len(wx[1])):
m = r.match(wx[1][i])
if m is not None:
rv = numpy.logical_or(rv, numpy.equal(wx[0], i))
return rv
# Helper For wxcontains checks a subkey field
def _cf(self, f, lst):
return len(lst) == 0 or f in lst
def wxcontains(self, wx, cov=[], type=[], inten=[], vis=[], att=[]):
rv = numpy.zeros(wx[0].shape, dtype=bool)
key = wx[1]
for index in range(len(key)):
skeys = key[index].split('^')
for sk in skeys:
c, t, i, v, a = sk.split(":")
if self._cf(c, cov) and self._cf(t, type) \
and self._cf(i, inten) and self._cf(v, vis) \
and self._cf(a, att):
rv = numpy.logical_or(rv, numpy.equal(wx[0], index))
break
return rv
def contains(self, wx, keys, delim='^'):
rv = numpy.zeros(wx[0].shape, dtype=bool)
for i in range(len(wx[1])):
for k in wx[1][i].split(delim):
if k in keys:
rv = numpy.logical_or(rv, numpy.equal(wx[0], i))
break
return rv
def __init__(self, client):
self._client = client
opmode = client.getOpMode()
if opmode == "PRACTICE":
fcst = [x for x in self._client.keys() if "_Prac_Fcst_" in x]
elif opmode == "TEST":
fcst = [x for x in self._client.keys() if "_Test_Fcst_" in x]
else:
fcst = [x for x in self._client.keys() if "__Fcst_" in x]
if len(fcst) == 0:
self._fcst = {}
else:
self._fcst = self._client[fcst[0]]
self._time = time.time()
def eval(self, queryStr):
timer = TimeUtil.getTimer()
timer.start()
co, glob, loc = self.getEval(queryStr)
area = eval(co, glob, loc)
timer.stop()
PERF_LOG.logDuration("Executing edit area query [" + queryStr + "]", timer.getElapsedTime())
return area
def getTime(self):
return self._time
def setTime(self, time):
self._time = time
def getCode(self, str):
co = compile(str, "<query>", "eval")
return co, co.co_names
def getGrid(self, we):
times = list(we.keys())
times = list(filter(lambda x,t=self._time : t >= x[0] and t < x[1], times))
try:
return we[times[0]]
except IndexError:
raise IndexError("NO GRID FOR: " + we.parmName + " at time: "
+ time.ctime(self.getTime()))
def getParm(self, name):
# Attempt to find a parm in all of the databases.
sid = self._client.siteIDs[0]
dbs = sorted(self._client.keys(), reverse=True)
for db in dbs:
for p in self._client[db]:
# exact match
ename = p + "_" + db
if ename == name:
return self._client[db][p]
# SITEID_GRID_ omitted
gname = p + '_' + re.sub(sid + "_GRID_", "", db)
if gname == name:
return self._client[db][p]
# Time specifier omited (use most recent
elif re.sub(r"_\d{8}_\d{4}\Z", "", ename) == name:
return self._client[db][p]
# Both GRID and time omited
elif re.sub(r"_\d{8}_\d{4}\Z", "", gname) == name:
return self._client[db][p]
return None
def getLocals(self, names):
rval = {}
rval['mask'] = self.mask
rval['wxcontains'] = self.wxcontains
rval['contains'] = self.contains
fcstParms = self._fcst.keys()
editAreas = self._client.editAreaNames()
timer = TimeUtil.getTimer()
for name in names:
timer.reset()
timer.start()
if name in fcstParms:
rval[name] = self.getGrid(self._fcst[name])
timer.stop()
PERF_LOG.logDuration("Retrieving grid for Parm [" + name + "]", timer.getElapsedTime())
elif name + "_SFC" in fcstParms:
rval[name] = self.getGrid(self._fcst[name + "_SFC"])
timer.stop()
PERF_LOG.logDuration("Retrieving grid for Parm [" + name + "_SFC]", timer.getElapsedTime())
elif name in editAreas:
ea = self._client.getEditArea(name)
if type(ea) == type(""):
ea = self.eval(ea)
rval[name] = ea
timer.stop()
PERF_LOG.logDuration("Retrieving edit area [" + name + "]", timer.getElapsedTime())
elif name.lower() == 'topo':
rval[name] = self._client.getTopo()
timer.stop()
PERF_LOG.logDuration("Retrieving topo grid", timer.getElapsedTime())
else:
tmp = self.getParm(name)
if tmp is not None:
rval[name] = self.getGrid(tmp)
timer.stop()
PERF_LOG.logDuration("Retrieving grid for Parm [" + name + "]", timer.getElapsedTime())
return rval
def willRecurse(self, name, str):
co, names = self.getCode(str)
editAreas = list(filter(lambda x,y=names: x in y,
self._client.editAreaNames()))
if name in editAreas:
return 1
return 0
def getEval(self, queryStr):
timer = TimeUtil.getTimer()
timer.start()
co, names = self.getCode(queryStr)
timer.stop()
PERF_LOG.logDuration("Compiling edit area query [" + queryStr + "]", timer.getElapsedTime())
timer.reset()
timer.start()
loc = self.getLocals(names)
timer.stop()
PERF_LOG.logDuration("Retrieving local variables for edit area query [" + queryStr + "]", timer.getElapsedTime())
timer.reset()
timer.start()
glob = copy.copy(getattr(numpy, '__dict__'))
timer.stop()
PERF_LOG.logDuration("Creating global variables for edit area query [" + queryStr + "]", timer.getElapsedTime())
return co, glob, loc