OB_14.1.1-21 baseline

Former-commit-id: 29681c7ca4 [formerly d220320ed3c6e9a0fe9fe26d83dd71eec6eafa0b]
Former-commit-id: 1d92e5bab6
This commit is contained in:
Brian.Dyke 2014-03-04 11:47:42 -05:00
parent b2401d2f0d
commit 271ec85c0c
6 changed files with 458 additions and 383 deletions

View file

@ -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

View file

@ -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:

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>