Change-Id: I258b2f8c8ddb7f45b02b1035f6fa5006b9fabe1b Former-commit-id: 0db3944372ecc381df4e8a918829530391d598db
This commit is contained in:
parent
d7e8bc97b6
commit
1ae8fe99aa
6 changed files with 1379 additions and 982 deletions
|
@ -67,34 +67,6 @@ class Procedure (SmartScript.SmartScript):
|
||||||
# "Downtown Miami",
|
# "Downtown Miami",
|
||||||
# ],
|
# ],
|
||||||
#
|
#
|
||||||
# # Threat statements can be overriden here; anything not overriden here
|
|
||||||
# # will use the generic threat statements
|
|
||||||
# 'threatStatements': {
|
|
||||||
# # Section name: "Wind", "Storm Surge", "Flooding Rain" or "Tornado"
|
|
||||||
# "Wind": {
|
|
||||||
# # Threat level: "None", "Low", "Mod", "High" or "Extreme"
|
|
||||||
# "Extreme": {
|
|
||||||
# # tr: "nothing to see here", "recovery", "hunker down",
|
|
||||||
# # "complete preparations" or "check plans"
|
|
||||||
# "hunker down": {
|
|
||||||
# # "Make plans: " will be prepended to this
|
|
||||||
# "planning": "For chance that wind could locally reach major " +\\
|
|
||||||
# "hurricane force; enact your emergency action plan " +\\
|
|
||||||
# "accordingly",
|
|
||||||
# # "Take action: " will be prepended to this
|
|
||||||
# "action": "For extremely dangerous and life threatening wind " +\\
|
|
||||||
# "to possibly occur; failure to act may result in " +\\
|
|
||||||
# "injury or loss of life",
|
|
||||||
# # "Prepare: " will be prepended to this
|
|
||||||
# "preparation": "Aggressively for chance of devastating to " +\\
|
|
||||||
# "catastrophic wind impacts based on threat " +\\
|
|
||||||
# "assessment that considers plausible worst " +\\
|
|
||||||
# "case scenario for safety",
|
|
||||||
# },
|
|
||||||
# },
|
|
||||||
# },
|
|
||||||
# },
|
|
||||||
#
|
|
||||||
# # Potential impacts statements can be overriden here; anything not
|
# # Potential impacts statements can be overriden here; anything not
|
||||||
# # overriden here will use the generic potential impacts statements
|
# # overriden here will use the generic potential impacts statements
|
||||||
# 'potentialImpactsStatements': {
|
# 'potentialImpactsStatements': {
|
||||||
|
@ -151,7 +123,6 @@ TCV_AreaDictionary = {
|
||||||
"""
|
"""
|
||||||
self._zoneSkeletonContents = {
|
self._zoneSkeletonContents = {
|
||||||
'locationsAffected' : [],
|
'locationsAffected' : [],
|
||||||
'threatStatements' : {},
|
|
||||||
'potentialImpactsStatements' : {},
|
'potentialImpactsStatements' : {},
|
||||||
'infoSection' : [],
|
'infoSection' : [],
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,7 @@ class TextProduct(GenericHazards.TextProduct):
|
||||||
# Set up the time range for 0-120 hours
|
# Set up the time range for 0-120 hours
|
||||||
|
|
||||||
# Create a time range from the issuanceHour out 120 hours
|
# Create a time range from the issuanceHour out 120 hours
|
||||||
startTime = self._calculateStartTime(time.localtime(self._issueTime_secs))
|
startTime = self._calculateStartTime(time.gmtime(self._issueTime_secs))
|
||||||
self._timeRange = self.makeTimeRange(startTime, startTime+120*3600)
|
self._timeRange = self.makeTimeRange(startTime, startTime+120*3600)
|
||||||
|
|
||||||
# Determine the time range list, making sure they are on hour boundaries
|
# Determine the time range list, making sure they are on hour boundaries
|
||||||
|
@ -300,21 +300,142 @@ class TextProduct(GenericHazards.TextProduct):
|
||||||
day = localCreationTime[2]
|
day = localCreationTime[2]
|
||||||
hour = localCreationTime[3]
|
hour = localCreationTime[3]
|
||||||
|
|
||||||
|
# If we are more than halfway though a 6 hr period
|
||||||
|
if hour % 6 > 3:
|
||||||
|
adjust = 6 # move on to the next 6 hr block
|
||||||
|
else:
|
||||||
|
adjust = 0
|
||||||
|
# print "MATT: _calculateStartTime %d adjust = %d" % (hour % 6, adjust)
|
||||||
|
|
||||||
# Now "truncate" to a 6-hourly boundary and compute startTime in local Time.
|
# Now "truncate" to a 6-hourly boundary and compute startTime in local Time.
|
||||||
hour = int (int(hour/6) * 6)
|
hour = int( (hour/6) * 6) + adjust
|
||||||
|
if hour > 23:
|
||||||
|
hour -= 24
|
||||||
|
elif hour < 0:
|
||||||
|
hour += 24
|
||||||
|
|
||||||
startTime = absTimeYMD(year, month, day, hour)
|
startTime = absTimeYMD(year, month, day, hour)
|
||||||
# Finally, convert back to GMT
|
|
||||||
localTime, shift = self.determineTimeShift()
|
|
||||||
startTime = startTime - shift
|
|
||||||
|
|
||||||
return startTime
|
return startTime
|
||||||
|
|
||||||
def _resolution(self):
|
def _resolution(self):
|
||||||
return 3
|
return 3
|
||||||
|
|
||||||
|
def _formatPeriod(self, period, wholePeriod=False, shiftToLocal=True, useEndTime=False,
|
||||||
|
resolution=3):
|
||||||
|
# Format period (a timeRange) resulting in
|
||||||
|
# DAY + MORNING / AFTERNOON / EVENING / OVERNIGHT.
|
||||||
|
# If wholePeriod, format FROM ... TO...
|
||||||
|
|
||||||
|
print "\nMATT Format period wholePeriod = %s, period = %s, useEndTime =%s" % (str(wholePeriod), str(period), str(useEndTime))
|
||||||
|
if period is None: return ""
|
||||||
|
if useEndTime:
|
||||||
|
startTime = period.endTime()
|
||||||
|
else:
|
||||||
|
startTime = period.startTime()
|
||||||
|
result = self._getTimeDesc(startTime, resolution, shiftToLocal)
|
||||||
|
print "MATT result = '%s'" % (result)
|
||||||
|
if wholePeriod:
|
||||||
|
endResult = self._getTimeDesc(period.endTime(), resolution, shiftToLocal)
|
||||||
|
print "MATT endResult = '%s'" % (endResult)
|
||||||
|
if result != endResult:
|
||||||
|
result=result + " TO "+ endResult
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _getTimeDesc(self, startTime, resolution=3, shiftToLocal=True):
|
||||||
|
# Create phrase such as Tuesday morning
|
||||||
|
# Handle today/tonight and "this" morning/afternoon/etc..
|
||||||
|
#
|
||||||
|
print "\n\n**************Formatting Period for GMT starttime ", startTime
|
||||||
|
labels = self.Labels()["SimpleWorded"]
|
||||||
|
currentTime = self._timeRange.startTime()
|
||||||
|
print " currentTime = %s" % (repr(currentTime))
|
||||||
|
if shiftToLocal:
|
||||||
|
currentLocalTime, shift = self.determineTimeShift()
|
||||||
|
startTime = startTime + shift
|
||||||
|
currentTime = currentTime + shift
|
||||||
|
print " shift, shifted start, current", shift/3600, startTime, currentTime
|
||||||
|
hour = startTime.hour
|
||||||
|
prevDay = False
|
||||||
|
prevDay, partOfDay = self._getPartOfDay(hour, resolution)
|
||||||
|
# if prevDay:
|
||||||
|
# startTime = startTime - 24*3600
|
||||||
|
todayFlag = currentTime.day == startTime.day
|
||||||
|
if todayFlag:
|
||||||
|
if partOfDay.upper().find("MIDNIGHT")>0: todayWord = "tonight"
|
||||||
|
else: todayWord = "THIS"
|
||||||
|
weekday = todayWord
|
||||||
|
else:
|
||||||
|
weekday = labels["Weekday"][startTime.weekday()]
|
||||||
|
if partOfDay.find("<weekday>") >= 0:
|
||||||
|
result = partOfDay.replace('<weekday>', weekday)
|
||||||
|
else:
|
||||||
|
result = weekday + " " + partOfDay
|
||||||
|
print "Result = '%s'" % (result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _getPartOfDay(self, hour, resolution):
|
||||||
|
prevDay = False
|
||||||
|
if resolution == 3:
|
||||||
|
if hour < 3:
|
||||||
|
prevDay = True
|
||||||
|
partOfDay = "early <weekday> morning"
|
||||||
|
# partOfDay = "AFTER MIDNIGHT"
|
||||||
|
elif hour < 6:
|
||||||
|
partOfDay = "early <weekday> morning"
|
||||||
|
elif hour < 9:
|
||||||
|
partOfDay = "morning"
|
||||||
|
elif hour < 12:
|
||||||
|
partOfDay = "late <weekday> morning"
|
||||||
|
elif hour < 15:
|
||||||
|
partOfDay = "early <weekday> afternoon"
|
||||||
|
elif hour < 18:
|
||||||
|
partOfDay = "late <weekday> afternoon"
|
||||||
|
elif hour < 21:
|
||||||
|
partOfDay = "early <weekday> evening"
|
||||||
|
else:
|
||||||
|
partOfDay = "late <weekday> evening"
|
||||||
|
else:
|
||||||
|
if hour < 6:
|
||||||
|
prevDay = True
|
||||||
|
# partOfDay = "AFTER MIDNIGHT"
|
||||||
|
partOfDay = "early <weekday> morning"
|
||||||
|
elif hour < 12: partOfDay = "morning"
|
||||||
|
elif hour < 18: partOfDay = "afternoon"
|
||||||
|
else: partOfDay = "evening"
|
||||||
|
return prevDay, partOfDay
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
### Sampling and Statistics related methods
|
### Sampling and Statistics related methods
|
||||||
|
|
||||||
|
def moderated_dict(self, parmHisto, timeRange, componentName):
|
||||||
|
"""
|
||||||
|
Specifies the lower percentages and upper percentages of
|
||||||
|
data to be thrown out for moderated stats.
|
||||||
|
"""
|
||||||
|
# COMMENT: This dictionary defines the low and high limit at which
|
||||||
|
# outliers will be removed when calculating moderated stats.
|
||||||
|
# By convention the first value listed is the percentage
|
||||||
|
# allowed for low values and second the percentage allowed
|
||||||
|
# for high values.
|
||||||
|
|
||||||
|
# Get Baseline thresholds
|
||||||
|
dict = SampleAnalysis.SampleAnalysis.moderated_dict(
|
||||||
|
self, parmHisto, timeRange, componentName)
|
||||||
|
|
||||||
|
# Change thresholds
|
||||||
|
dict["Wind"] = (0, 15)
|
||||||
|
dict["WindGust"] = (0, 15)
|
||||||
|
dict["pws34int"] = (0, 5)
|
||||||
|
dict["pws64int"] = (0, 5)
|
||||||
|
dict["pwsD34"] = (0, 5)
|
||||||
|
dict["pwsN34"] = (0, 5)
|
||||||
|
dict["pwsD64"] = (0, 5)
|
||||||
|
dict["pwsN64"] = (0, 5)
|
||||||
|
dict["InundationMax"] = (0, 5)
|
||||||
|
dict["InundationTiming"] = (0, 5)
|
||||||
|
return dict
|
||||||
|
|
||||||
def _getStatValue(self, statDict, element, method=None, dataType=None):
|
def _getStatValue(self, statDict, element, method=None, dataType=None):
|
||||||
stats = statDict.get(element, None)
|
stats = statDict.get(element, None)
|
||||||
if stats is None: return None
|
if stats is None: return None
|
||||||
|
@ -600,25 +721,44 @@ FORECASTER STEWART"""
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
### Advisory related methods
|
### Advisory related methods
|
||||||
|
|
||||||
def _archiveCurrentAdvisory(self):
|
|
||||||
### Determine if all actions are canceled
|
|
||||||
allCAN = True
|
|
||||||
for vtecRecord in self._getAllVTECRecords():
|
|
||||||
action = vtecRecord['act']
|
|
||||||
#print "vtecRecord", vtecRecord
|
|
||||||
if action != "CAN":
|
|
||||||
allCAN = False
|
|
||||||
break
|
|
||||||
|
|
||||||
self._currentAdvisory["AllCAN"] = allCAN
|
|
||||||
self._currentAdvisory["CreationTime"] = self._issueTime_secs
|
|
||||||
self._currentAdvisory["Transmitted"] = False
|
|
||||||
self._currentAdvisory["StormName"] = self._getStormNameFromTCP()
|
|
||||||
self._saveAdvisory("pending", self._currentAdvisory)
|
|
||||||
|
|
||||||
|
def _synchronizeAdvisories(self):
|
||||||
|
pathManager = PathManagerFactory.getPathManager()
|
||||||
|
context = pathManager.getContextForSite(LocalizationType.CAVE_STATIC, self._site)
|
||||||
|
|
||||||
|
# Retrieving a directory causes synching to occur
|
||||||
|
file = pathManager.getLocalizationFile(context, self._getAdvisoryPath()).getFile()
|
||||||
|
|
||||||
|
return file
|
||||||
|
|
||||||
|
def _getLocalAdvisoryDirectoryPath(self):
|
||||||
|
file = self._synchronizeAdvisories()
|
||||||
|
|
||||||
|
path = file.getPath()
|
||||||
|
return path
|
||||||
|
|
||||||
|
def _loadLastTwoAdvisories(self):
|
||||||
|
advisoryDirectoryPath = self._getLocalAdvisoryDirectoryPath()
|
||||||
|
filenames = os.listdir(advisoryDirectoryPath)
|
||||||
|
allAdvisories = filter(lambda filename: filename[-5:] == ".json", filenames)
|
||||||
|
|
||||||
|
stormAdvisories = filter(lambda filename: self._getStormNameFromTCP() in filename,
|
||||||
|
allAdvisories)
|
||||||
|
stormAdvisories = map(lambda filename: filename[:-5], stormAdvisories)
|
||||||
|
lastTwoAdvisories = sorted(stormAdvisories)[:2]
|
||||||
|
|
||||||
|
self._previousAdvisory = None
|
||||||
|
if len(lastTwoAdvisories) >= 1:
|
||||||
|
self._previousAdvisory = self._loadAdvisory(lastTwoAdvisories[0])
|
||||||
|
|
||||||
|
self._previousPreviousAdvisory = None
|
||||||
|
if len(lastTwoAdvisories) >= 2:
|
||||||
|
self._previousPreviousAdvisory = self._loadAdvisory(lastTwoAdvisories[1])
|
||||||
|
|
||||||
def _loadAdvisory(self, advisoryName):
|
def _loadAdvisory(self, advisoryName):
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
self._synchronizeAdvisories()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
jsonDict = self._getFileContents(LocalizationType.CAVE_STATIC,
|
jsonDict = self._getFileContents(LocalizationType.CAVE_STATIC,
|
||||||
|
@ -630,29 +770,24 @@ FORECASTER STEWART"""
|
||||||
print pythonDict
|
print pythonDict
|
||||||
|
|
||||||
# Only use transmitted advisories
|
# Only use transmitted advisories
|
||||||
if pythonDict["Transmitted"] == False:
|
if pythonDict["Transmitted"] == False and advisoryName != "pending":
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return pythonDict
|
return pythonDict
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print "SARAH Load Exception for", self._getAdvisoryFilename(advisoryName), ":", e
|
print "SARAH Load Exception for %s : %s" % (self._getAdvisoryFilename(advisoryName), e)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _saveAdvisory(self, advisoryName, advisoryDict):
|
|
||||||
import json
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._writeFileContents(LocalizationType.CAVE_STATIC,
|
|
||||||
self._site,
|
|
||||||
self._getAdvisoryPath() + advisoryName + ".json",
|
|
||||||
json.dumps(advisoryDict))
|
|
||||||
print "SARAH: Wrote file contents for", (self._getAdvisoryPath() + advisoryName + ".json")
|
|
||||||
except Exception, e:
|
|
||||||
print "SARAH Save Exception for", (self._getAdvisoryPath() + advisoryName + ".json"), ":", e
|
|
||||||
|
|
||||||
def _getAdvisoryPath(self):
|
def _getAdvisoryPath(self):
|
||||||
return "gfe/tcvAdvisories/"
|
return "gfe/tcvAdvisories/"
|
||||||
|
|
||||||
|
def _getLocalizationFile(self, loctype, siteID, filename):
|
||||||
|
pathManager = PathManagerFactory.getPathManager()
|
||||||
|
context = pathManager.getContextForSite(loctype, siteID)
|
||||||
|
localizationFile = pathManager.getLocalizationFile(context, filename)
|
||||||
|
|
||||||
|
return localizationFile
|
||||||
|
|
||||||
def _getFileContents(self, loctype, siteID, filename):
|
def _getFileContents(self, loctype, siteID, filename):
|
||||||
pathManager = PathManagerFactory.getPathManager()
|
pathManager = PathManagerFactory.getPathManager()
|
||||||
context = pathManager.getContextForSite(loctype, siteID)
|
context = pathManager.getContextForSite(loctype, siteID)
|
||||||
|
@ -662,20 +797,8 @@ FORECASTER STEWART"""
|
||||||
|
|
||||||
return fileContents
|
return fileContents
|
||||||
|
|
||||||
def _writeFileContents(self, loctype, siteID, filename, contents):
|
|
||||||
pathManager = PathManagerFactory.getPathManager()
|
|
||||||
context = pathManager.getContextForSite(loctype, siteID)
|
|
||||||
localizationFile = pathManager.getLocalizationFile(context, filename)
|
|
||||||
with File(localizationFile.getFile(), filename, 'w') as pythonFile:
|
|
||||||
pythonFile.write(contents)
|
|
||||||
|
|
||||||
localizationFile.save()
|
|
||||||
|
|
||||||
def _getAdvisoryFilename(self, advisoryName):
|
def _getAdvisoryFilename(self, advisoryName):
|
||||||
year = time.gmtime(self._issueTime_secs).tm_year
|
|
||||||
advisoryFilename = self._getAdvisoryPath() + \
|
advisoryFilename = self._getAdvisoryPath() + \
|
||||||
self._getStormNameFromTCP().upper() + \
|
|
||||||
str(year) + \
|
|
||||||
advisoryName + \
|
advisoryName + \
|
||||||
".json"
|
".json"
|
||||||
return advisoryFilename
|
return advisoryFilename
|
||||||
|
@ -711,7 +834,7 @@ FORECASTER STEWART"""
|
||||||
# Order and inclusion of GUI1 buttons
|
# Order and inclusion of GUI1 buttons
|
||||||
# Each entry is (name of button in GUI code, desired label on GUI)
|
# Each entry is (name of button in GUI code, desired label on GUI)
|
||||||
"buttonList":[
|
"buttonList":[
|
||||||
("Next","Next"),
|
("Run","Run"),
|
||||||
("Cancel","Cancel"),
|
("Cancel","Cancel"),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
@ -725,68 +848,6 @@ FORECASTER STEWART"""
|
||||||
###############################################################
|
###############################################################
|
||||||
### TCV Statistics
|
### TCV Statistics
|
||||||
|
|
||||||
def _analysisList_TCV(self):
|
|
||||||
# Sample over 120 hours beginning at current time
|
|
||||||
analysisList = [
|
|
||||||
# Wind Section
|
|
||||||
("Wind", self.vectorModeratedMax, [6]),
|
|
||||||
("WindGust", self.moderatedMax, [6]),
|
|
||||||
("WindThreat", self.mostSignificantDiscreteValue),
|
|
||||||
("pws34int", self.moderatedMax, [6]),
|
|
||||||
("pws64int", self.moderatedMax, [6]),
|
|
||||||
("pwsD34", self.moderatedMax),
|
|
||||||
("pwsN34", self.moderatedMax),
|
|
||||||
("pwsD64", self.moderatedMax),
|
|
||||||
("pwsN64", self.moderatedMax),
|
|
||||||
|
|
||||||
# Flooding Rain Section
|
|
||||||
("QPF", self.accumSum, [72]),
|
|
||||||
("FloodingRainThreat", self.mostSignificantDiscreteValue),
|
|
||||||
|
|
||||||
# Tornado Section
|
|
||||||
("TornadoThreat", self.mostSignificantDiscreteValue),
|
|
||||||
]
|
|
||||||
|
|
||||||
return analysisList
|
|
||||||
|
|
||||||
def _intersectAnalysisList_TCV(self):
|
|
||||||
# The grids for the Surge Section will be intersected with a special edit area
|
|
||||||
analysisList = [
|
|
||||||
("InundationMax", self.moderatedMax, [6]),
|
|
||||||
("InundationTiming", self.moderatedMax, [6]),
|
|
||||||
("StormSurgeThreat", self.mostSignificantDiscreteValue),
|
|
||||||
]
|
|
||||||
|
|
||||||
return analysisList
|
|
||||||
|
|
||||||
def moderated_dict(self, parmHisto, timeRange, componentName):
|
|
||||||
"""
|
|
||||||
Specifies the lower percentages and upper percentages of
|
|
||||||
data to be thrown out for moderated stats.
|
|
||||||
"""
|
|
||||||
# COMMENT: This dictionary defines the low and high limit at which
|
|
||||||
# outliers will be removed when calculating moderated stats.
|
|
||||||
# By convention the first value listed is the percentage
|
|
||||||
# allowed for low values and second the percentage allowed
|
|
||||||
# for high values.
|
|
||||||
|
|
||||||
# Get Baseline thresholds
|
|
||||||
dict = SampleAnalysis.SampleAnalysis.moderated_dict(
|
|
||||||
self, parmHisto, timeRange, componentName)
|
|
||||||
|
|
||||||
# Change thresholds
|
|
||||||
dict["Wind"] = (0, 15)
|
|
||||||
dict["WindGust"] = (0, 15)
|
|
||||||
dict["pws34int"] = (0, 5)
|
|
||||||
dict["pws64int"] = (0, 5)
|
|
||||||
dict["pwsD34"] = (0, 5)
|
|
||||||
dict["pwsN34"] = (0, 5)
|
|
||||||
dict["pwsD64"] = (0, 5)
|
|
||||||
dict["pwsN64"] = (0, 5)
|
|
||||||
dict["InundationMax"] = (0, 5)
|
|
||||||
dict["InundationTiming"] = (0, 5)
|
|
||||||
return dict
|
|
||||||
|
|
||||||
def threatKeyOrder(self):
|
def threatKeyOrder(self):
|
||||||
return [None, "None", "Elevated", "Mod", "High", "Extreme"]
|
return [None, "None", "Elevated", "Mod", "High", "Extreme"]
|
||||||
|
|
||||||
|
@ -812,50 +873,7 @@ FORECASTER STEWART"""
|
||||||
def _initializeAdvisories(self):
|
def _initializeAdvisories(self):
|
||||||
self._currentAdvisory = dict()
|
self._currentAdvisory = dict()
|
||||||
self._currentAdvisory['ZoneData'] = dict()
|
self._currentAdvisory['ZoneData'] = dict()
|
||||||
self._previousAdvisory = self._loadAdvisory("previous")
|
self._loadLastTwoAdvisories()
|
||||||
print "SARAH: loaded previous advisory =", self._previousAdvisory
|
|
||||||
self._previousPreviousAdvisory = self._loadAdvisory("previousPrevious")
|
|
||||||
print "SARAH: loaded previousPrevious advisory =", self._previousPreviousAdvisory
|
|
||||||
|
|
||||||
def _sampleTCVData(self, argDict):
|
|
||||||
# Sample the data
|
|
||||||
editAreas = self._makeSegmentEditAreas(argDict)
|
|
||||||
cwa = self._cwa()
|
|
||||||
editAreas.append((cwa, cwa))
|
|
||||||
|
|
||||||
self._sampler = self.getSampler(argDict,
|
|
||||||
(self._analysisList_TCV(), self._timeRangeList, editAreas))
|
|
||||||
|
|
||||||
intersectAreas = self._computeIntersectAreas(editAreas, argDict)
|
|
||||||
|
|
||||||
self._intersectSampler = self.getSampler(argDict,
|
|
||||||
(self._intersectAnalysisList_TCV(), self._timeRangeList, intersectAreas))
|
|
||||||
|
|
||||||
def _getTCVStats(self, argDict, segment, editAreaDict, timeRangeList):
|
|
||||||
# Get statistics for this segment
|
|
||||||
print "SARAH: issue time seconds =", self._issueTime_secs
|
|
||||||
print "SARAH: GMT issue time =", time.gmtime(self._issueTime_secs)
|
|
||||||
|
|
||||||
editArea = editAreaDict[segment]
|
|
||||||
statList = self.getStatList(self._sampler,
|
|
||||||
self._analysisList_TCV(),
|
|
||||||
timeRangeList,
|
|
||||||
editArea)
|
|
||||||
|
|
||||||
windStats = WindSectionStats(self, segment, statList, timeRangeList)
|
|
||||||
floodingRainStats = FloodingRainSectionStats(self, segment, statList, timeRangeList)
|
|
||||||
tornadoStats = TornadoSectionStats(self, segment, statList, timeRangeList)
|
|
||||||
|
|
||||||
# The surge section needs sampling done with an intersected edit area
|
|
||||||
intersectEditArea = "intersect_"+editArea
|
|
||||||
intersectStatList = self.getStatList(self._intersectSampler,
|
|
||||||
self._intersectAnalysisList_TCV(),
|
|
||||||
timeRangeList,
|
|
||||||
intersectEditArea)
|
|
||||||
|
|
||||||
stormSurgeStats = StormSurgeSectionStats(self, segment, intersectStatList, timeRangeList)
|
|
||||||
|
|
||||||
return (windStats, stormSurgeStats, floodingRainStats, tornadoStats)
|
|
||||||
|
|
||||||
def _initializeSegmentZoneData(self, segment):
|
def _initializeSegmentZoneData(self, segment):
|
||||||
# The current advisory will be populated when setting a section's stats
|
# The current advisory will be populated when setting a section's stats
|
||||||
|
@ -894,10 +912,10 @@ FORECASTER STEWART"""
|
||||||
if combos is None:
|
if combos is None:
|
||||||
LogStream.logVerbose("COMBINATION FILE NOT FOUND: " + self._defaultEditAreas)
|
LogStream.logVerbose("COMBINATION FILE NOT FOUND: " + self._defaultEditAreas)
|
||||||
return [], None
|
return [], None
|
||||||
print "\nSegments from Zone Combiner", combos
|
#print "\nSegments from Zone Combiner", combos
|
||||||
# "Overlay" the forecaster-entered combinations onto the segments
|
# "Overlay" the forecaster-entered combinations onto the segments
|
||||||
segmentList = self._refineSegments(hazSegments, combos)
|
segmentList = self._refineSegments(hazSegments, combos)
|
||||||
print "\nNew segments", segmentList
|
#print "\nNew segments", segmentList
|
||||||
|
|
||||||
# Instead of a segment being a group of zones, it will be just a single zone.
|
# Instead of a segment being a group of zones, it will be just a single zone.
|
||||||
# So collapse this list of lists down to a list of zones (aka. segments)
|
# So collapse this list of lists down to a list of zones (aka. segments)
|
||||||
|
@ -925,6 +943,7 @@ FORECASTER STEWART"""
|
||||||
# (We need to define self._segmentList for the mapping function
|
# (We need to define self._segmentList for the mapping function
|
||||||
# to use)
|
# to use)
|
||||||
self._segmentList = hazSegments
|
self._segmentList = hazSegments
|
||||||
|
#print "self._segmentList = %s" % (repr(self._segmentList))
|
||||||
segmentMapping = map(self._findSegment, combo)
|
segmentMapping = map(self._findSegment, combo)
|
||||||
#print " segmentMapping", segmentMapping
|
#print " segmentMapping", segmentMapping
|
||||||
|
|
||||||
|
@ -966,568 +985,6 @@ FORECASTER STEWART"""
|
||||||
return segment
|
return segment
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
###############################################################
|
|
||||||
### TCV Statistics Classes
|
|
||||||
|
|
||||||
class SectionCommonStats():
|
|
||||||
def __init__(self, textProduct, segment):
|
|
||||||
self._textProduct = textProduct
|
|
||||||
self._segment = segment
|
|
||||||
|
|
||||||
self._initializeAdvisories()
|
|
||||||
|
|
||||||
self._maxThreat = None
|
|
||||||
|
|
||||||
def _initializeAdvisories(self):
|
|
||||||
self._currentAdvisory = self._textProduct._currentAdvisory['ZoneData'][self._segment]
|
|
||||||
|
|
||||||
self._previousAdvisory = None
|
|
||||||
# print "MATT textProduct._previousAdvisory = '%s'" % (textProduct._previousAdvisory)
|
|
||||||
if self._textProduct._previousAdvisory is not None:
|
|
||||||
self._previousAdvisory = self._textProduct._previousAdvisory['ZoneData'][self._segment]
|
|
||||||
|
|
||||||
# print "MATT textProduct._previousPreviousAdvisory = '%s'" % \
|
|
||||||
# (textProduct._previousPreviousAdvisory)
|
|
||||||
self._previousPreviousAdvisory = None
|
|
||||||
if self._textProduct._previousPreviousAdvisory is not None:
|
|
||||||
self._previousPreviousAdvisory = self._textProduct._previousPreviousAdvisory['ZoneData'][self._segment]
|
|
||||||
|
|
||||||
def _updateThreatStats(self, tr, statDict, threatGridName):
|
|
||||||
print "SARAH: updateThreatStats for", threatGridName
|
|
||||||
threatLevel = self._textProduct.getStats(statDict, threatGridName)
|
|
||||||
if threatLevel is not None:
|
|
||||||
threatLevels = self._textProduct.threatKeyOrder()
|
|
||||||
print "SARAH: threatLevel =", threatLevel
|
|
||||||
print "SARAH: maxThreat =", self._maxThreat
|
|
||||||
if self._maxThreat is None or \
|
|
||||||
threatLevels.index(threatLevel) > threatLevels.index(self._maxThreat):
|
|
||||||
print "SARAH: updating max threat to =", threatLevel
|
|
||||||
self._maxThreat = threatLevel
|
|
||||||
|
|
||||||
def _calculateHourOffset(self, targetTime):
|
|
||||||
seconds = targetTime.unixTime() - self._textProduct._issueTime_secs
|
|
||||||
hour = int(round(seconds/60/60))
|
|
||||||
if hour < 0:
|
|
||||||
hour = 0
|
|
||||||
|
|
||||||
return hour
|
|
||||||
|
|
||||||
|
|
||||||
class WindSectionStats(SectionCommonStats):
|
|
||||||
def __init__(self, textProduct, segment, statList, timeRangeList):
|
|
||||||
SectionCommonStats.__init__(self, textProduct, segment)
|
|
||||||
self._maxWind = None
|
|
||||||
self._maxGust = None
|
|
||||||
self._onset34Hour = None
|
|
||||||
self._end34Hour = None
|
|
||||||
self._onset64Hour = None
|
|
||||||
self._end64Hour = None
|
|
||||||
self._windowTS = None
|
|
||||||
self._windowHU = None
|
|
||||||
|
|
||||||
self._setStats(statList, timeRangeList)
|
|
||||||
|
|
||||||
class PwsXXintStats():
|
|
||||||
max = None
|
|
||||||
onsetHour = None
|
|
||||||
|
|
||||||
class PwsTXXStats():
|
|
||||||
onsetHour = None
|
|
||||||
endHour = None
|
|
||||||
|
|
||||||
class TimeInfo():
|
|
||||||
onsetHour = None
|
|
||||||
endHour = None
|
|
||||||
|
|
||||||
class EventsOccurring():
|
|
||||||
pwsTXXEvent = False
|
|
||||||
windXXEvent = False
|
|
||||||
|
|
||||||
def _setStats(self, statList, timeRangeList):
|
|
||||||
pws34intStats = self.PwsXXintStats()
|
|
||||||
pws64intStats = self.PwsXXintStats()
|
|
||||||
pwsT34Stats = self.PwsTXXStats()
|
|
||||||
pwsT64Stats = self.PwsTXXStats()
|
|
||||||
wind34timeInfo = self.TimeInfo()
|
|
||||||
wind64timeInfo = self.TimeInfo()
|
|
||||||
|
|
||||||
events34 = self.EventsOccurring()
|
|
||||||
events64 = self.EventsOccurring()
|
|
||||||
|
|
||||||
for period in range(len(statList)):
|
|
||||||
tr, _ = timeRangeList[period]
|
|
||||||
statDict = statList[period]
|
|
||||||
|
|
||||||
self._updateStatsForPwsXXint(tr, statDict, "pws34int", pws34intStats)
|
|
||||||
self._updateStatsForPwsXXint(tr, statDict, "pws64int", pws64intStats)
|
|
||||||
|
|
||||||
self._updateStatsForPwsTXX(tr, statDict, "pwsD34", "pwsN34", pwsT34Stats, events34, period)
|
|
||||||
self._updateStatsForPwsTXX(tr, statDict, "pwsD64", "pwsN64", pwsT64Stats, events64, period)
|
|
||||||
|
|
||||||
wind = self._textProduct._getStatValue(statDict, "Wind", "Max", self._textProduct.VECTOR())
|
|
||||||
if wind is not None:
|
|
||||||
if wind >= 34:
|
|
||||||
events34.windXXEvent = True
|
|
||||||
if wind >= 64:
|
|
||||||
events64.windXXEvent = True
|
|
||||||
else:
|
|
||||||
events64.windXXEvent = False
|
|
||||||
else:
|
|
||||||
events34.windXXEvent = False
|
|
||||||
events64.windXXEvent = False
|
|
||||||
|
|
||||||
if self._maxWind is None or wind >= self._maxWind:
|
|
||||||
self._maxWind = wind
|
|
||||||
|
|
||||||
self._updateWindTimeInfo(tr, wind34timeInfo, speed=34)
|
|
||||||
self._updateWindTimeInfo(tr, wind64timeInfo, speed=64)
|
|
||||||
|
|
||||||
windGust = self._textProduct._getStatValue(statDict, "WindGust", "Max")
|
|
||||||
if windGust is not None:
|
|
||||||
if self._maxGust is None or windGust > self._maxGust:
|
|
||||||
self._maxGust = windGust
|
|
||||||
|
|
||||||
self._updateThreatStats(tr, statDict, "WindThreat")
|
|
||||||
|
|
||||||
#Tropical Storm
|
|
||||||
onsetEndInfo = self._computeWindOnsetAndEnd(wind34timeInfo, pws34intStats, pwsT34Stats)
|
|
||||||
self._onset34Hour = onsetEndInfo.onsetHour
|
|
||||||
self._end34Hour = onsetEndInfo.endHour
|
|
||||||
|
|
||||||
nonEnding34Event = False
|
|
||||||
if events34.pwsTXXEvent and (wind34timeInfo.endHour is None or events34.windXXEvent):
|
|
||||||
nonEnding34Event = True
|
|
||||||
|
|
||||||
print "SARAH: Tropical Storm Window:"
|
|
||||||
self._windowTS = self._createWindow("Tropical Storm",
|
|
||||||
self._onset34Hour,
|
|
||||||
self._end34Hour,
|
|
||||||
nonEnding34Event)
|
|
||||||
|
|
||||||
#Hurricane
|
|
||||||
onsetEndInfo = self._computeWindOnsetAndEnd(wind64timeInfo, pws64intStats, pwsT64Stats)
|
|
||||||
self._onset64Hour = onsetEndInfo.onsetHour
|
|
||||||
self._end64Hour = onsetEndInfo.endHour
|
|
||||||
|
|
||||||
nonEnding64Event = False
|
|
||||||
if events64.pwsTXXEvent and (wind64timeInfo.endHour is None or events64.windXXEvent):
|
|
||||||
nonEnding64Event = True
|
|
||||||
|
|
||||||
print "SARAH: Hurricane Window:"
|
|
||||||
self._windowHU = self._createWindow("Hurricane",
|
|
||||||
self._onset64Hour,
|
|
||||||
self._end64Hour,
|
|
||||||
nonEnding64Event)
|
|
||||||
|
|
||||||
self._currentAdvisory["WindThreat"] = self._maxThreat
|
|
||||||
self._currentAdvisory["WindForecast"] = self._maxWind
|
|
||||||
|
|
||||||
def _updateStatsForPwsXXint(self, tr, statDict, gridName, pwsXXintStats):
|
|
||||||
pwsXXint = self._textProduct._getStatValue(statDict, gridName, "Max")
|
|
||||||
|
|
||||||
if pwsXXint is not None:
|
|
||||||
if pwsXXintStats.max is None or pwsXXint > pwsXXintStats.max:
|
|
||||||
pwsXXintStats.max = pwsXXint
|
|
||||||
pwsXXintStats.onsetHour = self._calculateHourOffset(tr.startTime())
|
|
||||||
|
|
||||||
print "SARAH: Window Debug: pwsXXintStats gridName =", gridName
|
|
||||||
print "SARAH: Window Debug: pwsXXintStats pwsXXint =", pwsXXint
|
|
||||||
print "SARAH: Window Debug: pwsXXintStats tr =", tr
|
|
||||||
print "SARAH: Window Debug: pwsXXintStats onsetHour =", pwsXXintStats.onsetHour
|
|
||||||
|
|
||||||
def _updateStatsForPwsTXX(self, tr, statDict, dayGridName, nightGridName, pwsTXXStats, events, period):
|
|
||||||
|
|
||||||
# Convert this time to locatime
|
|
||||||
trStartLocalHour = time.localtime(tr.startTime().unixTime()).tm_hour
|
|
||||||
dayStartHour = self._textProduct.DAY()
|
|
||||||
nightStartHour = self._textProduct.NIGHT()
|
|
||||||
print "MATT _updateStatsForPwsTXX = %s localStartHr = %d" % (repr(tr),
|
|
||||||
trStartLocalHour)
|
|
||||||
print "MATT dayStart = %s nightStart = %s" % (repr(dayStartHour),
|
|
||||||
repr(nightStartHour))
|
|
||||||
|
|
||||||
pwsDXX = self._textProduct._getStatValue(statDict, dayGridName, "Max")
|
|
||||||
pwsNXX = self._textProduct._getStatValue(statDict, nightGridName, "Max")
|
|
||||||
maxPws = None
|
|
||||||
print "MATT pwsDXX = %s pwsNXX = %s " % (repr(pwsDXX), repr(pwsNXX))
|
|
||||||
|
|
||||||
# if pwsDXX is not None:
|
|
||||||
# print "SARAH: Window Debug: pwsTXXStats DAY"
|
|
||||||
# maxPws = pwsDXX
|
|
||||||
# elif pwsNXX is not None:
|
|
||||||
# print "SARAH: Window Debug: pwsTXXStats NIGHT"
|
|
||||||
# maxPws = pwsNXX
|
|
||||||
|
|
||||||
# SARAH - if we are close to the end of a day/night period, the first
|
|
||||||
# period we would really want to consider would be the next period.
|
|
||||||
# This is hard-coded to 3 hours to prove the concept.
|
|
||||||
if (nightStartHour >= trStartLocalHour and \
|
|
||||||
(nightStartHour - trStartLocalHour) <= 3) or pwsDXX is None:
|
|
||||||
print "MATT: Window Debug: pwsTXXStats NIGHT"
|
|
||||||
maxPws = pwsNXX
|
|
||||||
elif (dayStartHour >= trStartLocalHour and \
|
|
||||||
(dayStartHour - trStartLocalHour) <= 3) or pwsNXX is None:
|
|
||||||
print "MATT: Window Debug: pwsTXXStats DAY"
|
|
||||||
maxPws = pwsDXX
|
|
||||||
|
|
||||||
threshold34index = 0
|
|
||||||
threshold64index = 1
|
|
||||||
if maxPws is not None:
|
|
||||||
if "64" in dayGridName:
|
|
||||||
index = threshold64index
|
|
||||||
else: #if "34"
|
|
||||||
index = threshold34index
|
|
||||||
|
|
||||||
threshold = None
|
|
||||||
thresholds = self.windSpdProb_thresholds()
|
|
||||||
if period == 0:
|
|
||||||
(thresholdLow, thresholdHigh) = thresholds[period][index]
|
|
||||||
threshold = thresholdLow
|
|
||||||
else:
|
|
||||||
if period >= 10: # SARAH: TODO - remove???
|
|
||||||
period = 9
|
|
||||||
threshold = thresholds[period][index]
|
|
||||||
|
|
||||||
if maxPws > threshold:
|
|
||||||
events.pwsTXXEvent = True
|
|
||||||
|
|
||||||
configuredEndTime = self._getCorrespondingConfiguredTime(tr.endTime(), isOnset = False)
|
|
||||||
pwsTXXStats.endHour = self._calculateHourOffset(configuredEndTime)
|
|
||||||
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats dayGridName =", dayGridName
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats nightGridName =", nightGridName
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats original tr =", tr
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats maxPws =", maxPws
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats endHour =", pwsTXXStats.endHour
|
|
||||||
|
|
||||||
if pwsTXXStats.onsetHour is None:
|
|
||||||
configuredStartTime = self._getCorrespondingConfiguredTime(tr.startTime(), isOnset = True)
|
|
||||||
pwsTXXStats.onsetHour = self._calculateHourOffset(configuredStartTime)
|
|
||||||
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats dayGridName =", dayGridName
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats nightGridName =", nightGridName
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats original tr =", tr
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats maxPws =", maxPws
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats onsetHour =", pwsTXXStats.onsetHour
|
|
||||||
else:
|
|
||||||
events.pwsTXXEvent = False
|
|
||||||
|
|
||||||
def _getCorrespondingConfiguredTime(self, gmtTime, isOnset):
|
|
||||||
dayStartHour = self._textProduct.DAY()
|
|
||||||
nightStartHour = self._textProduct.NIGHT()
|
|
||||||
|
|
||||||
print "SARAH: gmtTime =", gmtTime
|
|
||||||
|
|
||||||
gmtSeconds = gmtTime.unixTime()
|
|
||||||
localTime = time.localtime(gmtSeconds)
|
|
||||||
print "SARAH: localTime =", localTime
|
|
||||||
|
|
||||||
localHour = localTime.tm_hour
|
|
||||||
print "SARAH: localHour =", localHour
|
|
||||||
|
|
||||||
if isOnset:
|
|
||||||
print "SARAH: Window Debug: Adjusting start time"
|
|
||||||
else:
|
|
||||||
print "SARAH: Window Debug: Adjusting end time"
|
|
||||||
|
|
||||||
newHour = None
|
|
||||||
if localHour < dayStartHour:
|
|
||||||
if isOnset:
|
|
||||||
# Subtract 24 hours to get to the previous day
|
|
||||||
newGmtTime = gmtTime - 24*60*60
|
|
||||||
gmtSeconds = newGmtTime.unixTime()
|
|
||||||
localTime = time.localtime(gmtSeconds)
|
|
||||||
print "SARAH: new localTime =", localTime
|
|
||||||
|
|
||||||
newHour = nightStartHour
|
|
||||||
else:
|
|
||||||
newHour = dayStartHour
|
|
||||||
elif dayStartHour <= localHour and localHour < nightStartHour:
|
|
||||||
if isOnset:
|
|
||||||
newHour = dayStartHour
|
|
||||||
else:
|
|
||||||
newHour = nightStartHour
|
|
||||||
else:
|
|
||||||
if isOnset:
|
|
||||||
newHour = nightStartHour
|
|
||||||
else:
|
|
||||||
# Add 24 hours to get to the next day
|
|
||||||
newGmtTime = gmtTime + 24*60*60
|
|
||||||
gmtSeconds = newGmtTime.unixTime()
|
|
||||||
localTime = time.localtime(gmtSeconds)
|
|
||||||
print "SARAH: new localTime =", localTime
|
|
||||||
|
|
||||||
newHour = dayStartHour
|
|
||||||
|
|
||||||
print "SARAH: new localHour =", localHour
|
|
||||||
|
|
||||||
newTimeTuple = localTime[:3] + (newHour,) + localTime[4:]
|
|
||||||
import calendar
|
|
||||||
seconds = calendar.timegm(newTimeTuple)
|
|
||||||
adjustedGmtTime = AbsTime(seconds)
|
|
||||||
print "SARAH: new local time =", adjustedGmtTime
|
|
||||||
|
|
||||||
seconds = time.mktime(newTimeTuple)
|
|
||||||
adjustedGmtTime = AbsTime(seconds)
|
|
||||||
print "SARAH: new GMT time =", adjustedGmtTime
|
|
||||||
return adjustedGmtTime
|
|
||||||
|
|
||||||
# SARAH - we don't want this here. Use the inherited version from the
|
|
||||||
# VectorRelatedPhrases module instead. This way, changes only need to be
|
|
||||||
# made in one place.
|
|
||||||
def windSpdProb_thresholds(self):
|
|
||||||
return [
|
|
||||||
((45.0, 80.0), (25.0, 60.0)), # Per 1
|
|
||||||
(35.0, 20.0), # Per 2
|
|
||||||
(30.0, 15.0), # Per 3
|
|
||||||
(25.0, 12.5), # Per 4
|
|
||||||
(22.5, 10.0), # Per 5
|
|
||||||
(20.0, 8.0), # Per 6
|
|
||||||
(17.5, 7.0), # Per 7
|
|
||||||
(15.0, 6.0), # Per 8
|
|
||||||
(12.5, 5.0), # Per 9
|
|
||||||
(10.0, 4.0), # Per 10
|
|
||||||
]
|
|
||||||
|
|
||||||
def _updateWindTimeInfo(self, tr, timeInfo, speed):
|
|
||||||
if self._maxWind is not None and self._maxWind >= speed:
|
|
||||||
timeInfo.endHour = self._calculateHourOffset(tr.endTime())
|
|
||||||
|
|
||||||
print "SARAH: Window Debug: timeInfo speed =", speed
|
|
||||||
print "SARAH: Window Debug: timeInfo maxWind =", self._maxWind
|
|
||||||
print "SARAH: Window Debug: timeInfo tr =", tr
|
|
||||||
print "SARAH: Window Debug: timeInfo endHour =", timeInfo.endHour
|
|
||||||
|
|
||||||
if timeInfo.onsetHour is None:
|
|
||||||
timeInfo.onsetHour = self._calculateHourOffset(tr.startTime())
|
|
||||||
|
|
||||||
print "SARAH: Window Debug: timeInfo speed =", speed
|
|
||||||
print "SARAH: Window Debug: timeInfo maxWind =", self._maxWind
|
|
||||||
print "SARAH: Window Debug: timeInfo tr =", tr
|
|
||||||
print "SARAH: Window Debug: timeInfo onsetHour =", timeInfo.onsetHour
|
|
||||||
|
|
||||||
def _computeWindOnsetAndEnd(self, windTimeInfo, pwsXXintStats, pwsTXXStats):
|
|
||||||
onsetEndInfo = self.TimeInfo()
|
|
||||||
|
|
||||||
print "SARAH: Window Debug: windTimeInfo.onsetHour =", windTimeInfo.onsetHour
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats.onsetHour =", pwsTXXStats.onsetHour
|
|
||||||
print "SARAH: Window Debug: pwsXXintStats.onsetHour =", pwsXXintStats.onsetHour
|
|
||||||
print "SARAH: Window Debug: windTimeInfo.endHour =", windTimeInfo.endHour
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats.endHour =", pwsTXXStats.endHour
|
|
||||||
|
|
||||||
if windTimeInfo.onsetHour is None:
|
|
||||||
# print "SARAH: Window Debug: windTimeInfo.onsetHour was None; using pwsTXXStats"
|
|
||||||
# windTimeInfo.onsetHour = pwsTXXStats.onsetHour
|
|
||||||
# print "SARAH: Window Debug: pwsTXXStats.onsetHour =", pwsTXXStats.onsetHour
|
|
||||||
|
|
||||||
# Short-circuit this logic as a temporary measure. Basically, do
|
|
||||||
# not include a window if the deterministic winds do not support
|
|
||||||
# a particular threshold
|
|
||||||
onsetEndInfo.endHour = None
|
|
||||||
|
|
||||||
if windTimeInfo.onsetHour is not None and pwsXXintStats.onsetHour is not None:
|
|
||||||
print "SARAH: Window Debug: windTimeInfo.onsetHour & pwsXXintStats.onsetHour not None; taking min"
|
|
||||||
onsetEndInfo.onsetHour = min(windTimeInfo.onsetHour, pwsXXintStats.onsetHour)
|
|
||||||
print "SARAH: Window Debug: min onsetHour =", onsetEndInfo.onsetHour
|
|
||||||
|
|
||||||
if onsetEndInfo.onsetHour is not None:
|
|
||||||
if windTimeInfo.endHour is None:
|
|
||||||
print "SARAH: Window Debug: windTimeInfo.endHour was None; using pwsTXXStats"
|
|
||||||
onsetEndInfo.endHour = pwsTXXStats.endHour
|
|
||||||
print "SARAH: Window Debug: pwsTXXStats.endHour =", pwsTXXStats.endHour
|
|
||||||
elif pwsTXXStats.endHour is not None:
|
|
||||||
print "SARAH: windendHour =", windTimeInfo.endHour
|
|
||||||
print "SARAH: probendHour =", pwsTXXStats.endHour
|
|
||||||
onsetEndInfo.endHour = int(round(self._textProduct.average(windTimeInfo.endHour, pwsTXXStats.endHour)))
|
|
||||||
print "SARAH: endHour =", onsetEndInfo.endHour
|
|
||||||
return onsetEndInfo
|
|
||||||
|
|
||||||
def _createWindow(self, windowName, onsetHour, endHour, nonEndingEvent):
|
|
||||||
window = "Window for " + windowName + " force winds: "
|
|
||||||
print "SARAH: window stats:"
|
|
||||||
print "SARAH: onsetHour =", onsetHour
|
|
||||||
print "SARAH: endHour =", endHour
|
|
||||||
print "SARAH: window nonEndingEvent =", nonEndingEvent
|
|
||||||
|
|
||||||
if onsetHour is None:
|
|
||||||
|
|
||||||
# SARAH - we do not want a statement of a non-existent window
|
|
||||||
# window += "None"
|
|
||||||
window = None
|
|
||||||
else:
|
|
||||||
startTime = AbsTime(self._textProduct._issueTime_secs + onsetHour*60*60)
|
|
||||||
if endHour is not None:
|
|
||||||
endTime = AbsTime(self._textProduct._issueTime_secs + endHour*60*60)
|
|
||||||
windowPeriod = self._textProduct.makeTimeRange(startTime, endTime)
|
|
||||||
else:
|
|
||||||
windowPeriod = self._textProduct.makeTimeRange(startTime, startTime + 1)
|
|
||||||
print "SARAH: window period =", windowPeriod
|
|
||||||
|
|
||||||
startTimeDescriptor = ""
|
|
||||||
if onsetHour >= 18:
|
|
||||||
startTimeDescriptor = self._textProduct._formatPeriod(windowPeriod, resolution = 6)
|
|
||||||
elif 6 <= onsetHour and onsetHour < 18:
|
|
||||||
startTimeDescriptor = self._textProduct._formatPeriod(windowPeriod, resolution = 3)
|
|
||||||
|
|
||||||
if endHour is None or nonEndingEvent:
|
|
||||||
if len(startTimeDescriptor) != 0:
|
|
||||||
window += "Begins " + startTimeDescriptor
|
|
||||||
else:
|
|
||||||
window += "None"
|
|
||||||
else:
|
|
||||||
connector = "through "
|
|
||||||
endTimeDescriptor = "the next few hours"
|
|
||||||
|
|
||||||
if endHour >= 18:
|
|
||||||
endTimeDescriptor = self._textProduct._formatPeriod(windowPeriod,
|
|
||||||
useEndTime = True,
|
|
||||||
resolution = 6)
|
|
||||||
elif 6 <= endHour and endHour < 18:
|
|
||||||
endTimeDescriptor = self._textProduct._formatPeriod(windowPeriod,
|
|
||||||
useEndTime = True,
|
|
||||||
resolution = 3)
|
|
||||||
|
|
||||||
if len(startTimeDescriptor) != 0:
|
|
||||||
connector = " " + connector
|
|
||||||
window += startTimeDescriptor + connector + endTimeDescriptor
|
|
||||||
|
|
||||||
return window
|
|
||||||
|
|
||||||
|
|
||||||
class StormSurgeSectionStats(SectionCommonStats):
|
|
||||||
def __init__(self, textProduct, segment, intersectStatList, timeRangeList):
|
|
||||||
SectionCommonStats.__init__(self, textProduct, segment)
|
|
||||||
self._inundationMax = None
|
|
||||||
self._onsetSurgeHour = None
|
|
||||||
self._endSurgeHour = None
|
|
||||||
self._windowSurge = None
|
|
||||||
|
|
||||||
self._setStats(intersectStatList, timeRangeList)
|
|
||||||
|
|
||||||
def _setStats(self, statList, timeRangeList):
|
|
||||||
phishStartTime = None
|
|
||||||
phishEndTime = None
|
|
||||||
possibleStop = 0
|
|
||||||
|
|
||||||
# print "*"*100
|
|
||||||
# print "MATT phishStartTime = %s phishEndTime = %s possibleStop = %d" % (str(phishStartTime), str(phishEndTime), possibleStop)
|
|
||||||
|
|
||||||
for period in range(len(statList)):
|
|
||||||
tr, _ = timeRangeList[period]
|
|
||||||
statDict = statList[period]
|
|
||||||
|
|
||||||
phishPeak = self._textProduct._getStatValue(statDict, "InundationMax", "Max")
|
|
||||||
if phishPeak is not None:
|
|
||||||
if self._inundationMax is None or phishPeak > self._inundationMax:
|
|
||||||
self._inundationMax = phishPeak
|
|
||||||
|
|
||||||
curPhish = self._textProduct._getStatValue(statDict, "InundationTiming", "Max")
|
|
||||||
# print "MATT tr = %s" % (repr(tr))
|
|
||||||
# print "MATT curPhish = '%s' possibleStop = %d" % (str(curPhish), possibleStop)
|
|
||||||
# print "MATT phishStartTime = %s phishEndTime = %s" % (str(phishStartTime), str(phishEndTime))
|
|
||||||
|
|
||||||
if curPhish is not None and possibleStop != 2:
|
|
||||||
if curPhish > 0:
|
|
||||||
if phishStartTime is None:
|
|
||||||
phishStartTime = tr.startTime()
|
|
||||||
possibleStop = 0
|
|
||||||
phishEndTime = None
|
|
||||||
elif phishStartTime is not None:
|
|
||||||
possibleStop += 1
|
|
||||||
|
|
||||||
if phishEndTime is None:
|
|
||||||
phishEndTime = tr.startTime()
|
|
||||||
|
|
||||||
self._updateThreatStats(tr, statDict, "StormSurgeThreat")
|
|
||||||
|
|
||||||
self._windowSurge = "Window for Storm Surge Inundation: "
|
|
||||||
|
|
||||||
if phishStartTime is None:
|
|
||||||
self._windowSurge += "None"
|
|
||||||
else:
|
|
||||||
self._onsetSurgeHour = self._calculateHourOffset(phishStartTime)
|
|
||||||
startTime = AbsTime(self._textProduct._issueTime_secs + self._onsetSurgeHour*60*60)
|
|
||||||
|
|
||||||
# print "MATT surge startTime = %s self._onsetSurgeHour = %s " % (repr(startTime), self._onsetSurgeHour)
|
|
||||||
if phishEndTime is not None:
|
|
||||||
self._endSurgeHour = self._calculateHourOffset(phishEndTime)
|
|
||||||
endTime = AbsTime(self._textProduct._issueTime_secs + self._endSurgeHour*60*60)
|
|
||||||
windowPeriod = self._textProduct.makeTimeRange(startTime, endTime)
|
|
||||||
else:
|
|
||||||
windowPeriod = self._textProduct.makeTimeRange(startTime, startTime + 1)
|
|
||||||
print "SARAH: window period =", windowPeriod
|
|
||||||
|
|
||||||
startTimeDescriptor = self._textProduct._formatPeriod(windowPeriod)
|
|
||||||
|
|
||||||
if phishEndTime is None:
|
|
||||||
self._windowSurge += "Begins " + startTimeDescriptor
|
|
||||||
elif phishStartTime == phishEndTime:
|
|
||||||
self._windowSurge += startTimeDescriptor
|
|
||||||
else:
|
|
||||||
endTimeDescriptor = self._textProduct._formatPeriod(windowPeriod, useEndTime = True)
|
|
||||||
|
|
||||||
if self._onsetSurgeHour > 12:
|
|
||||||
self._windowSurge += startTimeDescriptor +\
|
|
||||||
" through " +\
|
|
||||||
endTimeDescriptor
|
|
||||||
else:
|
|
||||||
self._windowSurge += "through " + endTimeDescriptor
|
|
||||||
|
|
||||||
self._currentAdvisory["StormSurgeThreat"] = self._maxThreat
|
|
||||||
if self._inundationMax is not None:
|
|
||||||
# Round so we don't store values like 1.600000023841858
|
|
||||||
self._currentAdvisory["StormSurgeForecast"] = \
|
|
||||||
int(self._inundationMax * 10.0) / 10.0
|
|
||||||
|
|
||||||
|
|
||||||
class FloodingRainSectionStats(SectionCommonStats):
|
|
||||||
def __init__(self, textProduct, segment, statList, timeRangeList):
|
|
||||||
SectionCommonStats.__init__(self, textProduct, segment)
|
|
||||||
self._sumAccum = None
|
|
||||||
|
|
||||||
self._setStats(statList, timeRangeList)
|
|
||||||
|
|
||||||
def _setStats(self, statList, timeRangeList):
|
|
||||||
for period in range(len(statList)):
|
|
||||||
tr, _ = timeRangeList[period]
|
|
||||||
statDict = statList[period]
|
|
||||||
|
|
||||||
stats = self._textProduct.getStats(statDict, "QPF")
|
|
||||||
if stats is not None:
|
|
||||||
for (value, tr) in stats:
|
|
||||||
|
|
||||||
if value is not None:
|
|
||||||
if self._sumAccum is None:
|
|
||||||
self._sumAccum = value
|
|
||||||
else:
|
|
||||||
self._sumAccum += value
|
|
||||||
|
|
||||||
self._updateThreatStats(tr, statDict, "FloodingRainThreat")
|
|
||||||
|
|
||||||
self._currentAdvisory["FloodingRainThreat"] = self._maxThreat
|
|
||||||
if self._sumAccum is not None:
|
|
||||||
# Round so that we don't end up with stats like 4.03143835067749
|
|
||||||
self._currentAdvisory["FloodingRainForecast"] = \
|
|
||||||
self._textProduct.round(self._sumAccum, "Nearest", 0.5)
|
|
||||||
|
|
||||||
|
|
||||||
class TornadoSectionStats(SectionCommonStats):
|
|
||||||
def __init__(self, textProduct, segment, statList, timeRangeList):
|
|
||||||
SectionCommonStats.__init__(self, textProduct, segment)
|
|
||||||
|
|
||||||
self._setStats(statList, timeRangeList)
|
|
||||||
|
|
||||||
def _setStats(self, statList, timeRangeList):
|
|
||||||
for period in range(len(statList)):
|
|
||||||
tr, _ = timeRangeList[period]
|
|
||||||
statDict = statList[period]
|
|
||||||
|
|
||||||
self._updateThreatStats(tr, statDict, "TornadoThreat")
|
|
||||||
|
|
||||||
self._currentAdvisory["TornadoThreat"] = self._maxThreat
|
|
||||||
|
|
||||||
|
|
||||||
import Tkinter
|
import Tkinter
|
||||||
class Common_Dialog(Dialog):
|
class Common_Dialog(Dialog):
|
||||||
def __init__(self, parent, title, infoDict=None):
|
def __init__(self, parent, title, infoDict=None):
|
|
@ -781,8 +781,8 @@ class TextUtils:
|
||||||
self._debugDict[name] = count
|
self._debugDict[name] = count
|
||||||
|
|
||||||
# Print the traceback message
|
# Print the traceback message
|
||||||
print "\n\tDEBUG:",name, "in", file, "at line",\
|
print "DEBUG: %s in %s at line %d" % (name, file, lineno)
|
||||||
lineno,"Class=", self.__class__, count
|
print "DEBUG: Class = %s %d\n\n" % (self.__class__, count)
|
||||||
#print "Super classes:",self.__class__.__bases__
|
#print "Super classes:",self.__class__.__bases__
|
||||||
|
|
||||||
# If there is a message, print that too
|
# If there is a message, print that too
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
##
|
##
|
||||||
# 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.
|
||||||
##
|
##
|
||||||
|
@ -51,8 +51,9 @@ DirectFileToProductMapping = {
|
||||||
'PublicMarine_EA_Site_MultiPil_Definition': 'AFD',
|
'PublicMarine_EA_Site_MultiPil_Definition': 'AFD',
|
||||||
'PublicMarineFireWx_EA_Site_MultiPil_Definition': 'AFD',
|
'PublicMarineFireWx_EA_Site_MultiPil_Definition': 'AFD',
|
||||||
'FireWxZones_EA_Site_MultiPil_Definition': 'RFW',
|
'FireWxZones_EA_Site_MultiPil_Definition': 'RFW',
|
||||||
'MarineZones_EA_Site_MultiPil_Definition': ['CFW', 'MWW'],
|
'MarineZones_EA_Site_MultiPil_Definition': 'MWW',
|
||||||
'PublicZones_EA_Site_MultiPil_Definition': ['NPW','WSW','CFW','FFA','AQA'],
|
'PublicZones_EA_Site_MultiPil_Definition': ['NPW','WSW','CFW','FFA','AQA'],
|
||||||
|
'Hazard_TCV': 'TCV',
|
||||||
'Hazard_HLS': 'HLS',
|
'Hazard_HLS': 'HLS',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,20 +63,19 @@ NWSProducts = ['ADR', 'AFD', 'AFM', 'AQA', 'AVA', 'AVW', 'CAE', 'CCF', 'CDW', 'C
|
||||||
'CFW', 'CWF', 'EQR', 'EQW', 'ESF', 'EVI', 'FFA', 'FRW', 'FWF',
|
'CFW', 'CWF', 'EQR', 'EQW', 'ESF', 'EVI', 'FFA', 'FRW', 'FWF',
|
||||||
'FWM', 'FWS', 'GLF', 'HLS', 'HMW', 'HWO', 'LAE', 'LEW', 'MWS',
|
'FWM', 'FWS', 'GLF', 'HLS', 'HMW', 'HWO', 'LAE', 'LEW', 'MWS',
|
||||||
'MVF', 'NOW', 'NPW', 'NSH', 'NUW', 'OFF', 'PFM', 'PNS', 'RFD',
|
'MVF', 'NOW', 'NPW', 'NSH', 'NUW', 'OFF', 'PFM', 'PNS', 'RFD',
|
||||||
'RFW', 'RHW', 'SAF', 'SFT', 'SPS', 'SPW', 'SRF', 'TOE', 'VOW',
|
'RFW', 'RHW', 'SAF', 'SFT', 'SPS', 'SPW', 'SRF', 'TCV', 'TOE',
|
||||||
'WCN', 'WSW', 'ZFP', 'MWW']
|
'VOW', 'WCN', 'WSW', 'ZFP', 'MWW']
|
||||||
|
|
||||||
|
|
||||||
#Templated files. Named with "Product" in them, will be replaced with the
|
#Templated files. Named with "Product" in them, will be replaced with the
|
||||||
#actual product name. Dictionary contains the template filename, list
|
#actual product name. Dictionary contains the template filename, list
|
||||||
#contains the products to be generated (e.g., AFM). These products
|
#contains the products to be generated (e.g., AFM). These products
|
||||||
#follow the Baseline, Region, Site technique.
|
#follow the Baseline, Region, Site technique.
|
||||||
templateProds= ['AFM', 'ZFP', 'CCF', 'CWF', 'CWF_Pacific', 'FWF',
|
templateProds= ['AFM', 'ZFP', 'CCF', 'CWF', 'CWF_Pacific', 'FWF', 'HLS',
|
||||||
'FWFTable', 'FWM', 'GLF', 'MVF', 'NSH', 'PFM', 'SFT', 'SRF', 'OFF', 'AFD',
|
'FWFTable', 'FWM', 'GLF', 'MVF', 'NSH', 'PFM', 'SFT', 'SRF', 'OFF', 'AFD']
|
||||||
'Hazard_HLS']
|
templateProdsWsaf= ['AFM', 'ZFP', 'CCF', 'CWF', 'CWF_Pacific', 'FWF', 'HLS',
|
||||||
templateProdsWsaf= ['AFM', 'ZFP', 'CCF', 'CWF', 'CWF_Pacific', 'FWF',
|
|
||||||
'FWFTable', 'FWM', 'GLF', 'MVF', 'NSH', 'PFM', 'SFT', 'SRF', 'OFF', 'AFD', 'SAF',
|
'FWFTable', 'FWM', 'GLF', 'MVF', 'NSH', 'PFM', 'SFT', 'SRF', 'OFF', 'AFD', 'SAF',
|
||||||
'FWS', 'Hazard_HLS']
|
'FWS', 'Hazard_TCV', 'Hazard_HLS']
|
||||||
templateProds_minus_HLS = ['AFM', 'ZFP', 'CCF', 'CWF', 'CWF_Pacific', 'FWF',
|
templateProds_minus_HLS = ['AFM', 'ZFP', 'CCF', 'CWF', 'CWF_Pacific', 'FWF',
|
||||||
'FWFTable', 'FWM', 'GLF', 'MVF', 'NSH', 'PFM', 'SFT', 'SRF', 'OFF', 'AFD']
|
'FWFTable', 'FWM', 'GLF', 'MVF', 'NSH', 'PFM', 'SFT', 'SRF', 'OFF', 'AFD']
|
||||||
TemplatedProducts = {
|
TemplatedProducts = {
|
||||||
|
@ -85,3 +85,4 @@ TemplatedProducts = {
|
||||||
'Product_Region_Overrides': templateProdsWsaf,
|
'Product_Region_Overrides': templateProdsWsaf,
|
||||||
'Product_Site_Overrides': templateProdsWsaf,
|
'Product_Site_Overrides': templateProdsWsaf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,20 +20,20 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
Definition["outputFile"] = "{prddir}/TEXT/HLS.txt"
|
Definition["outputFile"] = "{prddir}/TEXT/HLS.txt"
|
||||||
Definition["database"] = "Official" # Source database
|
Definition["database"] = "Official" # Source database
|
||||||
Definition["debug"] = 1
|
Definition["debug"] = 1
|
||||||
Definition["mapNameForCombinations"] = "Zones_<site>"
|
Definition["mapNameForCombinations"] = "Zones_MFL"
|
||||||
Definition["defaultEditAreas"] = "EditAreas_PublicMarine_<site>"
|
Definition["defaultEditAreas"] = "Combinations_HLS_MFL"
|
||||||
Definition["showZoneCombiner"] = 1 # 1 to cause zone combiner to display
|
Definition["showZoneCombiner"] = 0 # 1 to cause zone combiner to display
|
||||||
|
|
||||||
Definition["productName"] = "LOCAL STATEMENT"
|
Definition["productName"] = "LOCAL STATEMENT"
|
||||||
|
|
||||||
Definition["fullStationID" ] = "<fullStationID>"
|
Definition["fullStationID" ] = "KMFL"
|
||||||
Definition["wmoID" ] = "<wmoID>"
|
Definition["wmoID" ] = "WTUS82"
|
||||||
Definition["wfoCityState" ] = "<wfoCityState>"
|
Definition["wfoCityState" ] = "MIAMI FL"
|
||||||
Definition["pil" ] = "<pil>"
|
Definition["pil" ] = "HLSMIA"
|
||||||
Definition["textdbPil" ] = "<textdbPil>"
|
Definition["textdbPil" ] = "MIAHLSMIA"
|
||||||
Definition["awipsWANPil" ] = "<awipsWANPil>"
|
Definition["awipsWANPil" ] = "KMFLHLSMIA"
|
||||||
Definition["site"] = "<site>"
|
Definition["site"] = "MFL"
|
||||||
Definition["wfoCity"] = "<wfoCity>"
|
Definition["wfoCity"] = "MIAMI"
|
||||||
|
|
||||||
Definition["areaName"] = "" #optional area name for product
|
Definition["areaName"] = "" #optional area name for product
|
||||||
Definition["areaDictionary"] = "AreaDictionary"
|
Definition["areaDictionary"] = "AreaDictionary"
|
||||||
|
@ -173,13 +173,16 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
analysisList = [
|
analysisList = [
|
||||||
# Wind Section
|
# Wind Section
|
||||||
("WindThreat", self.rankedDiscreteValue),
|
("WindThreat", self.rankedDiscreteValue),
|
||||||
|
("WindThreat", self.mostSignificantDiscreteValue),
|
||||||
|
|
||||||
# Flooding Rain Section
|
# Flooding Rain Section
|
||||||
("QPFtoFFGRatio", self.moderatedMax, [6]),
|
("QPFtoFFGRatio", self.moderatedMax, [6]),
|
||||||
("FloodingRainThreat", self.rankedDiscreteValue),
|
("FloodingRainThreat", self.rankedDiscreteValue),
|
||||||
|
("FloodingRainThreat", self.mostSignificantDiscreteValue),
|
||||||
|
|
||||||
# Tornado Section
|
# Tornado Section
|
||||||
("TornadoThreat", self.rankedDiscreteValue),
|
("TornadoThreat", self.rankedDiscreteValue),
|
||||||
|
("TornadoThreat", self.mostSignificantDiscreteValue),
|
||||||
]
|
]
|
||||||
|
|
||||||
return analysisList
|
return analysisList
|
||||||
|
@ -198,6 +201,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
analysisList = [
|
analysisList = [
|
||||||
("InundationMax", self.moderatedMax, [6]),
|
("InundationMax", self.moderatedMax, [6]),
|
||||||
("StormSurgeThreat", self.rankedDiscreteValue),
|
("StormSurgeThreat", self.rankedDiscreteValue),
|
||||||
|
("StormSurgeThreat", self.mostSignificantDiscreteValue),
|
||||||
]
|
]
|
||||||
|
|
||||||
return analysisList
|
return analysisList
|
||||||
|
@ -223,7 +227,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
if self._ImpactsAnticipated:
|
if self._ImpactsAnticipated:
|
||||||
includedImpacts = sorted(self._IncludedImpacts, key=self._impactsKeyFunction)
|
includedImpacts = sorted(self._IncludedImpacts, key=self._impactsKeyFunction)
|
||||||
for ((_, sectionName), _) in includedImpacts:
|
for ((_, sectionName), _) in includedImpacts:
|
||||||
print "SARAH: adding section", sectionName
|
print "SARAH: adding section = '%s'" % (sectionName)
|
||||||
partsList.append(sectionName)
|
partsList.append(sectionName)
|
||||||
|
|
||||||
partsList.append('preparednessSection')
|
partsList.append('preparednessSection')
|
||||||
|
@ -249,7 +253,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
return int(indexStr)
|
return int(indexStr)
|
||||||
|
|
||||||
def _ugcHeader(self, productDict, productSegmentGroup, productSegment):
|
def _ugcHeader(self, productDict, productSegmentGroup, productSegment):
|
||||||
self._ugcs = self._allAreas()
|
self._ugcs = self._allAreas()
|
||||||
productDict['ugcCodes'] = self._formatUGC_entries()
|
productDict['ugcCodes'] = self._formatUGC_entries()
|
||||||
self._ugcHeader_value = self._tpc.formatUGCs(self._ugcs, self._expireTime)
|
self._ugcHeader_value = self._tpc.formatUGCs(self._ugcs, self._expireTime)
|
||||||
productDict['ugcHeader'] = self._ugcHeader_value
|
productDict['ugcHeader'] = self._ugcHeader_value
|
||||||
|
@ -334,7 +338,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
|
|
||||||
# If there is only one impact across the entire CWA, and it is the max
|
# If there is only one impact across the entire CWA, and it is the max
|
||||||
if impactMax != "none" and impactMin == impactMax and inputThreatDominant != "None":
|
if impactMax != "none" and impactMin == impactMax and inputThreatDominant != "None":
|
||||||
sectionDict['impactRange'] = "Prepare for " + impactMax + " damage across " + self._cwa() + "."
|
sectionDict['impactRange'] = "Prepare for " + impactMax + " damage across " + self._cwa_descriptor() + "."
|
||||||
# Handle the case where the impacts are not the same across the entire CWA
|
# Handle the case where the impacts are not the same across the entire CWA
|
||||||
else:
|
else:
|
||||||
sectionDict['variedImpacts'] = True
|
sectionDict['variedImpacts'] = True
|
||||||
|
@ -344,14 +348,27 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
|
|
||||||
# If there are additional areas
|
# If there are additional areas
|
||||||
if impactRange != impactMax:
|
if impactRange != impactMax:
|
||||||
sectionDict['additionalImpactRange'].append("Prepare for " +
|
|
||||||
impactRange +
|
curPhrase = "Prepare for %s damage across %s." % \
|
||||||
" damage across " +
|
(impactRange, self._frame("ENTER AREA DESCRIPTION"))
|
||||||
self._frame("ENTER AREA DESCRIPTION") + ".")
|
|
||||||
|
# If this phrase is not already part of the additional impacts
|
||||||
|
if curPhrase not in sectionDict['additionalImpactRange']:
|
||||||
|
|
||||||
|
# Add it now
|
||||||
|
sectionDict['additionalImpactRange'].append(curPhrase)
|
||||||
|
|
||||||
# If there is no impact across more than one half the area, include a statement for that as well
|
# If there is no impact across more than one half the area, include a statement for that as well
|
||||||
if inputThreatDominant == "None":
|
if inputThreatDominant == "None":
|
||||||
sectionDict['additionalImpactRange'].append("Elsewhere across " + self._cwa() + ", little to no impact is anticipated.")
|
|
||||||
|
curPhrase = "Elsewhere across " + self._cwa_descriptor() + \
|
||||||
|
", little to no impact is anticipated."
|
||||||
|
|
||||||
|
# If this phrase is not already part of the additional impacts
|
||||||
|
if curPhrase not in sectionDict['additionalImpactRange']:
|
||||||
|
|
||||||
|
# Add it now
|
||||||
|
sectionDict['additionalImpactRange'].append(curPhrase)
|
||||||
|
|
||||||
productDict['windSection'] = sectionDict
|
productDict['windSection'] = sectionDict
|
||||||
|
|
||||||
|
@ -384,7 +401,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
|
|
||||||
sectionDict['impactRange'] = "Prepare for " + \
|
sectionDict['impactRange'] = "Prepare for " + \
|
||||||
lifeThreatening + impactMax + \
|
lifeThreatening + impactMax + \
|
||||||
" damage in surge prone areas of " + self._cwa() + ", with the greatest impacts " + \
|
" damage in surge prone areas of " + self._cwa_descriptor() + ", with the greatest impacts " + \
|
||||||
self._frame("ENTER AREA DESCRIPTION") + "."
|
self._frame("ENTER AREA DESCRIPTION") + "."
|
||||||
|
|
||||||
sectionDict['impactLib'] = self._getPotentialImpactsStatements("Storm Surge", self._impactCategoryToThreatLevel(impactMax))
|
sectionDict['impactLib'] = self._getPotentialImpactsStatements("Storm Surge", self._impactCategoryToThreatLevel(impactMax))
|
||||||
|
@ -414,20 +431,40 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
|
|
||||||
# If there are additional life-threatening surge areas
|
# If there are additional life-threatening surge areas
|
||||||
if impactRange != impactMax and impactRange != impactMin:
|
if impactRange != impactMax and impactRange != impactMin:
|
||||||
sectionDict['additionalImpactRange'].append("Brace for " +
|
|
||||||
lifeThreatening + impactRange +
|
curPhrase = "Brace for %s%s damage across %s." % \
|
||||||
" damage " + self._frame("ENTER AREA DESCRIPTION"))
|
(lifeThreatening, impactRange, self._frame("ENTER AREA DESCRIPTION"))
|
||||||
|
|
||||||
|
# If this phrase is not already part of the additional impacts
|
||||||
|
if curPhrase not in sectionDict['additionalImpactRange']:
|
||||||
|
|
||||||
|
# Add it now
|
||||||
|
sectionDict['additionalImpactRange'].append(curPhrase)
|
||||||
|
|
||||||
# If there are additional areas
|
# If there are additional areas
|
||||||
if impactRangeRest != impactMax:
|
if impactRangeRest != impactMax:
|
||||||
sectionDict['additionalImpactRange'].append("Prepare for " +
|
|
||||||
impactRangeRest +
|
curPhrase = "Prepare for %s damage from storm surge across %s." % \
|
||||||
" damage from storm surge " + self._frame("ENTER AREA DESCRIPTION"))
|
(impactRangeRest, self._frame("ENTER AREA DESCRIPTION"))
|
||||||
|
|
||||||
|
# If this phrase is not already part of the additional impacts
|
||||||
|
if curPhrase not in sectionDict['additionalImpactRange']:
|
||||||
|
|
||||||
|
# Add it now
|
||||||
|
sectionDict['additionalImpactRange'].append(curPhrase)
|
||||||
|
|
||||||
# If there is no impact across more than one half the area, include a statement for that as well
|
# If there is no impact across more than one half the area, include a statement for that as well
|
||||||
if inputThreatDominant == "None":
|
if inputThreatDominant == "None":
|
||||||
sectionDict['additionalImpactRange'].append("Elsewhere across " + self._cwa() + ", little to no impact is anticipated.")
|
|
||||||
|
curPhrase = "Elsewhere across " + self._cwa_descriptor() + \
|
||||||
|
", little to no impact is anticipated."
|
||||||
|
|
||||||
|
# If this phrase is not already part of the additional impacts
|
||||||
|
if curPhrase not in sectionDict['additionalImpactRange']:
|
||||||
|
|
||||||
|
# Add it now
|
||||||
|
sectionDict['additionalImpactRange'].append(curPhrase)
|
||||||
|
|
||||||
productDict['surgeSection'] = sectionDict
|
productDict['surgeSection'] = sectionDict
|
||||||
|
|
||||||
def _floodingRainSection(self, productDict, productSegmentGroup, productSegment):
|
def _floodingRainSection(self, productDict, productSegmentGroup, productSegment):
|
||||||
|
@ -443,6 +480,9 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
impactRange = self._samplingDict['FloodingRainThreat']['impactRange']
|
impactRange = self._samplingDict['FloodingRainThreat']['impactRange']
|
||||||
inputThreatDominant = self._samplingDict['FloodingRainThreat']['inputThreatDominant']
|
inputThreatDominant = self._samplingDict['FloodingRainThreat']['inputThreatDominant']
|
||||||
|
|
||||||
|
self.debug_print("In _floodingRainSection", 1)
|
||||||
|
self.debug_print("_samplingDict = %s" % (repr(self._samplingDict['FloodingRainThreat'])), 1)
|
||||||
|
|
||||||
# Test the simplest case first
|
# Test the simplest case first
|
||||||
if impactMin == "none" and impactMax == "none":
|
if impactMin == "none" and impactMax == "none":
|
||||||
sectionDict['impactRange'] = impactRange
|
sectionDict['impactRange'] = impactRange
|
||||||
|
@ -452,7 +492,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
|
|
||||||
# If there is only one impact across the entire CWA, and it is the max
|
# If there is only one impact across the entire CWA, and it is the max
|
||||||
if impactMax != "none" and impactMin == impactMax and inputThreatDominant != "None":
|
if impactMax != "none" and impactMin == impactMax and inputThreatDominant != "None":
|
||||||
sectionDict['impactRange'] = "Prepare for " + impactMax + " flooding across " + self._cwa() + "."
|
sectionDict['impactRange'] = "Prepare for " + impactMax + " flooding across " + self._cwa_descriptor() + "."
|
||||||
# Handle the case where the impacts are not the same across the entire CWA
|
# Handle the case where the impacts are not the same across the entire CWA
|
||||||
else:
|
else:
|
||||||
sectionDict['variedImpacts'] = True
|
sectionDict['variedImpacts'] = True
|
||||||
|
@ -462,14 +502,27 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
|
|
||||||
# If there are additional areas
|
# If there are additional areas
|
||||||
if impactRange != impactMax:
|
if impactRange != impactMax:
|
||||||
sectionDict['additionalImpactRange'].append("Prepare for " +
|
|
||||||
impactRange +
|
curPhrase = "Prepare for %s flooding impacts across %s." % \
|
||||||
" flooding impacts " +
|
(impactRange, self._frame("ENTER AREA DESCRIPTION"))
|
||||||
self._frame("ENTER AREA DESCRIPTION") + ".")
|
|
||||||
|
# If this phrase is not already part of the additional impacts
|
||||||
|
if curPhrase not in sectionDict['additionalImpactRange']:
|
||||||
|
|
||||||
|
# Add it now
|
||||||
|
sectionDict['additionalImpactRange'].append(curPhrase)
|
||||||
|
|
||||||
# If there is no impact across more than one half the area, include a statement for that as well
|
# If there is no impact across more than one half the area, include a statement for that as well
|
||||||
if inputThreatDominant == "None":
|
if inputThreatDominant == "None":
|
||||||
sectionDict['additionalImpactRange'].append("Elsewhere across " + self._cwa() + ", little to no impact is anticipated.")
|
|
||||||
|
curPhrase = "Elsewhere across " + self._cwa_descriptor() + \
|
||||||
|
", little to no impact is anticipated."
|
||||||
|
|
||||||
|
# If this phrase is not already part of the additional impacts
|
||||||
|
if curPhrase not in sectionDict['additionalImpactRange']:
|
||||||
|
|
||||||
|
# Add it now
|
||||||
|
sectionDict['additionalImpactRange'].append(curPhrase)
|
||||||
|
|
||||||
productDict['floodingRainSection'] = sectionDict
|
productDict['floodingRainSection'] = sectionDict
|
||||||
|
|
||||||
|
@ -517,7 +570,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
|
|
||||||
# If there is only one impact across the entire CWA, and it is the max
|
# If there is only one impact across the entire CWA, and it is the max
|
||||||
if impactMax != "none" and impactMin == impactMax and inputThreatDominant != "None":
|
if impactMax != "none" and impactMin == impactMax and inputThreatDominant != "None":
|
||||||
sectionDict['impactRange'] = "Prepare for " + impactMax + " damage across " + self._cwa() + "."
|
sectionDict['impactRange'] = "Prepare for " + impactMax + " damage across " + self._cwa_descriptor() + "."
|
||||||
# Handle the case where the impacts are not the same across the entire CWA
|
# Handle the case where the impacts are not the same across the entire CWA
|
||||||
else:
|
else:
|
||||||
sectionDict['variedImpacts'] = True
|
sectionDict['variedImpacts'] = True
|
||||||
|
@ -527,14 +580,27 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
|
|
||||||
# If there are additional areas
|
# If there are additional areas
|
||||||
if impactRange != impactMax:
|
if impactRange != impactMax:
|
||||||
sectionDict['additionalImpactRange'].append("Prepare for " +
|
|
||||||
impactRange +
|
curPhrase = "Prepare for %s damage across %s." % \
|
||||||
" damage " +
|
(impactRange, self._frame("ENTER AREA DESCRIPTION"))
|
||||||
self._frame("ENTER AREA DESCRIPTION") + ".")
|
|
||||||
|
# If this phrase is not already part of the additional impacts
|
||||||
|
if curPhrase not in sectionDict['additionalImpactRange']:
|
||||||
|
|
||||||
|
# Add it now
|
||||||
|
sectionDict['additionalImpactRange'].append(curPhrase)
|
||||||
|
|
||||||
# If there is no impact across more than one half the area, include a statement for that as well
|
# If there is no impact across more than one half the area, include a statement for that as well
|
||||||
if inputThreatDominant == "None":
|
if inputThreatDominant == "None":
|
||||||
sectionDict['additionalImpactRange'].append("Elsewhere across " + self._cwa() + ", little to no impact is anticipated.")
|
|
||||||
|
curPhrase = "Elsewhere across " + self._cwa_descriptor() + \
|
||||||
|
", little to no impact is anticipated."
|
||||||
|
|
||||||
|
# If this phrase is not already part of the additional impacts
|
||||||
|
if curPhrase not in sectionDict['additionalImpactRange']:
|
||||||
|
|
||||||
|
# Add it now
|
||||||
|
sectionDict['additionalImpactRange'].append(curPhrase)
|
||||||
|
|
||||||
productDict['tornadoSection'] = sectionDict
|
productDict['tornadoSection'] = sectionDict
|
||||||
|
|
||||||
|
@ -565,7 +631,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
actionsDict['title'] = "Other Preparedness Information"
|
actionsDict['title'] = "Other Preparedness Information"
|
||||||
|
|
||||||
import TCVDictionary
|
import TCVDictionary
|
||||||
actionsDict['actions'] = TCVDictionary.OtherPreparednessActions
|
actionsDict['actions'] = TCVDictionary.OtherPreparednessActions[self._GeneralOnsetTime]
|
||||||
|
|
||||||
productDict['otherPreparednessActions'] = actionsDict
|
productDict['otherPreparednessActions'] = actionsDict
|
||||||
|
|
||||||
|
@ -581,15 +647,15 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
def _nextUpdate(self, productDict, productSegmentGroup, productSegment):
|
def _nextUpdate(self, productDict, productSegmentGroup, productSegment):
|
||||||
if self._NextUpdate == "LastIssuance" or not self._ImpactsAnticipated:
|
if self._NextUpdate == "LastIssuance" or not self._ImpactsAnticipated:
|
||||||
productDict['nextUpdate'] = "As it pertains to this event...this will be the last local statement issued by the National Weather Service in " + \
|
productDict['nextUpdate'] = "As it pertains to this event...this will be the last local statement issued by the National Weather Service in " + \
|
||||||
self._cwa() + \
|
self._wfoCityState + \
|
||||||
" regarding the effects of tropical cyclone hazards upon the area."
|
" regarding the effects of tropical cyclone hazards upon the area."
|
||||||
elif self._NextUpdate == "Conditions":
|
elif self._NextUpdate == "Conditions":
|
||||||
productDict['nextUpdate'] = "The next local statement will be issued by the National Weather Service in " + \
|
productDict['nextUpdate'] = "The next local statement will be issued by the National Weather Service in " + \
|
||||||
self._cwa() + \
|
self._wfoCityState + \
|
||||||
" as conditions warrant."
|
" as conditions warrant."
|
||||||
elif self._NextUpdate == "Enter":
|
elif self._NextUpdate == "Enter":
|
||||||
productDict['nextUpdate'] = "The next local statement will be issued by the National Weather Service in " + \
|
productDict['nextUpdate'] = "The next local statement will be issued by the National Weather Service in " + \
|
||||||
self._cwa() + \
|
self._wfoCityState + \
|
||||||
" around " + self._NextUpdate_entry.strip() + ", or sooner if conditions warrant."
|
" around " + self._NextUpdate_entry.strip() + ", or sooner if conditions warrant."
|
||||||
|
|
||||||
def _getPotentialImpactsStatements(self, elementName, maxThreat):
|
def _getPotentialImpactsStatements(self, elementName, maxThreat):
|
||||||
|
@ -621,6 +687,10 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
if error is not None:
|
if error is not None:
|
||||||
return error
|
return error
|
||||||
|
|
||||||
|
# Determine time ranges
|
||||||
|
self._initializeTimeVariables(argDict)
|
||||||
|
self._determineTimeRanges(argDict)
|
||||||
|
|
||||||
error = self._initializeStormInformation()
|
error = self._initializeStormInformation()
|
||||||
if error is not None:
|
if error is not None:
|
||||||
return error
|
return error
|
||||||
|
@ -629,41 +699,25 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
if self._stormName is None or self._stormName.strip() == "":
|
if self._stormName is None or self._stormName.strip() == "":
|
||||||
return "Could not determine the storm name"
|
return "Could not determine the storm name"
|
||||||
|
|
||||||
|
self._loadLastTwoAdvisories()
|
||||||
|
if self._previousAdvisory is None:
|
||||||
|
return "A TCV must be transmitted before an HLS can be run"
|
||||||
|
|
||||||
self._initializeHeadlines()
|
self._initializeHeadlines()
|
||||||
|
|
||||||
self._initializeHazardsTable(argDict)
|
self._initializeHazardsTable(argDict)
|
||||||
|
|
||||||
self._determineHazardStates()
|
self._determineHazardStates()
|
||||||
|
|
||||||
# Determine time ranges
|
if self._ImpactsAnticipated:
|
||||||
self._initializeTimeVariables(argDict)
|
# Sample the data
|
||||||
self._determineTimeRanges(argDict)
|
self._initializeSamplingDict()
|
||||||
|
|
||||||
# Sample the data
|
|
||||||
self._initializeSamplingDict()
|
|
||||||
|
|
||||||
previousAdvisory = self._loadAdvisory("previous")
|
|
||||||
if previousAdvisory is not None:
|
|
||||||
self._sampleTCVAdvisory(previousAdvisory)
|
|
||||||
else:
|
|
||||||
self._segmentList = self._determineSegments()
|
|
||||||
print "Segment Information: ", self._segmentList, "\n\n"
|
|
||||||
if len(self._segmentList) == 0:
|
|
||||||
return "NO HAZARDS TO REPORT"
|
|
||||||
|
|
||||||
self._initializeAdvisories()
|
self._sampleHLSData(argDict)
|
||||||
self._sampleTCVData(argDict)
|
|
||||||
for segment in self._segmentList:
|
for threatName in ['WindThreat', 'StormSurgeThreat', 'FloodingRainThreat', 'TornadoThreat']:
|
||||||
self._initializeSegmentZoneData(segment)
|
self._setHazardImpactCategories(threatName)
|
||||||
self._getTCVStats(argDict, segment, self._editAreaDict, self._timeRangeList)
|
|
||||||
|
|
||||||
self._sampleTCVAdvisory(self._currentAdvisory)
|
|
||||||
|
|
||||||
self._sampleHLSData(argDict)
|
|
||||||
|
|
||||||
for threatName in ['WindThreat', 'StormSurgeThreat', 'FloodingRainThreat', 'TornadoThreat']:
|
|
||||||
self._setHazardImpactCategories(threatName)
|
|
||||||
|
|
||||||
# Create the product dictionary and format it to create the output
|
# Create the product dictionary and format it to create the output
|
||||||
productDict = self._createProductDictionary()
|
productDict = self._createProductDictionary()
|
||||||
productOutput = self._formatProductDictionary(productDict)
|
productOutput = self._formatProductDictionary(productDict)
|
||||||
|
@ -672,16 +726,14 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
|
|
||||||
|
|
||||||
def _determineHazardStates(self):
|
def _determineHazardStates(self):
|
||||||
hazardTable = self._argDict["hazards"]
|
|
||||||
hazardsList = hazardTable.getHazardList(self._allAreas())
|
|
||||||
self._currentHazardsList = []
|
self._currentHazardsList = []
|
||||||
self._changesHazardsList = []
|
self._changesHazardsList = []
|
||||||
for hazard in hazardsList:
|
|
||||||
if hazard['act'] == 'CON':
|
for hazard in self._previousAdvisory["HazardsForHLS"]:
|
||||||
self._currentHazardsList.append(hazard)
|
print "SARAH DEBUG Hazard: %s" % (repr(hazard))
|
||||||
else:
|
if hazard['act'] != 'CON':
|
||||||
self._changesHazardsList.append(hazard)
|
self._changesHazardsList.append(hazard)
|
||||||
|
self._currentHazardsList.append(hazard)
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
### Sampling and Statistics related methods
|
### Sampling and Statistics related methods
|
||||||
|
@ -698,18 +750,24 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
self._cwa())
|
self._cwa())
|
||||||
|
|
||||||
for period in range(len(statList)):
|
for period in range(len(statList)):
|
||||||
|
|
||||||
|
self.debug_print("=" * 100, 1)
|
||||||
|
self.debug_print("In _sampleHLSData for period %s (%s)" % \
|
||||||
|
(period, repr(self._timeRangeList[period][0])), 1)
|
||||||
|
|
||||||
statDict = statList[period]
|
statDict = statList[period]
|
||||||
for threatName in ['WindThreat', 'FloodingRainThreat', 'TornadoThreat']:
|
for threatName in ['WindThreat', 'FloodingRainThreat', 'TornadoThreat']:
|
||||||
self._sampleThreatGrid(threatName, statDict)
|
self._sampleRankedDiscreteValue(threatName, statDict)
|
||||||
|
self._sampleMostSignificantDiscreteValue(threatName, statDict)
|
||||||
|
|
||||||
qpfToFfgRatio = self._getStatValue(statDict, "QPFtoFFGRatio", "Max")
|
qpfToFfgRatio = self._getStatValue(statDict, "QPFtoFFGRatio", "Max")
|
||||||
decidingField = self._samplingDict['FloodingRainThreat']['decidingField']
|
decidingField = self._samplingDict['FloodingRainThreat']['decidingField']
|
||||||
if decidingField is None or qpfToFfgRatio > decidingField:
|
if decidingField is None or qpfToFfgRatio > decidingField:
|
||||||
self._samplingDict['FloodingRainThreat']['decidingField'] = qpfToFfgRatio
|
self._samplingDict['FloodingRainThreat']['decidingField'] = qpfToFfgRatio
|
||||||
|
|
||||||
print "SARAH: WindThreat =", self._samplingDict['WindThreat']['inputThreatDominant']
|
print "SARAH: WindThreat = %s" % (self._samplingDict['WindThreat']['inputThreatDominant'])
|
||||||
print "SARAH: FloodingRainThreat =", self._samplingDict['FloodingRainThreat']['inputThreatDominant']
|
print "SARAH: FloodingRainThreat = %s" % (self._samplingDict['FloodingRainThreat']['inputThreatDominant'])
|
||||||
print "SARAH: TornadoThreat =", self._samplingDict['TornadoThreat']['inputThreatDominant']
|
print "SARAH: TornadoThreat = %s" % (self._samplingDict['TornadoThreat']['inputThreatDominant'])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -744,14 +802,15 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
|
|
||||||
for period in range(len(statList)):
|
for period in range(len(statList)):
|
||||||
statDict = statList[period]
|
statDict = statList[period]
|
||||||
self._sampleThreatGrid('StormSurgeThreat', statDict)
|
self._sampleRankedDiscreteValue('StormSurgeThreat', statDict)
|
||||||
|
self._sampleMostSignificantDiscreteValue('StormSurgeThreat', statDict)
|
||||||
|
|
||||||
inundationMax = self._getStatValue(statDict, "InundationMax", "Max")
|
inundationMax = self._getStatValue(statDict, "InundationMax", "Max")
|
||||||
decidingField = self._samplingDict['StormSurgeThreat']['decidingField']
|
decidingField = self._samplingDict['StormSurgeThreat']['decidingField']
|
||||||
if decidingField is None or inundationMax > decidingField:
|
if decidingField is None or inundationMax > decidingField:
|
||||||
self._samplingDict['StormSurgeThreat']['decidingField'] = inundationMax
|
self._samplingDict['StormSurgeThreat']['decidingField'] = inundationMax
|
||||||
|
|
||||||
print "SARAH: StormSurgeThreat =", self._samplingDict['StormSurgeThreat']['inputThreatDominant']
|
print "SARAH: StormSurgeThreat = %s" % (self._samplingDict['StormSurgeThreat']['inputThreatDominant'])
|
||||||
|
|
||||||
def _createWholeDomainEditArea(self, argDict):
|
def _createWholeDomainEditArea(self, argDict):
|
||||||
editAreaUtils = EditAreaUtils.EditAreaUtils()
|
editAreaUtils = EditAreaUtils.EditAreaUtils()
|
||||||
|
@ -765,16 +824,44 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
refData = ReferenceData(gridLoc, refID, grid2Dbit)
|
refData = ReferenceData(gridLoc, refID, grid2Dbit)
|
||||||
editAreaUtils.saveEditAreas([refData])
|
editAreaUtils.saveEditAreas([refData])
|
||||||
|
|
||||||
def _sampleThreatGrid(self, threatName, statDict):
|
def _sampleMostSignificantDiscreteValue(self, threatName, statDict):
|
||||||
rankedThreatLevels = self.getStats(statDict, threatName)
|
print "SARAH: _sampleMostSignificantDiscreteValue for %s" % (threatName)
|
||||||
print "SARAH: sampling", threatName
|
threatLevel = self.getStats(statDict, threatName + "__mostSignificantDiscreteValue")
|
||||||
print "SARAH: sampleData: rankedThreatLevels =", rankedThreatLevels
|
print "SARAH: threatLevel =", threatLevel
|
||||||
dominantThreatLevel = self._getDominantThreatLevel(threatName, rankedThreatLevels)
|
if threatLevel is not None:
|
||||||
|
inputThreatLow = self._samplingDict[threatName]['inputThreatLow']
|
||||||
currentDominantThreatLevel = self._samplingDict[threatName]['inputThreatDominant']
|
print "SARAH: current inputThreatLow =", inputThreatLow
|
||||||
self._samplingDict[threatName]['inputThreatDominant'] = self._getHighestThreat(threatName,
|
if inputThreatLow is None:
|
||||||
dominantThreatLevel,
|
self._samplingDict[threatName]['inputThreatLow'] = threatLevel
|
||||||
currentDominantThreatLevel)
|
else:
|
||||||
|
self._samplingDict[threatName]['inputThreatLow'] = self._getLowestThreat(threatName,
|
||||||
|
threatLevel,
|
||||||
|
inputThreatLow)
|
||||||
|
print "SARAH: new inputThreatLow =", self._samplingDict[threatName]['inputThreatLow']
|
||||||
|
|
||||||
|
inputThreatHigh = self._samplingDict[threatName]['inputThreatHigh']
|
||||||
|
print "SARAH: current inputThreatHigh =", inputThreatHigh
|
||||||
|
self._samplingDict[threatName]['inputThreatHigh'] = self._getHighestThreat(threatName,
|
||||||
|
threatLevel,
|
||||||
|
inputThreatHigh)
|
||||||
|
print "SARAH: new inputThreatHigh =", self._samplingDict[threatName]['inputThreatHigh']
|
||||||
|
|
||||||
|
def _sampleRankedDiscreteValue(self, threatName, statDict):
|
||||||
|
print "-" * 60
|
||||||
|
print "_sampleRankedDiscreteValue statDict = %s" % (repr(statDict))
|
||||||
|
rankedThreatLevels = self.getStats(statDict, threatName + "__rankedDiscreteValue")
|
||||||
|
print "SARAH: sampling %s" % (threatName)
|
||||||
|
print "SARAH: sampleData: rankedThreatLevels = %s" % (repr(rankedThreatLevels))
|
||||||
|
if rankedThreatLevels is not None:
|
||||||
|
dominantThreatLevel = self._getDominantThreatLevel(threatName, rankedThreatLevels)
|
||||||
|
print "SARAH: dominantThreatLevel =", dominantThreatLevel
|
||||||
|
|
||||||
|
currentDominantThreatLevel = self._samplingDict[threatName]['inputThreatDominant']
|
||||||
|
print "SARAH: currentDominantThreatLevel =", currentDominantThreatLevel
|
||||||
|
self._samplingDict[threatName]['inputThreatDominant'] = self._getHighestThreat(threatName,
|
||||||
|
dominantThreatLevel,
|
||||||
|
currentDominantThreatLevel)
|
||||||
|
print "SARAH: new dominant =", self._samplingDict[threatName]['inputThreatDominant']
|
||||||
|
|
||||||
def _getDominantThreatLevel(self, threatName, rankedThreatLevels):
|
def _getDominantThreatLevel(self, threatName, rankedThreatLevels):
|
||||||
dominantLevelWithHighestRank = None
|
dominantLevelWithHighestRank = None
|
||||||
|
@ -805,6 +892,20 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
else:
|
else:
|
||||||
return threatLevel1
|
return threatLevel1
|
||||||
|
|
||||||
|
def _getLowestThreat(self, threatName, threatLevel1, threatLevel2):
|
||||||
|
keyOrderDict = self.mostSignificantDiscrete_keyOrder_dict(None, None, None)
|
||||||
|
keyOrder = keyOrderDict[threatName]
|
||||||
|
|
||||||
|
level1Index = keyOrder.index(threatLevel1)
|
||||||
|
level2Index = keyOrder.index(threatLevel2)
|
||||||
|
|
||||||
|
if level1Index < level2Index:
|
||||||
|
return threatLevel1
|
||||||
|
elif level1Index == level2Index:
|
||||||
|
return threatLevel1
|
||||||
|
else:
|
||||||
|
return threatLevel2
|
||||||
|
|
||||||
def _initializeVariables(self, argDict):
|
def _initializeVariables(self, argDict):
|
||||||
# Get variables
|
# Get variables
|
||||||
error = self._getVariables(argDict)
|
error = self._getVariables(argDict)
|
||||||
|
@ -860,15 +961,16 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
def _sampleTCVAdvisory(self, advisory):
|
def _sampleTCVAdvisory(self, advisory):
|
||||||
print "SARAH: sampling TCV advisory!"
|
print "SARAH: sampling TCV advisory!"
|
||||||
for zone in advisory["ZoneData"]:
|
for zone in advisory["ZoneData"]:
|
||||||
print "Looking at zone", zone
|
print "-" * 60
|
||||||
|
print "Looking at zone %s" % (zone)
|
||||||
for key in advisory["ZoneData"][zone]:
|
for key in advisory["ZoneData"][zone]:
|
||||||
if "Threat" not in key:
|
if "Threat" not in key:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
print "Looking at key", key
|
print "Looking at key '%s'" % (key)
|
||||||
|
|
||||||
threatLevel = advisory["ZoneData"][zone][key]
|
threatLevel = advisory["ZoneData"][zone][key]
|
||||||
print "Threat level =", threatLevel
|
print " Threat level = %s" % (threatLevel)
|
||||||
if self._samplingDict[key]['inputThreatLow'] is None:
|
if self._samplingDict[key]['inputThreatLow'] is None:
|
||||||
self._samplingDict[key]['inputThreatLow'] = threatLevel
|
self._samplingDict[key]['inputThreatLow'] = threatLevel
|
||||||
if self._samplingDict[key]['inputThreatHigh'] is None:
|
if self._samplingDict[key]['inputThreatHigh'] is None:
|
||||||
|
@ -883,13 +985,13 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
if threatOrder.index(threatLevel) > threatOrder.index(highThreat):
|
if threatOrder.index(threatLevel) > threatOrder.index(highThreat):
|
||||||
highThreat = threatLevel
|
highThreat = threatLevel
|
||||||
|
|
||||||
print "low threat =", lowThreat
|
print " low threat = %s" % (lowThreat)
|
||||||
print "high threat =", highThreat
|
print " high threat = %s" % (highThreat)
|
||||||
|
|
||||||
self._samplingDict[key]['inputThreatLow'] = lowThreat
|
self._samplingDict[key]['inputThreatLow'] = lowThreat
|
||||||
self._samplingDict[key]['inputThreatHigh'] = highThreat
|
self._samplingDict[key]['inputThreatHigh'] = highThreat
|
||||||
|
|
||||||
print "Sampling dict =", self._samplingDict
|
print "Sampling dict = %s" % (repr(self._samplingDict))
|
||||||
|
|
||||||
def _setHazardImpactCategories(self, threatName):
|
def _setHazardImpactCategories(self, threatName):
|
||||||
inputThreatLow = self._samplingDict[threatName]['inputThreatLow']
|
inputThreatLow = self._samplingDict[threatName]['inputThreatLow']
|
||||||
|
@ -897,7 +999,10 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
inputThreatDominant = self._samplingDict[threatName]['inputThreatDominant']
|
inputThreatDominant = self._samplingDict[threatName]['inputThreatDominant']
|
||||||
decidingField = self._samplingDict[threatName]['decidingField']
|
decidingField = self._samplingDict[threatName]['decidingField']
|
||||||
catastrophicThreshold = self._samplingDict[threatName]['catastrophicThreshold']
|
catastrophicThreshold = self._samplingDict[threatName]['catastrophicThreshold']
|
||||||
|
|
||||||
|
print "-" * 60
|
||||||
|
print "MATT DEBUG: _setHazardImpactCategories for %s" % (threatName)
|
||||||
|
|
||||||
impactMin = None
|
impactMin = None
|
||||||
impactMax = None
|
impactMax = None
|
||||||
impactRange = None
|
impactRange = None
|
||||||
|
@ -926,22 +1031,25 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
else:
|
else:
|
||||||
impactMax = "devastating"
|
impactMax = "devastating"
|
||||||
impactRangeMax = "extensive"
|
impactRangeMax = "extensive"
|
||||||
elif inputThreatLow == "High":
|
elif inputThreatHigh == "High":
|
||||||
impactMax = "extensive"
|
impactMax = "extensive"
|
||||||
impactRangeMax = "significant"
|
impactRangeMax = "significant"
|
||||||
elif inputThreatLow == "Mod":
|
elif inputThreatHigh == "Mod":
|
||||||
impactMax = "significant"
|
impactMax = "significant"
|
||||||
impactRangeMax = "limited"
|
impactRangeMax = "limited"
|
||||||
elif inputThreatLow == "Elevated":
|
elif inputThreatHigh == "Elevated":
|
||||||
impactMax = "limited"
|
impactMax = "limited"
|
||||||
impactRangeMax = "none"
|
impactRangeMax = "none"
|
||||||
else:
|
else:
|
||||||
impactMax = "none"
|
impactMax = "none"
|
||||||
impactRangeMax = "none"
|
impactRangeMax = "none"
|
||||||
|
|
||||||
|
print "MATT DEBUG: impactMin = '%s' impactMax = '%s' impactRangeMax = '%s'" % \
|
||||||
|
(impactMin, impactMax, impactRangeMax)
|
||||||
|
|
||||||
# Determine dominant impact category for rest of CWA - No impact
|
# Determine dominant impact category for rest of CWA - No impact
|
||||||
if impactMin == "none" and impactMax == "none":
|
if impactMin == "none" and impactMax == "none":
|
||||||
impactRange = "No impacts are anticipated at this time across " + self._cwa() + "."
|
impactRange = "No impacts are anticipated at this time across " + self._cwa_descriptor() + "."
|
||||||
# Otherwise, at least some impact will be experienced across the CWA
|
# Otherwise, at least some impact will be experienced across the CWA
|
||||||
else:
|
else:
|
||||||
# Do not permit the lowest category to be "None", if the highest category is also not "None"
|
# Do not permit the lowest category to be "None", if the highest category is also not "None"
|
||||||
|
@ -967,18 +1075,29 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
# Fixed pattern to grab headline (MHB 04/08/2009)
|
# Fixed pattern to grab headline (MHB 04/08/2009)
|
||||||
# See if there is a headline in this text
|
# See if there is a headline in this text
|
||||||
headlineSearch = re.findall("(?ism)^(\.{3}.+?\.{3}) *\n", text)
|
headlineSearch = re.findall("(?ism)^(\.{3}.+?\.{3}) *\n", text)
|
||||||
|
|
||||||
|
# If we could not find original headlines, try to use 'new' HLS style
|
||||||
|
if headlineSearch is None:
|
||||||
|
headlineSearch = re.findall("(?ism)^\*\*.+?\*\* *\n", text)
|
||||||
|
|
||||||
self.debug_print("headlineSearch = %s" % (headlineSearch))
|
self.debug_print("headlineSearch = %s" % (headlineSearch))
|
||||||
|
|
||||||
# If we found a headline
|
# If we found a headline
|
||||||
if len(headlineSearch) > 0:
|
if len(headlineSearch) > 0:
|
||||||
|
|
||||||
|
# Remove the first and last ellipses - if they exist
|
||||||
|
headlineSearch[0] = re.sub("^\.\.\.", "", headlineSearch[0])
|
||||||
|
headlineSearch[0] = re.sub("\.\.\.$", "", headlineSearch[0])
|
||||||
|
|
||||||
|
# # Remove the first and last '**' - if they exist
|
||||||
|
# headlineSearch[0] = headlineSearch[0].sub("**", "").strip()
|
||||||
|
|
||||||
# Return the first cleaned-up headline string we found
|
# Return the first cleaned-up headline string we found
|
||||||
return self._cleanText(headlineSearch[0])
|
return self._cleanText(headlineSearch[0])
|
||||||
|
|
||||||
# Otherwise, return an indicator there is no headline in this text
|
# Otherwise, return an indicator there is no headline in this text
|
||||||
else:
|
else:
|
||||||
return '' # Changed to an null string instead of None
|
return "" # Changed to an null string instead of None
|
||||||
# (MHB 04/08/2009)
|
# (MHB 04/08/2009)
|
||||||
|
|
||||||
def _determineHazards(self, segments):
|
def _determineHazards(self, segments):
|
||||||
|
@ -1071,18 +1190,18 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
self._stormIntensityTrend = "Storm Intensity " + stormDict.get("StormIntensity","")
|
self._stormIntensityTrend = "Storm Intensity " + stormDict.get("StormIntensity","")
|
||||||
|
|
||||||
print "SARAH: BEGIN STORM INFORMATION"
|
print "SARAH: BEGIN STORM INFORMATION"
|
||||||
print "storm dict =", stormDict
|
print "storm dict = %s" % (stormDict)
|
||||||
print "storm name =", self._stormName
|
print "storm name = %s" % (self._stormName)
|
||||||
print "type =", self._stormType
|
print "type = %s" % (self._stormType)
|
||||||
print "type name =", self._stormTypeName
|
print "type name = %s" % (self._stormTypeName)
|
||||||
print "time =", self._stormTime
|
print "time = %s" % (self._stormTime)
|
||||||
print "lat =", self._stormLat
|
print "lat = %s" % (self._stormLat)
|
||||||
print "lon =", self._stormLon
|
print "lon = %s" % (self._stormLon)
|
||||||
print "location =", self._stormLocation
|
print "location = %s" % (str(self._stormLocation))
|
||||||
print "reference =", self._stormReference
|
print "reference = %s" % (self._stormReference)
|
||||||
print "references =", self._stormLocalReferences
|
print "references = %s" % (self._stormLocalReferences)
|
||||||
print "movement trend =", self._stormMovementTrend
|
print "movement trend = %s" % (self._stormMovementTrend)
|
||||||
print "intensity trend =", self._stormIntensityTrend
|
print "intensity trend = %s" % (self._stormIntensityTrend)
|
||||||
print "SARAH: END STORM INFORMATION"
|
print "SARAH: END STORM INFORMATION"
|
||||||
|
|
||||||
def _grabStormInfo(self, tcp):
|
def _grabStormInfo(self, tcp):
|
||||||
|
@ -1758,7 +1877,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
removedParts.append(part)
|
removedParts.append(part)
|
||||||
|
|
||||||
for part in removedParts:
|
for part in removedParts:
|
||||||
print "SARAH: Removing part =", part
|
print "SARAH: Removing part = %s" % (part)
|
||||||
partsList.remove(part)
|
partsList.remove(part)
|
||||||
|
|
||||||
def _noOpParts(self):
|
def _noOpParts(self):
|
||||||
|
@ -1805,7 +1924,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
upgPhenSig = record['phen'] + "." + record['sig']
|
upgPhenSig = record['phen'] + "." + record['sig']
|
||||||
newRecord = self._findNEWAssociatedWithUPG(upgPhenSig, vtecRecords)
|
newRecord = self._findNEWAssociatedWithUPG(upgPhenSig, vtecRecords)
|
||||||
record['new_record'] = newRecord
|
record['new_record'] = newRecord
|
||||||
print "SARAH: vtecRecord =", record
|
print "SARAH: vtecRecord = %s" % (repr(record))
|
||||||
segment_vtecRecords_tuples.append((segment, vtecRecords))
|
segment_vtecRecords_tuples.append((segment, vtecRecords))
|
||||||
|
|
||||||
productSegmentGroup = {
|
productSegmentGroup = {
|
||||||
|
@ -1888,7 +2007,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
def _initializeHazardsTable(self, argDict):
|
def _initializeHazardsTable(self, argDict):
|
||||||
import VTECMessageType
|
import VTECMessageType
|
||||||
productID = self._pil[0:3]
|
productID = self._pil[0:3]
|
||||||
vtecMode = VTECMessageType.getVTECMessageType(productID)
|
vtecMode = VTECMessageType.getVTECMessageType(productID.upper())
|
||||||
argDict["vtecMode"] = vtecMode
|
argDict["vtecMode"] = vtecMode
|
||||||
|
|
||||||
self._setVTECActiveTable(argDict)
|
self._setVTECActiveTable(argDict)
|
||||||
|
@ -1902,6 +2021,11 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
def _setVTECActiveTable(self, argDict):
|
def _setVTECActiveTable(self, argDict):
|
||||||
dataMgr = argDict["dataMgr"]
|
dataMgr = argDict["dataMgr"]
|
||||||
gfeMode = dataMgr.getOpMode().name()
|
gfeMode = dataMgr.getOpMode().name()
|
||||||
|
|
||||||
|
print "*" *100
|
||||||
|
print "gfeMode = '%s'" % (gfeMode)
|
||||||
|
print "*" *100
|
||||||
|
|
||||||
|
|
||||||
if gfeMode == "PRACTICE":
|
if gfeMode == "PRACTICE":
|
||||||
argDict["vtecActiveTable"] = "PRACTICE"
|
argDict["vtecActiveTable"] = "PRACTICE"
|
||||||
|
@ -1960,7 +2084,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
("Tornadoes", 'tornadoSection'),
|
("Tornadoes", 'tornadoSection'),
|
||||||
("Other Coastal Hazards", 'coastalHazardsSection')
|
("Other Coastal Hazards", 'coastalHazardsSection')
|
||||||
],
|
],
|
||||||
"default": ["Wind", "Surge", "Flooding Rain", "Tornadoes", "Other Coastal Hazards"],
|
"default": ["Wind", "Surge", "Flooding Rain", "Tornadoes"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name":"LocalReferencePoints",
|
"name":"LocalReferencePoints",
|
||||||
|
@ -1971,14 +2095,14 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
"default": self._localReferencePoints_defaults(),
|
"default": self._localReferencePoints_defaults(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MainHeadline",
|
"name":"GeneralOnsetTime",
|
||||||
"label": "Step 5. Input Main Headline (required)",
|
"label": "Step 5. General Time to Onset",
|
||||||
"options": [
|
"options": [
|
||||||
("Enter Unique Headline (below)", "Enter"),
|
("Watch", 'check plans'),
|
||||||
("Use Previous HLS Headline", "UsePrev"),
|
("Warning", 'complete preparations'),
|
||||||
("Use Latest TCP Headline", "UseTCP"),
|
("Conditions/Ongoing", 'hunker down'),
|
||||||
],
|
("Recovery", 'recovery'),
|
||||||
"entryField": " ",
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "NextUpdate",
|
"name": "NextUpdate",
|
||||||
|
@ -1991,6 +2115,16 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
||||||
"default": "Shortly",
|
"default": "Shortly",
|
||||||
"entryField": " e.g. 6 AM EDT",
|
"entryField": " e.g. 6 AM EDT",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "MainHeadline",
|
||||||
|
"label": "Step 7. Input Main Headline (required)",
|
||||||
|
"options": [
|
||||||
|
("Enter Unique Headline (below)", "Enter"),
|
||||||
|
("Use Previous HLS Headline", "UsePrev"),
|
||||||
|
("Use Latest TCP Headline", "UseTCP"),
|
||||||
|
],
|
||||||
|
"entryField": " ",
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
def _displayGUI(self, infoDict=None):
|
def _displayGUI(self, infoDict=None):
|
||||||
|
@ -2043,10 +2177,12 @@ class Overview_Dialog(HLSTCV_Common.Common_Dialog):
|
||||||
boxNum = 0
|
boxNum = 0
|
||||||
buttonSide=Tkinter.TOP
|
buttonSide=Tkinter.TOP
|
||||||
frameSide = Tkinter.LEFT
|
frameSide = Tkinter.LEFT
|
||||||
elif index in [3,4]:
|
elif index in [3,4,5]:
|
||||||
boxNum = 1
|
boxNum = 1
|
||||||
buttonSide=Tkinter.LEFT
|
# buttonSide=Tkinter.LEFT
|
||||||
frameSide=Tkinter.TOP
|
# frameSide=Tkinter.TOP
|
||||||
|
buttonSide=Tkinter.TOP
|
||||||
|
frameSide=Tkinter.LEFT
|
||||||
else:
|
else:
|
||||||
boxNum = 2
|
boxNum = 2
|
||||||
buttonSide=Tkinter.TOP
|
buttonSide=Tkinter.TOP
|
||||||
|
@ -2126,7 +2262,7 @@ class Overview_Dialog(HLSTCV_Common.Common_Dialog):
|
||||||
frame = Tkinter.Frame(master)
|
frame = Tkinter.Frame(master)
|
||||||
buttonList = self._parent._GUI1_configDict().get("buttonList", [])
|
buttonList = self._parent._GUI1_configDict().get("buttonList", [])
|
||||||
for button, label in buttonList:
|
for button, label in buttonList:
|
||||||
if button == "Next":
|
if button == "Run":
|
||||||
command = self.okCB
|
command = self.okCB
|
||||||
else: # Cancel
|
else: # Cancel
|
||||||
command = self.cancelCB
|
command = self.cancelCB
|
||||||
|
@ -2157,7 +2293,7 @@ class Overview_Dialog(HLSTCV_Common.Common_Dialog):
|
||||||
checkList.append((options[i], svar.get()))
|
checkList.append((options[i], svar.get()))
|
||||||
else:
|
else:
|
||||||
if ivarList[i].get():
|
if ivarList[i].get():
|
||||||
print "SARAH: adding option =", options[i]
|
print "SARAH: adding option = %s" % (repr(options[i]))
|
||||||
checkList.append(options[i])
|
checkList.append(options[i])
|
||||||
value = checkList
|
value = checkList
|
||||||
self._setVarDict(name, value)
|
self._setVarDict(name, value)
|
||||||
|
@ -2195,7 +2331,7 @@ class LegacyFormatter():
|
||||||
@return text -- product string
|
@return text -- product string
|
||||||
'''
|
'''
|
||||||
text = ''
|
text = ''
|
||||||
print "SARAH: productParts =", productParts
|
print "SARAH: productParts = %s" % (productParts)
|
||||||
for part in productParts:
|
for part in productParts:
|
||||||
valtype = type(part)
|
valtype = type(part)
|
||||||
if valtype is str:
|
if valtype is str:
|
||||||
|
@ -2203,11 +2339,11 @@ class LegacyFormatter():
|
||||||
elif valtype is tuple:
|
elif valtype is tuple:
|
||||||
name = part[0]
|
name = part[0]
|
||||||
infoDicts = part[1]
|
infoDicts = part[1]
|
||||||
print "SARAH: name =", str(name)
|
print "SARAH: name = %s" % (str(name))
|
||||||
print "SARAH: infoDicts =", infoDicts
|
print "SARAH: infoDicts = %s" % (repr(infoDicts))
|
||||||
newtext = self.processSubParts(productDict.get(name), infoDicts)
|
newtext = self.processSubParts(productDict.get(name), infoDicts)
|
||||||
print "SARAH: newtext type =", type(newtext)
|
print "SARAH: newtext type = %s" % (type(newtext))
|
||||||
print "SARAH: newtext =", repr(newtext)
|
print "SARAH: newtext = %s" % (repr(newtext))
|
||||||
text += newtext
|
text += newtext
|
||||||
continue
|
continue
|
||||||
elif valtype is list:
|
elif valtype is list:
|
||||||
|
@ -2291,8 +2427,8 @@ class LegacyFormatter():
|
||||||
text += '&&\n'
|
text += '&&\n'
|
||||||
elif name not in self._noOpParts():
|
elif name not in self._noOpParts():
|
||||||
textStr = productDict.get(name)
|
textStr = productDict.get(name)
|
||||||
print "SARAH: name =", name
|
print "SARAH: name = %s" % (name)
|
||||||
print "SARAH: textStr =", textStr
|
print "SARAH: textStr = '%s'" % (textStr)
|
||||||
if textStr:
|
if textStr:
|
||||||
text += textStr + '\n'
|
text += textStr + '\n'
|
||||||
return text
|
return text
|
||||||
|
@ -2355,7 +2491,7 @@ class LegacyFormatter():
|
||||||
text += self._textProduct.indentText("**" + headline + "**\n",
|
text += self._textProduct.indentText("**" + headline + "**\n",
|
||||||
maxWidth=self._textProduct._lineLength)
|
maxWidth=self._textProduct._lineLength)
|
||||||
|
|
||||||
text = self._textProduct._frame(text) + "\n"
|
text = self._textProduct._frame(text) + "\n\n"
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
@ -2456,13 +2592,32 @@ class LegacyFormatter():
|
||||||
text += "\n"
|
text += "\n"
|
||||||
|
|
||||||
additionalImpactRangeText = ""
|
additionalImpactRangeText = ""
|
||||||
|
curAdditionalImpactText = ""
|
||||||
|
count = 1
|
||||||
for additionalImpact in sectionDict['additionalImpactRange']:
|
for additionalImpact in sectionDict['additionalImpactRange']:
|
||||||
additionalImpactRangeText += additionalImpact + " "
|
|
||||||
|
curAdditionalImpactText += \
|
||||||
|
self._textProduct.indentText(additionalImpact,
|
||||||
|
maxWidth=self._textProduct._lineLength)
|
||||||
|
|
||||||
|
if count != len(sectionDict['additionalImpactRange']) and \
|
||||||
|
len(curAdditionalImpactText) > 0:
|
||||||
|
curAdditionalImpactText += "\n"
|
||||||
|
|
||||||
|
# If this additional impact is not already included in the output
|
||||||
|
if additionalImpactRangeText.find(curAdditionalImpactText) == -1:
|
||||||
|
|
||||||
|
# Add this additional impact text
|
||||||
|
print "Adding current impact."
|
||||||
|
additionalImpactRangeText += curAdditionalImpactText
|
||||||
|
count += 1
|
||||||
|
|
||||||
# Remove the trailing space
|
# Remove the trailing space
|
||||||
additionalImpactRangeText = additionalImpactRangeText[:-1]
|
# additionalImpactRangeText = additionalImpactRangeText[:-1]
|
||||||
|
|
||||||
text += self._textProduct.indentText(additionalImpactRangeText, maxWidth=self._textProduct._lineLength)
|
# text += self._textProduct.indentText(additionalImpactRangeText, maxWidth=self._textProduct._lineLength)
|
||||||
|
|
||||||
|
text += additionalImpactRangeText
|
||||||
|
|
||||||
text += "\n"
|
text += "\n"
|
||||||
return text
|
return text
|
||||||
|
@ -2476,10 +2631,10 @@ class LegacyFormatter():
|
||||||
"""
|
"""
|
||||||
text = ''
|
text = ''
|
||||||
for i in range(len(subParts)):
|
for i in range(len(subParts)):
|
||||||
print "SARAH: subpart subParts[i] =", subParts[i]
|
print "SARAH: subpart subParts[i] = %s" % (subParts[i])
|
||||||
print "SARAH: subpart infoDicts[i] =", infoDicts[i]
|
print "SARAH: subpart infoDicts[i] = %s" % (infoDicts[i])
|
||||||
newtext = self._processProductParts(subParts[i], infoDicts[i].get('partsList'))
|
newtext = self._processProductParts(subParts[i], infoDicts[i].get('partsList'))
|
||||||
print "SARAH: subpart newtext type =", type(newtext)
|
print "SARAH: subpart newtext type = %s" % (type(newtext))
|
||||||
print "SARAH: subpart newtext =", repr(newtext)
|
print "SARAH: subpart newtext = '%s'" % (repr(newtext))
|
||||||
text += newtext
|
text += newtext
|
||||||
return text
|
return text
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue