OB_14.1.1-21 baseline
Former-commit-id:29681c7ca4
[formerly d220320ed3c6e9a0fe9fe26d83dd71eec6eafa0b] Former-commit-id:1d92e5bab6
This commit is contained in:
parent
b2401d2f0d
commit
271ec85c0c
6 changed files with 458 additions and 383 deletions
|
@ -1,61 +1,70 @@
|
||||||
##
|
##
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
# This software was developed and / or modified by Raytheon Company,
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
#
|
#
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
# This software product contains export-restricted data whose
|
# This software product contains export-restricted data whose
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
# to non-U.S. persons whether in the United States or abroad requires
|
||||||
# an export license or other authorization.
|
# an export license or other authorization.
|
||||||
#
|
#
|
||||||
# Contractor Name: Raytheon Company
|
# Contractor Name: Raytheon Company
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
# Contractor Address: 6825 Pine Street, Suite 340
|
||||||
# Mail Stop B8
|
# Mail Stop B8
|
||||||
# Omaha, NE 68106
|
# Omaha, NE 68106
|
||||||
# 402.291.0100
|
# 402.291.0100
|
||||||
#
|
#
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
# further licensing information.
|
# further licensing information.
|
||||||
##
|
##
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# This software is in the public domain, furnished "as is", without technical
|
# This software is in the public domain, furnished "as is", without technical
|
||||||
# support, and with no warranty, express or implied, as to its usefulness for
|
# support, and with no warranty, express or implied, as to its usefulness for
|
||||||
# any purpose.
|
# any purpose.
|
||||||
#
|
#
|
||||||
# MergeHazards
|
# MergeHazards
|
||||||
#
|
#
|
||||||
# Author: lefebvre
|
# Author: lefebvre
|
||||||
#
|
#
|
||||||
# This procedure reads all of the temporary hazard grids and selectively
|
# This procedure reads all of the temporary hazard grids and selectively
|
||||||
# loads them in the the "Hazards" grid.
|
# loads them in the the "Hazards" grid.
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
# The MenuItems list defines the GFE menu item(s) under which the
|
# SOFTWARE HISTORY
|
||||||
# Procedure is to appear.
|
#
|
||||||
# Possible items are: Populate, Edit, Consistency, Verify, Hazards
|
# Date Ticket# Engineer Description
|
||||||
MenuItems = ["Hazards"]
|
# ------------ ---------- ----------- --------------------------
|
||||||
|
# Dec 23, 2013 16893 ryu Check in njensen's change to removeTempHazards()
|
||||||
#import Tkinter
|
# to call SmartScript.unloadWEs().
|
||||||
import SmartScript
|
#
|
||||||
import string
|
########################################################################
|
||||||
import HazardUtils
|
|
||||||
import VTECTable
|
# The MenuItems list defines the GFE menu item(s) under which the
|
||||||
import LogStream
|
# Procedure is to appear.
|
||||||
import numpy
|
# Possible items are: Populate, Edit, Consistency, Verify, Hazards
|
||||||
from MessageBox import MessageBox
|
MenuItems = ["Hazards"]
|
||||||
|
|
||||||
from HazardUtils import MODEL
|
#import Tkinter
|
||||||
from HazardUtils import ELEMENT
|
import SmartScript
|
||||||
from HazardUtils import LEVEL
|
import string
|
||||||
|
import HazardUtils
|
||||||
######################### CONFIGURATION SECTION ######################
|
import VTECTable
|
||||||
#
|
import LogStream
|
||||||
# This dictionary defines which hazards cannot be combined with other
|
import numpy
|
||||||
# Hazards. The structure lists each hazard in the VTECTable followed
|
from MessageBox import MessageBox
|
||||||
# by a list of VTEC codes that may not be combined with it at the same
|
|
||||||
# grid point. For example "DS.W" : ["DU.Y"] means that DS.W may not
|
from HazardUtils import MODEL
|
||||||
# be combined with a DU.Y hazard at the same grid point.
|
from HazardUtils import ELEMENT
|
||||||
|
from HazardUtils import LEVEL
|
||||||
|
|
||||||
|
######################### CONFIGURATION SECTION ######################
|
||||||
|
#
|
||||||
|
# This dictionary defines which hazards cannot be combined with other
|
||||||
|
# Hazards. The structure lists each hazard in the VTECTable followed
|
||||||
|
# by a list of VTEC codes that may not be combined with it at the same
|
||||||
|
# grid point. For example "DS.W" : ["DU.Y"] means that DS.W may not
|
||||||
|
# be combined with a DU.Y hazard at the same grid point.
|
||||||
|
|
||||||
HazardsConflictDict = {
|
HazardsConflictDict = {
|
||||||
"AF.W" : ["AF.Y"],
|
"AF.W" : ["AF.Y"],
|
||||||
"AF.Y" : ["AF.W"],
|
"AF.Y" : ["AF.W"],
|
||||||
|
@ -187,301 +196,303 @@ HazardsConflictDict = {
|
||||||
"ZR.Y" : ["BZ.A", "LE.A", "WS.A", "BZ.W", "IS.W", "WS.W", "LE.W",
|
"ZR.Y" : ["BZ.A", "LE.A", "WS.A", "BZ.W", "IS.W", "WS.W", "LE.W",
|
||||||
"WW.Y", "LE.Y"],
|
"WW.Y", "LE.Y"],
|
||||||
}
|
}
|
||||||
|
|
||||||
########################## END OF CONFIGURATION SECTION ########################
|
########################## END OF CONFIGURATION SECTION ########################
|
||||||
|
|
||||||
class Procedure(SmartScript.SmartScript):
|
class Procedure(SmartScript.SmartScript):
|
||||||
def __init__(self, dbss):
|
def __init__(self, dbss):
|
||||||
SmartScript.SmartScript.__init__(self, dbss)
|
SmartScript.SmartScript.__init__(self, dbss)
|
||||||
self._dbss = dbss
|
self._dbss = dbss
|
||||||
|
|
||||||
##
|
##
|
||||||
# Get the list of loaded temporary hazard parms
|
# Get the list of loaded temporary hazard parms
|
||||||
# @return: Temporary hazard parm names, i.e., ["hazAFY"]
|
# @return: Temporary hazard parm names, i.e., ["hazAFY"]
|
||||||
# @rtype: List of Strings
|
# @rtype: List of Strings
|
||||||
def getHazardParmNames(self):
|
def getHazardParmNames(self):
|
||||||
parms = self.loadedParms()
|
parms = self.loadedParms()
|
||||||
hazParms = []
|
hazParms = []
|
||||||
for weName, level, dbID in parms:
|
for weName, level, dbID in parms:
|
||||||
if string.find(weName, "haz") == 0:
|
if string.find(weName, "haz") == 0:
|
||||||
# TODO: Why is this back/forth xform needed?
|
# TODO: Why is this back/forth xform needed?
|
||||||
key = self._hazUtils._tempWENameToKey(weName)
|
key = self._hazUtils._tempWENameToKey(weName)
|
||||||
index = string.find(key, ":")
|
index = string.find(key, ":")
|
||||||
if index != -1:
|
if index != -1:
|
||||||
mkey = key[0:index]
|
mkey = key[0:index]
|
||||||
segNum = key[index+1:]
|
segNum = key[index+1:]
|
||||||
else:
|
else:
|
||||||
mkey = key
|
mkey = key
|
||||||
segNum = ""
|
segNum = ""
|
||||||
|
|
||||||
# append the hazard and a description
|
# append the hazard and a description
|
||||||
parmName = "haz" + key
|
parmName = "haz" + key
|
||||||
parmName = string.replace(parmName, ".", "")
|
parmName = string.replace(parmName, ".", "")
|
||||||
parmName = string.replace(parmName, ":", "")
|
parmName = string.replace(parmName, ":", "")
|
||||||
hazParms.append(parmName)
|
hazParms.append(parmName)
|
||||||
|
|
||||||
return hazParms
|
return hazParms
|
||||||
|
|
||||||
##
|
##
|
||||||
# Unload (delete) all the temporary hazards
|
# Unload (delete) all the temporary hazards
|
||||||
def removeTempHazards(self):
|
def removeTempHazards(self):
|
||||||
parms = self.loadedParms()
|
parms = self.loadedParms()
|
||||||
|
|
||||||
for weName, level, dbID in parms:
|
toRemovePairs = []
|
||||||
if string.find(weName, "haz") == 0:
|
for weName, level, dbID in parms:
|
||||||
self.unloadWE(MODEL, weName, level)
|
if string.find(weName, "haz") == 0:
|
||||||
|
toRemovePairs.append((weName, level))
|
||||||
return
|
self.unloadWEs(MODEL, toRemovePairs)
|
||||||
|
|
||||||
##
|
return
|
||||||
# The action performed when the user opts to cancel a merge.
|
|
||||||
# This was a callback under Tcl/tk; now displayDialog invokes
|
##
|
||||||
# it directly.
|
# The action performed when the user opts to cancel a merge.
|
||||||
def cancelCommand(self):
|
# This was a callback under Tcl/tk; now displayDialog invokes
|
||||||
LogStream.logEvent("MergeHazards: cancel")
|
# it directly.
|
||||||
return
|
def cancelCommand(self):
|
||||||
|
LogStream.logEvent("MergeHazards: cancel")
|
||||||
##
|
return
|
||||||
# The action performed when the user opts to continue a merge.
|
|
||||||
# This was a callback under Tcl/tk; now displayDialog invokes
|
##
|
||||||
# it directly.
|
# The action performed when the user opts to continue a merge.
|
||||||
def continueCommand(self):
|
# This was a callback under Tcl/tk; now displayDialog invokes
|
||||||
LogStream.logEvent("MergeHazards: continue")
|
# it directly.
|
||||||
parm = self.getParm(MODEL, ELEMENT, LEVEL)
|
def continueCommand(self):
|
||||||
parm.setMutable(True)
|
LogStream.logEvent("MergeHazards: continue")
|
||||||
self.mergeHazardGrids()
|
parm = self.getParm(MODEL, ELEMENT, LEVEL)
|
||||||
return
|
parm.setMutable(True)
|
||||||
|
self.mergeHazardGrids()
|
||||||
##
|
return
|
||||||
# Displays a dialog box and queries the user to continue to merge or
|
|
||||||
# abort the merge
|
##
|
||||||
def displayDialog(self, message):
|
# Displays a dialog box and queries the user to continue to merge or
|
||||||
messageBox = MessageBox(style=MessageBox.ICON_WARNING)
|
# abort the merge
|
||||||
messageBox.setText("MakeHazard")
|
def displayDialog(self, message):
|
||||||
messageBox.setMessage(message)
|
messageBox = MessageBox(style=MessageBox.ICON_WARNING)
|
||||||
messageBox.setButtonLabels(["Continue Merge", "Cancel Merge"])
|
messageBox.setText("MakeHazard")
|
||||||
messageBox.setDefaultIndex(1)
|
messageBox.setMessage(message)
|
||||||
if (messageBox.open() == 0):
|
messageBox.setButtonLabels(["Continue Merge", "Cancel Merge"])
|
||||||
self.continueCommand()
|
messageBox.setDefaultIndex(1)
|
||||||
else:
|
if (messageBox.open() == 0):
|
||||||
self.cancelCommand()
|
self.continueCommand()
|
||||||
|
else:
|
||||||
return
|
self.cancelCommand()
|
||||||
|
|
||||||
##
|
return
|
||||||
# Returns the set of hazParms grids that overlap with the specified
|
|
||||||
# timeRange.
|
##
|
||||||
# @param hazParms: Hazard parm names to check
|
# Returns the set of hazParms grids that overlap with the specified
|
||||||
# @type hazParms: Sequence of string
|
# timeRange.
|
||||||
# @param timeRange: The time range to check for overlap with
|
# @param hazParms: Hazard parm names to check
|
||||||
# @type timeRange: Python TimeRange
|
# @type hazParms: Sequence of string
|
||||||
# @return: Byte grids and keys of the overlapping parms
|
# @param timeRange: The time range to check for overlap with
|
||||||
# @rtype: 2-tuple: list of byte arrays, list of list of strings
|
# @type timeRange: Python TimeRange
|
||||||
def getOverlappingHazGrids(self, hazParms, timeRange):
|
# @return: Byte grids and keys of the overlapping parms
|
||||||
byteGridList = []
|
# @rtype: 2-tuple: list of byte arrays, list of list of strings
|
||||||
keyList = []
|
def getOverlappingHazGrids(self, hazParms, timeRange):
|
||||||
for hazParm in hazParms:
|
byteGridList = []
|
||||||
trList = self._hazUtils._getWEInventory(hazParm)
|
keyList = []
|
||||||
for tr in trList:
|
for hazParm in hazParms:
|
||||||
if tr.overlaps(timeRange):
|
trList = self._hazUtils._getWEInventory(hazParm)
|
||||||
byteGrid, hazKey = self.getGrids(MODEL, hazParm, LEVEL,
|
for tr in trList:
|
||||||
tr, mode="First")
|
if tr.overlaps(timeRange):
|
||||||
if isinstance(hazKey, str):
|
byteGrid, hazKey = self.getGrids(MODEL, hazParm, LEVEL,
|
||||||
hazKey = eval(hazKey)
|
tr, mode="First")
|
||||||
byteGridList.append(byteGrid)
|
if isinstance(hazKey, str):
|
||||||
keyList.append(hazKey)
|
hazKey = eval(hazKey)
|
||||||
|
byteGridList.append(byteGrid)
|
||||||
return byteGridList, keyList
|
keyList.append(hazKey)
|
||||||
|
|
||||||
##
|
return byteGridList, keyList
|
||||||
# Returns the first non-None key it finds in the keyList
|
|
||||||
# @param keyList: Keys to search
|
##
|
||||||
# @type keyList: Sequence of string
|
# Returns the first non-None key it finds in the keyList
|
||||||
# @return: First key that is not "<None>"
|
# @param keyList: Keys to search
|
||||||
# @rtype: string
|
# @type keyList: Sequence of string
|
||||||
def getHazardKey(self, keyList):
|
# @return: First key that is not "<None>"
|
||||||
for k in keyList:
|
# @rtype: string
|
||||||
if k != "<None>":
|
def getHazardKey(self, keyList):
|
||||||
return k
|
for k in keyList:
|
||||||
|
if k != "<None>":
|
||||||
##
|
return k
|
||||||
# Checks the specified hazard grids to see if they are conflicting
|
|
||||||
# Each grid is a tuple (byteGrid, key). Uses the configurable
|
##
|
||||||
# HazardConflictDict to determine whether two hazards can be combined
|
# Checks the specified hazard grids to see if they are conflicting
|
||||||
# at the same grid point. Returns an empty list if no conflict or
|
# Each grid is a tuple (byteGrid, key). Uses the configurable
|
||||||
# the list of hazards if they do.
|
# HazardConflictDict to determine whether two hazards can be combined
|
||||||
#
|
# at the same grid point. Returns an empty list if no conflict or
|
||||||
# This method should really only be used internally; it assumes that
|
# the list of hazards if they do.
|
||||||
# there is at most one key other than "<None>", and that it contains
|
#
|
||||||
# a single subkey.
|
# This method should really only be used internally; it assumes that
|
||||||
#
|
# there is at most one key other than "<None>", and that it contains
|
||||||
# @param hazGrid1: The first hazard grid
|
# a single subkey.
|
||||||
# @type hazGrid1: 2-tuple: numpy array of int8, list of String
|
#
|
||||||
# @param hazGrid2: The second hazard grid
|
# @param hazGrid1: The first hazard grid
|
||||||
# @type hazGrid2: 2-tuple: numpy array of int8, list of String
|
# @type hazGrid1: 2-tuple: numpy array of int8, list of String
|
||||||
# @return: conflicting hazard names or empty list
|
# @param hazGrid2: The second hazard grid
|
||||||
# @rtype: list
|
# @type hazGrid2: 2-tuple: numpy array of int8, list of String
|
||||||
def conflictingHazards(self, hazGrid1, hazGrid2):
|
# @return: conflicting hazard names or empty list
|
||||||
byteGrid1, hazKey1 = hazGrid1
|
# @rtype: list
|
||||||
byteGrid2, hazKey2 = hazGrid2
|
def conflictingHazards(self, hazGrid1, hazGrid2):
|
||||||
|
byteGrid1, hazKey1 = hazGrid1
|
||||||
key1 = self.getHazardKey(hazKey1)
|
byteGrid2, hazKey2 = hazGrid2
|
||||||
key2 = self.getHazardKey(hazKey2)
|
|
||||||
phenSig1 = key1[0:4] # remove the etn
|
key1 = self.getHazardKey(hazKey1)
|
||||||
phenSig2 = key2[0:4]
|
key2 = self.getHazardKey(hazKey2)
|
||||||
|
phenSig1 = key1[0:4] # remove the etn
|
||||||
keyConflict = False
|
phenSig2 = key2[0:4]
|
||||||
if phenSig1 == phenSig2 and key1 != key2:
|
|
||||||
keyConflict = True
|
keyConflict = False
|
||||||
elif HazardsConflictDict.has_key(phenSig1):
|
if phenSig1 == phenSig2 and key1 != key2:
|
||||||
if phenSig2 in HazardsConflictDict[phenSig1]:
|
keyConflict = True
|
||||||
keyConflict = True
|
elif HazardsConflictDict.has_key(phenSig1):
|
||||||
|
if phenSig2 in HazardsConflictDict[phenSig1]:
|
||||||
if keyConflict:
|
keyConflict = True
|
||||||
# calculate the overlap, adding the grids together will tell us if
|
|
||||||
# there is any overlap. Any grid points > 1 are overlapped
|
if keyConflict:
|
||||||
totalGrid = byteGrid1 + byteGrid2
|
# calculate the overlap, adding the grids together will tell us if
|
||||||
overlapMask = numpy.greater(totalGrid, 1)
|
# there is any overlap. Any grid points > 1 are overlapped
|
||||||
if numpy.any(overlapMask):
|
totalGrid = byteGrid1 + byteGrid2
|
||||||
return [key1, key2]
|
overlapMask = numpy.greater(totalGrid, 1)
|
||||||
|
if numpy.any(overlapMask):
|
||||||
return []
|
return [key1, key2]
|
||||||
|
|
||||||
##
|
return []
|
||||||
# See if there are any temporary hazards for the same position and time
|
|
||||||
# that conflict with one another.
|
##
|
||||||
#
|
# See if there are any temporary hazards for the same position and time
|
||||||
# @param hazParms: Temporary hazard parm names to check.
|
# that conflict with one another.
|
||||||
# @type hazParms: sequence of string
|
#
|
||||||
# @return: The first conflict, or None if there are no conflicts
|
# @param hazParms: Temporary hazard parm names to check.
|
||||||
# @rtype: 2-tuple(TimeRange, list of string) or NoneType
|
# @type hazParms: sequence of string
|
||||||
def checkForHazardConflicts(self, hazParms):
|
# @return: The first conflict, or None if there are no conflicts
|
||||||
timeList = []
|
# @rtype: 2-tuple(TimeRange, list of string) or NoneType
|
||||||
for hazParm in hazParms:
|
def checkForHazardConflicts(self, hazParms):
|
||||||
trList = self._hazUtils._getWEInventory(hazParm)
|
timeList = []
|
||||||
for tr in trList:
|
for hazParm in hazParms:
|
||||||
if tr.startTime().unixTime() not in timeList:
|
trList = self._hazUtils._getWEInventory(hazParm)
|
||||||
timeList.append(tr.startTime().unixTime())
|
for tr in trList:
|
||||||
if tr.endTime().unixTime() not in timeList:
|
if tr.startTime().unixTime() not in timeList:
|
||||||
timeList.append(tr.endTime().unixTime())
|
timeList.append(tr.startTime().unixTime())
|
||||||
|
if tr.endTime().unixTime() not in timeList:
|
||||||
timeList.sort() # sort the list
|
timeList.append(tr.endTime().unixTime())
|
||||||
|
|
||||||
for t in xrange(len(timeList) - 1):
|
timeList.sort() # sort the list
|
||||||
start = timeList[t]
|
|
||||||
end = timeList[t+1]
|
for t in xrange(len(timeList) - 1):
|
||||||
timeRange = self._hazUtils._makeTimeRange(start, end)
|
start = timeList[t]
|
||||||
byteGridList = []
|
end = timeList[t+1]
|
||||||
keyList = []
|
timeRange = self._hazUtils._makeTimeRange(start, end)
|
||||||
byteGridList, keyList = self.getOverlappingHazGrids(hazParms, timeRange)
|
byteGridList = []
|
||||||
# compare each grid to all other grids at this timeRange
|
keyList = []
|
||||||
for firstIndex in xrange(len(byteGridList) - 1):
|
byteGridList, keyList = self.getOverlappingHazGrids(hazParms, timeRange)
|
||||||
for secondIndex in xrange(firstIndex + 1, len(byteGridList)):
|
# compare each grid to all other grids at this timeRange
|
||||||
grid1 = (byteGridList[firstIndex], keyList[firstIndex])
|
for firstIndex in xrange(len(byteGridList) - 1):
|
||||||
grid2 = (byteGridList[secondIndex], keyList[secondIndex])
|
for secondIndex in xrange(firstIndex + 1, len(byteGridList)):
|
||||||
conflictList = self.conflictingHazards(grid1, grid2)
|
grid1 = (byteGridList[firstIndex], keyList[firstIndex])
|
||||||
if conflictList != []:
|
grid2 = (byteGridList[secondIndex], keyList[secondIndex])
|
||||||
return (timeRange, conflictList)
|
conflictList = self.conflictingHazards(grid1, grid2)
|
||||||
|
if conflictList != []:
|
||||||
# if we made it to here, all is well
|
return (timeRange, conflictList)
|
||||||
return None
|
|
||||||
|
# if we made it to here, all is well
|
||||||
##
|
return None
|
||||||
# Perform checks to see if it's OK to merge hazards. If there are no conflicting
|
|
||||||
# locks or incompatible hazards, do the merge. If there are conflicting locks,
|
##
|
||||||
# generate a status bar message and quit. If there incompatible
|
# Perform checks to see if it's OK to merge hazards. If there are no conflicting
|
||||||
# hazards, show a warning and let the user decide whether to continue.
|
# locks or incompatible hazards, do the merge. If there are conflicting locks,
|
||||||
def checkForMerge(self):
|
# generate a status bar message and quit. If there incompatible
|
||||||
# get the hazards selected by the forecaster
|
# hazards, show a warning and let the user decide whether to continue.
|
||||||
hazParms = self.getHazardParmNames()
|
def checkForMerge(self):
|
||||||
|
# get the hazards selected by the forecaster
|
||||||
# check for empty list of hazards
|
hazParms = self.getHazardParmNames()
|
||||||
if hazParms == []:
|
|
||||||
self.statusBarMsg("No temporary grids to merge.", "S")
|
# check for empty list of hazards
|
||||||
return
|
if hazParms == []:
|
||||||
|
self.statusBarMsg("No temporary grids to merge.", "S")
|
||||||
# FIXME: Lock race condition
|
return
|
||||||
# check for conflicting locks
|
|
||||||
if self._hazUtils._conflictingLocks(hazParms):
|
# FIXME: Lock race condition
|
||||||
self.statusBarMsg("There are conflicting locks. " +
|
# check for conflicting locks
|
||||||
"Please resolve these before merging any hazards", "S")
|
if self._hazUtils._conflictingLocks(hazParms):
|
||||||
return
|
self.statusBarMsg("There are conflicting locks. " +
|
||||||
|
"Please resolve these before merging any hazards", "S")
|
||||||
conflicts = self.checkForHazardConflicts(hazParms)
|
return
|
||||||
if conflicts is None:
|
|
||||||
# if no conflicts, merge the grids
|
conflicts = self.checkForHazardConflicts(hazParms)
|
||||||
# We made the hazards parm immutable when we separated hazard grids.
|
if conflicts is None:
|
||||||
# It has to be made mutable to do the merge.
|
# if no conflicts, merge the grids
|
||||||
parm = self.getParm(MODEL, ELEMENT, LEVEL)
|
# We made the hazards parm immutable when we separated hazard grids.
|
||||||
parm.setMutable(True)
|
# It has to be made mutable to do the merge.
|
||||||
self.mergeHazardGrids()
|
parm = self.getParm(MODEL, ELEMENT, LEVEL)
|
||||||
else:
|
parm.setMutable(True)
|
||||||
haz1 = string.replace(conflicts[1][0], ".", "")
|
self.mergeHazardGrids()
|
||||||
haz2 = string.replace(conflicts[1][1], ".", "")
|
else:
|
||||||
timeRange = str(conflicts[0])
|
haz1 = string.replace(conflicts[1][0], ".", "")
|
||||||
msg = "Hazard conflict detected!\n\n"
|
haz2 = string.replace(conflicts[1][1], ".", "")
|
||||||
msg += "Time: " + timeRange + " \n\n"
|
timeRange = str(conflicts[0])
|
||||||
msg += "with Hazard grids haz" + haz1 + " and haz" + haz2 + ".\n"
|
msg = "Hazard conflict detected!\n\n"
|
||||||
|
msg += "Time: " + timeRange + " \n\n"
|
||||||
LogStream.logEvent("Merge conflict: "+ msg)
|
msg += "with Hazard grids haz" + haz1 + " and haz" + haz2 + ".\n"
|
||||||
self.displayDialog(msg)
|
|
||||||
|
LogStream.logEvent("Merge conflict: "+ msg)
|
||||||
return
|
self.displayDialog(msg)
|
||||||
|
|
||||||
##
|
return
|
||||||
# Performs the actual merge of the temp hazards grids into the "Hazards" grid.
|
|
||||||
def mergeHazardGrids(self):
|
##
|
||||||
# get the hazards selected by the forecaster
|
# Performs the actual merge of the temp hazards grids into the "Hazards" grid.
|
||||||
hazParms = self.getHazardParmNames()
|
def mergeHazardGrids(self):
|
||||||
|
# get the hazards selected by the forecaster
|
||||||
self._hazUtils._removeAllHazardsGrids()
|
hazParms = self.getHazardParmNames()
|
||||||
|
|
||||||
for hazParm in hazParms:
|
self._hazUtils._removeAllHazardsGrids()
|
||||||
trList = self._hazUtils._getWEInventory(hazParm)
|
|
||||||
|
for hazParm in hazParms:
|
||||||
for tr in trList:
|
trList = self._hazUtils._getWEInventory(hazParm)
|
||||||
byteGrid, hazKey = self.getGrids(MODEL, hazParm, LEVEL, tr,
|
|
||||||
mode="First")
|
for tr in trList:
|
||||||
if isinstance(hazKey, str):
|
byteGrid, hazKey = self.getGrids(MODEL, hazParm, LEVEL, tr,
|
||||||
hazKey = eval(hazKey)
|
mode="First")
|
||||||
|
if isinstance(hazKey, str):
|
||||||
uniqueKeys = self._hazUtils._getUniqueKeys(byteGrid, hazKey)
|
hazKey = eval(hazKey)
|
||||||
for uKey in uniqueKeys:
|
|
||||||
if uKey == "<None>":
|
uniqueKeys = self._hazUtils._getUniqueKeys(byteGrid, hazKey)
|
||||||
continue
|
for uKey in uniqueKeys:
|
||||||
subKeys = self._hazUtils._getSubKeys(uKey)
|
if uKey == "<None>":
|
||||||
for subKey in subKeys:
|
continue
|
||||||
# make the mask - find all areas that contain the subKey
|
subKeys = self._hazUtils._getSubKeys(uKey)
|
||||||
mask = numpy.zeros(byteGrid.shape)
|
for subKey in subKeys:
|
||||||
for haz in hazKey:
|
# make the mask - find all areas that contain the subKey
|
||||||
if string.find(haz, subKey) >= 0:
|
mask = numpy.zeros(byteGrid.shape)
|
||||||
hazIndex = self.getIndex(haz, hazKey)
|
for haz in hazKey:
|
||||||
mask = numpy.logical_or(numpy.equal(byteGrid, hazIndex), mask)
|
if string.find(haz, subKey) >= 0:
|
||||||
|
hazIndex = self.getIndex(haz, hazKey)
|
||||||
# make the grid
|
mask = numpy.logical_or(numpy.equal(byteGrid, hazIndex), mask)
|
||||||
self._hazUtils._addHazard(ELEMENT, tr, subKey, mask)
|
|
||||||
LogStream.logEvent("merge: " + \
|
# make the grid
|
||||||
str(self._hazUtils._printTime(tr.startTime().unixTime())) + " " + \
|
self._hazUtils._addHazard(ELEMENT, tr, subKey, mask)
|
||||||
str(self._hazUtils._printTime(tr.endTime().unixTime())) + " " + \
|
LogStream.logEvent("merge: " + \
|
||||||
subKey + "\n")
|
str(self._hazUtils._printTime(tr.startTime().unixTime())) + " " + \
|
||||||
|
str(self._hazUtils._printTime(tr.endTime().unixTime())) + " " + \
|
||||||
self.removeTempHazards()
|
subKey + "\n")
|
||||||
|
|
||||||
return
|
self.removeTempHazards()
|
||||||
|
|
||||||
##
|
return
|
||||||
# The main entry point of the procedure.
|
|
||||||
def execute(self):
|
##
|
||||||
self.setToolType("numeric")
|
# The main entry point of the procedure.
|
||||||
|
def execute(self):
|
||||||
self._hazUtils = HazardUtils.HazardUtils(self._dbss, None)
|
self.setToolType("numeric")
|
||||||
|
|
||||||
# see if the Hazards WE is loaded in the GFE, if not abort the tool
|
self._hazUtils = HazardUtils.HazardUtils(self._dbss, None)
|
||||||
if not self._hazUtils._hazardsLoaded():
|
|
||||||
self.statusBarMsg("Hazards Weather Element must be loaded in " +\
|
# see if the Hazards WE is loaded in the GFE, if not abort the tool
|
||||||
"the GFE before running MergeHazards", "S")
|
if not self._hazUtils._hazardsLoaded():
|
||||||
self.cancel()
|
self.statusBarMsg("Hazards Weather Element must be loaded in " +\
|
||||||
|
"the GFE before running MergeHazards", "S")
|
||||||
self.checkForMerge()
|
self.cancel()
|
||||||
return
|
|
||||||
|
self.checkForMerge()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
# Jun 21, 2013 14983 ryu Fixed encodeEditArea() to evaluate query
|
# Jun 21, 2013 14983 ryu Fixed encodeEditArea() to evaluate query
|
||||||
# when necessary
|
# when necessary
|
||||||
# Oct 07, 2013 2424 randerso remove use of pytz
|
# Oct 07, 2013 2424 randerso remove use of pytz
|
||||||
|
# Dec 23, 2013 16893 ryu Added unloadWEs() method (created by njensen)
|
||||||
#
|
#
|
||||||
########################################################################
|
########################################################################
|
||||||
import types, string, time, sys
|
import types, string, time, sys
|
||||||
|
@ -1788,6 +1789,19 @@ class SmartScript(BaseTool.BaseTool):
|
||||||
parmJA[0] = parm
|
parmJA[0] = parm
|
||||||
self.__parmMgr.deleteParm(parmJA)
|
self.__parmMgr.deleteParm(parmJA)
|
||||||
|
|
||||||
|
def unloadWEs(self, model, elementLevelPairs, mostRecent=0):
|
||||||
|
jparms = []
|
||||||
|
for element, level in elementLevelPairs:
|
||||||
|
exprName = self.getExprName(model, element, level, mostRecent)
|
||||||
|
parm = self.__parmMgr.getParmInExpr(exprName, 1)
|
||||||
|
if parm:
|
||||||
|
jparms.append(parm)
|
||||||
|
if jparms:
|
||||||
|
parmJA = jep.jarray(len(jparms), jparms[0])
|
||||||
|
for i in xrange(len(jparms)):
|
||||||
|
parmJA[i] = jparms[i]
|
||||||
|
self.__parmMgr.deleteParm(parmJA)
|
||||||
|
|
||||||
def saveElements(self, elementList):
|
def saveElements(self, elementList):
|
||||||
# Save the given Fcst elements to the server
|
# Save the given Fcst elements to the server
|
||||||
# Example:
|
# Example:
|
||||||
|
|
|
@ -86,6 +86,7 @@
|
||||||
<exclude>.*datadelivery.*</exclude>
|
<exclude>.*datadelivery.*</exclude>
|
||||||
<exclude>.*bandwidth.*</exclude>
|
<exclude>.*bandwidth.*</exclude>
|
||||||
<includeMode>excludeDpaAndOgc</includeMode>
|
<includeMode>excludeDpaAndOgc</includeMode>
|
||||||
|
<exclude>obs-ingest-metarshef.xml</exclude>
|
||||||
<!-- ncep excludes until tested -->
|
<!-- ncep excludes until tested -->
|
||||||
<exclude>aww-ingest.xml</exclude>
|
<exclude>aww-ingest.xml</exclude>
|
||||||
<exclude>ncairep-ingest.xml</exclude>
|
<exclude>ncairep-ingest.xml</exclude>
|
||||||
|
@ -120,7 +121,8 @@
|
||||||
<include>shef-ingest.xml</include>
|
<include>shef-ingest.xml</include>
|
||||||
<include>persist-ingest.xml</include>
|
<include>persist-ingest.xml</include>
|
||||||
<include>obs-common.xml</include>
|
<include>obs-common.xml</include>
|
||||||
<include>obs-ingest.xml</include>
|
<include>obs-ingest.xml</include>
|
||||||
|
<include>obs-ingest-metarshef.xml</include>
|
||||||
<include>metartohmdb-plugin.xml</include>
|
<include>metartohmdb-plugin.xml</include>
|
||||||
<include>pointdata-common.xml</include>
|
<include>pointdata-common.xml</include>
|
||||||
<include>shef-common.xml</include>
|
<include>shef-common.xml</include>
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<beans
|
||||||
|
xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||||
|
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||||
|
|
||||||
|
<bean id="obsCamelRegistered" factory-bean="contextManager" factory-method="register"
|
||||||
|
depends-on="persistCamelRegistered,
|
||||||
|
shefCamelRegistered,
|
||||||
|
metarToHMDBCamelRegistered">
|
||||||
|
<constructor-arg ref="obs-camel" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<camelContext id="obs-camel" xmlns="http://camel.apache.org/schema/spring"
|
||||||
|
errorHandlerRef="errorHandler" autoStartup="false">
|
||||||
|
|
||||||
|
<!-- Begin METAR routes -->
|
||||||
|
<route id="metarIngestRoute">
|
||||||
|
<from uri="jms-durable:queue:Ingest.obs" />
|
||||||
|
<setHeader headerName="pluginName">
|
||||||
|
<constant>obs</constant>
|
||||||
|
</setHeader>
|
||||||
|
<doTry>
|
||||||
|
<pipeline>
|
||||||
|
<bean ref="stringToFile" />
|
||||||
|
<bean ref="obsDecoder" method="decode" />
|
||||||
|
<bean ref="dupElim" />
|
||||||
|
<bean ref="metarPointData" method="toPointData" />
|
||||||
|
<multicast>
|
||||||
|
<to uri="direct-vm:persistIndexAlert" />
|
||||||
|
<to uri="direct-vm:metarToShef" />
|
||||||
|
<to uri="direct-vm:metarToHMDB" />
|
||||||
|
</multicast>
|
||||||
|
</pipeline>
|
||||||
|
<doCatch>
|
||||||
|
<exception>java.lang.Throwable</exception>
|
||||||
|
<to uri="log:metar?level=ERROR" />
|
||||||
|
</doCatch>
|
||||||
|
</doTry>
|
||||||
|
</route>
|
||||||
|
</camelContext>
|
||||||
|
</beans>
|
|
@ -0,0 +1,41 @@
|
||||||
|
<beans
|
||||||
|
xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||||
|
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||||
|
|
||||||
|
<!-- This spring configuration is currently only used by the ingestHydro EDEX instance. -->
|
||||||
|
|
||||||
|
<bean id="obsCamelRegistered" factory-bean="contextManager" factory-method="register"
|
||||||
|
depends-on="shefCamelRegistered,
|
||||||
|
metarToHMDBCamelRegistered">
|
||||||
|
<constructor-arg ref="obs-camel" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<camelContext id="obs-camel" xmlns="http://camel.apache.org/schema/spring"
|
||||||
|
errorHandlerRef="errorHandler" autoStartup="false">
|
||||||
|
|
||||||
|
<!-- Begin METAR routes -->
|
||||||
|
<route id="metarIngestRoute">
|
||||||
|
<from uri="jms-durable:queue:Ingest.obs" />
|
||||||
|
<setHeader headerName="pluginName">
|
||||||
|
<constant>obs</constant>
|
||||||
|
</setHeader>
|
||||||
|
<doTry>
|
||||||
|
<pipeline>
|
||||||
|
<bean ref="stringToFile" />
|
||||||
|
<bean ref="obsDecoder" method="decode" />
|
||||||
|
<bean ref="metarPointData" method="toPointData" />
|
||||||
|
<multicast>
|
||||||
|
<to uri="direct-vm:metarToShef" />
|
||||||
|
<to uri="direct-vm:metarToHMDB" />
|
||||||
|
</multicast>
|
||||||
|
</pipeline>
|
||||||
|
<doCatch>
|
||||||
|
<exception>java.lang.Throwable</exception>
|
||||||
|
<to uri="log:metar?level=ERROR" />
|
||||||
|
</doCatch>
|
||||||
|
</doTry>
|
||||||
|
</route>
|
||||||
|
</camelContext>
|
||||||
|
</beans>
|
|
@ -3,7 +3,7 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||||
|
|
||||||
<bean id="obsDecoder" class="com.raytheon.edex.plugin.obs.ObsDecoder" />
|
<bean id="obsDecoder" class="com.raytheon.edex.plugin.obs.ObsDecoder" />
|
||||||
|
|
||||||
<bean id="metarPointData" class="com.raytheon.edex.plugin.obs.metar.MetarPointDataTransform" />
|
<bean id="metarPointData" class="com.raytheon.edex.plugin.obs.metar.MetarPointDataTransform" />
|
||||||
|
@ -14,40 +14,5 @@
|
||||||
<constructor-arg value="obs" />
|
<constructor-arg value="obs" />
|
||||||
<constructor-arg value="jms-durable:queue:Ingest.obs" />
|
<constructor-arg value="jms-durable:queue:Ingest.obs" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="obsCamelRegistered" factory-bean="contextManager" factory-method="register"
|
|
||||||
depends-on="persistCamelRegistered,
|
|
||||||
shefCamelRegistered,
|
|
||||||
metarToHMDBCamelRegistered">
|
|
||||||
<constructor-arg ref="obs-camel" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<camelContext id="obs-camel" xmlns="http://camel.apache.org/schema/spring"
|
|
||||||
errorHandlerRef="errorHandler" autoStartup="false">
|
|
||||||
|
|
||||||
<!-- Begin METAR routes -->
|
|
||||||
<route id="metarIngestRoute">
|
|
||||||
<from uri="jms-durable:queue:Ingest.obs" />
|
|
||||||
<setHeader headerName="pluginName">
|
|
||||||
<constant>obs</constant>
|
|
||||||
</setHeader>
|
|
||||||
<doTry>
|
|
||||||
<pipeline>
|
|
||||||
<bean ref="stringToFile" />
|
|
||||||
<bean ref="obsDecoder" method="decode" />
|
|
||||||
<bean ref="dupElim" />
|
|
||||||
<bean ref="metarPointData" method="toPointData" />
|
|
||||||
<multicast>
|
|
||||||
<to uri="direct-vm:persistIndexAlert" />
|
|
||||||
<to uri="direct-vm:metarToShef" />
|
|
||||||
<to uri="direct-vm:metarToHMDB" />
|
|
||||||
</multicast>
|
|
||||||
</pipeline>
|
|
||||||
<doCatch>
|
|
||||||
<exception>java.lang.Throwable</exception>
|
|
||||||
<to uri="log:metar?level=ERROR" />
|
|
||||||
</doCatch>
|
|
||||||
</doTry>
|
|
||||||
</route>
|
|
||||||
</camelContext>
|
|
||||||
</beans>
|
</beans>
|
Loading…
Add table
Reference in a new issue