Merge branch 'master_14.3.2' into asm_14.3.2

Former-commit-id: 6296329c20f11180f3e1556ae0681d736d71020d
This commit is contained in:
Fay.Liang 2015-01-14 16:05:15 -05:00
commit f7e38eaf36
10 changed files with 491 additions and 375 deletions

View file

@ -1,4 +1,4 @@
# Version 2014.12.12-0
# Version 2014.12.17-0
import GenericHazards
import JsonSupport
@ -6,6 +6,7 @@ import LocalizationSupport
import string, time, os, errno, re, types, copy, collections
import LogStream, ModuleAccessor, SampleAnalysis, EditAreaUtils
import math
import pprint
from AbsTime import *
from StartupDialog import IFPDialog as Dialog
@ -17,6 +18,8 @@ class TextProduct(GenericHazards.TextProduct):
def __init__(self):
GenericHazards.TextProduct.__init__(self)
self._pp = pprint.PrettyPrinter()
###############################################################
### Hazards and Additional Hazards
@ -242,7 +245,8 @@ class TextProduct(GenericHazards.TextProduct):
removedParts.append(part)
for part in removedParts:
self.debug_print("SARAH: Removing part = %s" % (part), 1)
self.debug_print("in _processProductParts - " +
"Removing product part = %s" % (part), 1)
partsList.remove(part)
################# Product Parts Helper Methods
@ -502,15 +506,16 @@ class TextProduct(GenericHazards.TextProduct):
for area in hazard['id']:
hazDict.setdefault((hdln, phen, sig), []).append(area)
#self.debug_print("hazDict", hazDict
self.debug_print("hazDict = %s" % (self._pp.pformat(hazDict)), 1)
hazardHdlns=[]
huAreas = []
# self.debug_print("\nAdditional Hazard Headlines"
self.debug_print("Additional Hazard Headlines", 1)
for key in hazDict.keys():
hdln, phen, sig = key
huAreas = huAreas + hazDict[key]
hazardHdln = ((hdln, "NEW", phen,sig), hazDict[key], [],[],[])
#self.debug_print(" ", hazardHdln, hazDict[key]
self.debug_print(" %s" % (self._pp.pformat(hazardHdln)), 1)
self.debug_print(" %s" % (self._pp.pformat(hazDict[key])), 1)
hazardHdlns.append(hazardHdln)
return hazardHdlns, huAreas
@ -533,14 +538,12 @@ class TextProduct(GenericHazards.TextProduct):
# Otherwise, they are ignored.
#
# E.g. hdlnList = self._checkHazard(hazardHdlns, [("FA","W")], returnList=True)
self.debug_print("_checkHazard hazardHdlns is %s" % (hazardHdlns), 1)
self.debug_print("_checkHazard phenSigList is %s" % (phenSigList), 1)
self.debug_print("_checkHazard hazardHdlns is %s" % (self._pp.pformat(hazardHdlns)), 1)
self.debug_print("_checkHazard phenSigList is %s" % (self._pp.pformat(phenSigList)), 1)
chosen = []
for key, landList, marineList, coastalList, inlandList in hazardHdlns:
# self.debug_print("what is mode? %s" % mode, 1)
# SARAH - we do not want to consider marine hazards in this product
# hazAreas = landList+marineList
# We do not want to consider marine hazards in this product
hazAreas = landList
hazValue = (key, hazAreas)
self.debug_print("hazValue is %s" % (repr(hazValue)), 1)
@ -555,10 +558,9 @@ class TextProduct(GenericHazards.TextProduct):
# Check for land, marine, etc.
for checkAreaType in checkAreaTypes:
exec "testList = " + checkAreaType + "List"
# self.debug_print("testList is %s" % testList, 1)
self.debug_print("testList is %s" % (testList), 1)
if testList != []:
chosen.append(hazValue)
# self.debug_print("chosen is %s" % chosen, 1)
elif checkAreas is not None:
acceptedAreas=[]
for hazArea in hazAreas:
@ -570,7 +572,8 @@ class TextProduct(GenericHazards.TextProduct):
chosen.append(hazValue)
if not returnList and chosen!=[]: break
self.debug_print("MATT _checkHazard chosen = %s" % (repr(chosen)), 1)
self.debug_print("In _checkHazard chosen = %s" %
(self._pp.pformat(chosen)), 1)
if not returnList:
return chosen!=[]
return chosen
@ -609,7 +612,8 @@ class TextProduct(GenericHazards.TextProduct):
trList = []
self._periodList = []
for index, tr in enumerate(subRanges):
# self.debug_print(tr)
self.debug_print("In _determineTimeRanges -> tr = %s" %
(self._pp.pformat(tr)), 1)
trList.append((tr, "Label"))
if index == 0:
@ -633,10 +637,13 @@ class TextProduct(GenericHazards.TextProduct):
period = self.makeTimeRange(startTime, startTime+periodLength*3600)
self._periodList.append(period)
for i in range(1,10):
startTime = period.endTime() # Start where the last period leaves off
period = self.makeTimeRange(startTime, startTime+12*3600)
self._periodList.append(period)
self.debug_print("final periodList =\n\n%s\n" %
(self._pp.pformat(self._periodList)), 1)
self._timeRangeList = trList
def _calculateStartTime(self, localCreationTime):
@ -645,21 +652,21 @@ class TextProduct(GenericHazards.TextProduct):
day = localCreationTime[2]
hour = localCreationTime[3]
# If we are more than halfway though a 3 hr period
if hour % 3 > 1:
adjust = 3 # move on to the next 3 hr block
# Define a variable to control which resolution we want
resolution = self._resolution() # 6 is also a valid option
# If we are more than halfway though a block we would want
if hour % resolution > resolution / 2:
adjust = resolution # move on to the next block
else:
adjust = 0
# if hour % 6 > 3:
# adjust = 6 # move on to the next 6 hr block
# else:
# adjust = 0
# self.debug_print("MATT: _calculateStartTime %d adjust = %d" % (hour % 6, adjust)
self.debug_print("In _calculateStartTime %d adjust = %d" %
(hour % resolution, adjust), 1)
# Now "truncate" to a 3-hourly boundary and compute startTime in local Time.
# hour = int( (hour/6) * 6) + adjust
hour = int( (hour/3) * 3) + adjust
# Now "truncate" to a block boundary and compute startTime in local time.
# hour = int( (hour/3) * 3) + adjust
hour = int( (hour/resolution) * resolution) + adjust
if hour > 23:
hour -= 24
elif hour < 0:
@ -678,7 +685,7 @@ class TextProduct(GenericHazards.TextProduct):
# DAY + MORNING / AFTERNOON / EVENING / OVERNIGHT.
# If wholePeriod, format FROM ... TO...
self.debug_print("MATT Format period wholePeriod = %s, period = %s, useEndTime =%s" %
self.debug_print("Format period wholePeriod = %s, period = %s, useEndTime =%s" %
(str(wholePeriod), str(period), str(useEndTime)), 1)
if period is None:
return ""
@ -687,10 +694,10 @@ class TextProduct(GenericHazards.TextProduct):
else:
startTime = period.startTime()
result = self._getTimeDesc(startTime, resolution, shiftToLocal)
self.debug_print("MATT result = '%s'" % (result), 1)
self.debug_print("_getTimeDesc result = '%s'" % (result), 1)
if wholePeriod:
endResult = self._getTimeDesc(period.endTime(), resolution, shiftToLocal)
self.debug_print("MATT endResult = '%s'" % (endResult), 1)
self.debug_print("_getTimeDesc endResult = '%s'" % (endResult), 1)
if result != endResult:
result=result + " TO "+ endResult
return result
@ -1020,8 +1027,9 @@ FORECASTER STEWART"""
self._loadLastTwoAdvisories()
def _synchronizeAdvisories(self):
# Retrieving a directory causes synching to occur
file = LocalizationSupport.getLocalizationFile(LocalizationSupport.CAVE_STATIC,
file = LocalizationSupport.getLocalizationFile(LocalizationSupport.CAVE_STATIC,
LocalizationSupport.SITE, self._site,
self._getAdvisoryPath()).getFile()
@ -1044,12 +1052,12 @@ FORECASTER STEWART"""
filenames = os.listdir(advisoryDirectoryPath)
allAdvisories = filter(lambda filename: filename[-5:] == ".json", filenames)
self.debug_print("allAdvisories = %s" % (repr(allAdvisories)))
self.debug_print("allAdvisories = %s" % (self._pp.pformat(allAdvisories)))
stormAdvisories = filter(lambda filename: self._getStormNameFromTCP() in filename,
allAdvisories)
stormAdvisories = map(lambda filename: filename[:-5], stormAdvisories)
self.debug_print("stormAdvisories = %s" % (repr(stormAdvisories)))
self.debug_print("stormAdvisories = %s" % (self._pp.pformat(stormAdvisories)))
return stormAdvisories
@ -1074,8 +1082,8 @@ FORECASTER STEWART"""
else: # Must be the HLS
lastTwoAdvisories = stormAdvisories[:2]
self.debug_print("MATT DEBUG: last two advisories = %s" %
(repr(lastTwoAdvisories)), 1)
self.debug_print("DEBUG: last two advisories = %s" %
(self._pp.pformat(lastTwoAdvisories)), 1)
self._previousAdvisory = None
if len(lastTwoAdvisories) >= 1:
self._previousAdvisory = self._loadAdvisory(lastTwoAdvisories[0])
@ -1093,8 +1101,8 @@ FORECASTER STEWART"""
self._site,
fileName)
self.debug_print("SARAH: File contents for %s:" % (fileName), 1)
self.debug_print(repr(pythonDict), 1)
self.debug_print("File contents for %s:" % (fileName), 1)
self.debug_print(self._pp.pformat(pythonDict), 1)
# Only use transmitted advisories
if pythonDict["Transmitted"] == False and advisoryName != "pending":
@ -1102,8 +1110,7 @@ FORECASTER STEWART"""
else:
return pythonDict
except Exception, e:
self.debug_print("SARAH Load Exception for %s : %s" %
(fileName, e), 1)
self.debug_print("Load Exception for %s : %s" % (fileName, e), 1)
return None
def _getAdvisoryPath(self):
@ -1170,6 +1177,7 @@ class Common_Dialog(Dialog):
self._varDict = {} # all end results must be saved here
self._infoDict = infoDict
self._parent = parent
self._pp = pprint.PrettyPrinter()
Dialog.__init__(self, parent=None, title=title)
def getVarDict(self):

View file

@ -630,7 +630,7 @@ PotentialImpactStatements = {
},
}
EvacuationStatements = ["For those under evacuation orders, leave as soon as practical with a destination in mind. Gas up your vehicle well ahead of time. Be sure that you take essential materiasl from your Emergency Supplies Kit. Let others know where you are going and when you intend to arrive.",
EvacuationStatements = ["For those under evacuation orders, leave as soon as practical with a destination in mind. Gas up your vehicle well ahead of time. Be sure that you take essential materials from your Emergency Supplies Kit. Let others know where you are going and when you intend to arrive.",
"If evacuating the area, stick to prescribed evacuation routes. Look for additional traffic information on roadway smart signs and listen to select radio channels for further travel instructions. Do not use your cell phone while driving."
"For those not under evacuation orders, understand that there are inherent risks to evacuation (such as traffic congestion, accidents, and driving in bad weather), so evacuate only if necessary. Help keep roadways open for those that are under evacuation orders."]
@ -678,7 +678,6 @@ OtherPreparednessActions = {
"Problems with sewer backups can contaminate standing flood waters. Keep children away. Also, listen for boil water alerts relative to communities whose tap water may have become temporarily non-potable."],
}
AdditionalSources = ["- For information on appropriate preparations see ready.gov/louisiana",
"- For information on local evacuation shelters see www.emergency.louisana.gov/disaster_evaluation_guide.html",
AdditionalSources = ["- For information on appropriate preparations see ready.gov",
"- For information on creating an emergency plan see getagameplan.org",
"- For additional disaster preparedness information see redcross.org"]

View file

@ -192,48 +192,47 @@ public final class TPCWatchSrv extends AbstractWatchNotifierSrv {
// if it's a TCV
if ("TCV".equals(pil)) {
super.handleWatch(warningRecs);
}
// if we are not in practice mode
if (!practiceMode) {
// if we are not in practice mode
if (!practiceMode) {
// if xxxId ends with a digit (i.e. its a national TCV)
String xxxId = record.getXxxid();
if (Character.isDigit(xxxId.charAt(xxxId.length() - 1))) {
// if xxxId ends with a digit (i.e. its a national TCV)
String xxxId = record.getXxxid();
if (Character.isDigit(xxxId.charAt(xxxId.length() - 1))) {
// build the full 9-letter PIL
String fullPil = SiteMap.getInstance().mapICAOToCCC(
issuingOffice)
+ pil + xxxId;
// build the full 9-letter PIL
String fullPil = SiteMap.getInstance().mapICAOToCCC(
issuingOffice)
+ pil + xxxId;
// build the command line for the NWRWAVES script
final String command = NWRWAVES_SCRIPT + fullPil;
// build the command line for the NWRWAVES script
final String command = NWRWAVES_SCRIPT + fullPil;
// Create a separate thread to run the script
Thread thread = new Thread(new Runnable() {
// Create a separate thread to run the script
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
RunProcess proc;
try {
proc = RunProcess.getRunProcess().exec(command);
} catch (IOException e) {
statusHandler.error("Error executing "
+ command, e);
return;
}
int exitCode = proc.waitFor();
if (exitCode != 0) {
statusHandler
.error(command
+ " terminated abnormally with exit code: "
+ exitCode);
}
@Override
public void run() {
RunProcess proc;
try {
proc = RunProcess.getRunProcess().exec(command);
} catch (IOException e) {
statusHandler
.error("Error executing " + command, e);
return;
}
});
thread.start();
}
int exitCode = proc.waitFor();
if (exitCode != 0) {
statusHandler.error(command
+ " terminated abnormally with exit code: "
+ exitCode);
}
}
});
thread.start();
}
}
@ -296,7 +295,11 @@ public final class TPCWatchSrv extends AbstractWatchNotifierSrv {
statusHandler.error("Unable to delete " + pendingFile, e);
}
sendTCVFiles(siteId);
// if not practice mode
if (!practiceMode) {
// send TCV files to VTEC partner sites
sendTCVFiles(siteId);
}
}
}

View file

@ -516,24 +516,39 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
nwsIntroUsed = 1
if phraseCount == 0:
phraseCount = 1
hazardBodyPhrase = hazardBodyPhrase + " HAS ISSUED " + \
hazNameA + forPhrase + \
"...WHICH IS IN EFFECT" + endTimePhrase + ". "
if eachHazard['phen'] in ['HU', 'TR', 'TY']:
hazardBodyPhrase = hazardBodyPhrase + " HAS ISSUED " + \
hazNameA + ". "
else:
hazardBodyPhrase = hazardBodyPhrase + " HAS ISSUED " + \
hazNameA + forPhrase + \
"...WHICH IS IN EFFECT" + endTimePhrase + ". "
elif phraseCount == 1:
phraseCount = 2
if hdln != lastHdln:
hazardBodyPhrase = hazardBodyPhrase + hazNameA + \
" HAS ALSO BEEN ISSUED. THIS " + hazName + forPhrase + \
" IS IN EFFECT" + endTimePhrase + ". "
if eachHazard['phen'] in ['HU', 'TR', 'TY']:
hazardBodyPhrase = hazardBodyPhrase + hazNameA + \
" HAS ALSO BEEN ISSUED."
else:
hazardBodyPhrase = hazardBodyPhrase + hazNameA + \
" HAS ALSO BEEN ISSUED. THIS " + hazName + forPhrase + \
" IS IN EFFECT" + endTimePhrase + ". "
else:
hazardBodyPhrase = hazardBodyPhrase + hazNameA + \
" HAS ALSO BEEN ISSUED" + endTimePhrase + ". "
if eachHazard['phen'] in ['HU', 'TR', 'TY']:
hazardBodyPhrase = hazardBodyPhrase + hazNameA + \
" HAS ALSO BEEN ISSUED."
else:
hazardBodyPhrase = hazardBodyPhrase + hazNameA + forPhrase + \
" HAS ALSO BEEN ISSUED" + endTimePhrase + ". "
else:
hazardBodyPhrase = hazardBodyPhrase + "IN ADDITION..." + \
hazNameA + forPhrase + " HAS BEEN ISSUED. THIS " + hazName + \
" IS IN EFFECT" + endTimePhrase + ". "
lastHdln = hdln
if eachHazard['phen'] in ['HU', 'TR', 'TY']:
hazardBodyPhrase = hazardBodyPhrase + "IN ADDITION..." + \
hazNameA + " HAS BEEN ISSUED."
else:
hazardBodyPhrase = hazardBodyPhrase + "IN ADDITION..." + \
hazNameA + forPhrase + " HAS BEEN ISSUED. THIS " + hazName + \
" IS IN EFFECT" + endTimePhrase + ". "
lastHdln = hdln
#
# This is for the can hazards
#

View file

@ -1,4 +1,4 @@
# Version 2014.12.12-0
# Version 2015.1.6-0
import GenericHazards
import string, time, os, re, types, copy, LogStream, collections
@ -358,7 +358,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
if self._ImpactsAnticipated:
includedImpacts = sorted(self._IncludedImpacts, key=self._impactsKeyFunction)
for ((_, sectionName), _) in includedImpacts:
self.debug_print("SARAH: adding section = '%s'" % (sectionName), 1)
self.debug_print("adding section = '%s'" % (sectionName), 1)
partsList.append(sectionName)
partsList.append('preparednessSection')
@ -371,7 +371,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
partsList.append('nextUpdate')
partsList.append('endProduct')
self.debug_print("Product Parts partsList = %s" % partsList, 1)
self.debug_print("Product Parts partsList =\n\n%s\n" % (self._pp.pformat(partsList)), 1)
return {
'partsList': partsList
@ -466,7 +466,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
self._initializeHeadlines()
self._ugcs = self._allAreas()
self._ugcs = sorted(self._allAreas())
return None
@ -660,15 +660,17 @@ class TextProduct(HLSTCV_Common.TextProduct):
elif len(impactParts) == 1:
impactRangeRest = impactParts[0]
self.debug_print("MATT DEBUG: impactRange = '%s' impactMax = '%s' impactMin = '%s'" % (impactRange, impactMax, impactMin), 1)
self.debug_print("DEBUG: impactRange = '%s' impactMax = '%s' impactMin = '%s'" %
(impactRange, impactMax, impactMin), 1)
# If there are additional life-threatening surge areas
if impactRange != impactMax and impactRange != impactMin:
curPhrase = "Brace for %s%s damage across %s." % \
(lifeThreatening, impactRange, self._frame("ENTER AREA DESCRIPTION"))
self.debug_print("MATT DEBUG: curPhrase = '%s'" % (curPhrase), 1)
self.debug_print("MATT DEBUG: sectionDict['additionalImpactRange'] = '%s'" % (repr(sectionDict['additionalImpactRange'])), 1)
self.debug_print("DEBUG: curPhrase = '%s'" % (curPhrase), 1)
self.debug_print("DEBUG: sectionDict['additionalImpactRange'] = \n'%s'" %
(sectionDict['additionalImpactRange']), 1)
# If this phrase is not already part of the additional impacts
if curPhrase not in sectionDict['additionalImpactRange']:
@ -699,7 +701,8 @@ class TextProduct(HLSTCV_Common.TextProduct):
# Add it now
sectionDict['additionalImpactRange'].append(curPhrase)
self.debug_print("Final Surge sectionDict['additionalImpactRange'] = '%s'" % (sectionDict['additionalImpactRange']), 1)
self.debug_print("Final Surge sectionDict['additionalImpactRange'] = '%s'" %
(sectionDict['additionalImpactRange']), 1)
productDict['surgeSection'] = sectionDict
def _floodingRainSection(self, productDict, productSegmentGroup, productSegment):
@ -716,7 +719,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
inputThreatDominant = self._samplingDict['FloodingRainThreat']['inputThreatDominant']
self.debug_print("In _floodingRainSection", 1)
self.debug_print("_samplingDict = %s" % (repr(self._samplingDict['FloodingRainThreat'])), 1)
self.debug_print("_samplingDict = \n\n%s\n" % (self._pp.pformat(self._samplingDict['FloodingRainThreat'])), 1)
# Test the simplest case first
if impactMin == "none" and impactMax == "none":
@ -935,10 +938,10 @@ class TextProduct(HLSTCV_Common.TextProduct):
for key in keys:
self.debug_print("%s : %s" % (key, self._previousAdvisory[key]), 1)
for hazard in self._previousAdvisory["HazardsForHLS"]:
self.debug_print("SARAH DEBUG Hazard: %s" % (repr(hazard)), 1)
self.debug_print("DEBUG Hazard: %s" % (self._pp.pformat(hazard)), 1)
if hazard['act'] != 'CON':
self._changesHazardsList.append(hazard)
if hazard['act'] != 'CAN':
if hazard['act'] not in ['CAN', "UPG"]:
self._currentHazardsList.append(hazard)
self.debug_print("-"*80, 1)
@ -963,7 +966,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
self.debug_print("=" * 100, 1)
self.debug_print("In _sampleHLSData for period %s (%s)" % \
(period, repr(self._timeRangeList[period][0])), 1)
(period, self._timeRangeList[period][0]), 1)
statDict = statList[period]
for threatName in ['WindThreat', 'FloodingRainThreat', 'TornadoThreat']:
@ -975,9 +978,9 @@ class TextProduct(HLSTCV_Common.TextProduct):
if decidingField is None or qpfToFfgRatio > decidingField:
self._samplingDict['FloodingRainThreat']['decidingField'] = qpfToFfgRatio
self.debug_print("SARAH: WindThreat = %s" % (self._samplingDict['WindThreat']['inputThreatDominant']), 1)
self.debug_print("SARAH: FloodingRainThreat = %s" % (self._samplingDict['FloodingRainThreat']['inputThreatDominant']), 1)
self.debug_print("SARAH: TornadoThreat = %s" % (self._samplingDict['TornadoThreat']['inputThreatDominant']), 1)
self.debug_print("WindThreat = %s" % (self._samplingDict['WindThreat']['inputThreatDominant']), 1)
self.debug_print("FloodingRainThreat = %s" % (self._samplingDict['FloodingRainThreat']['inputThreatDominant']), 1)
self.debug_print("TornadoThreat = %s" % (self._samplingDict['TornadoThreat']['inputThreatDominant']), 1)
@ -1020,10 +1023,10 @@ class TextProduct(HLSTCV_Common.TextProduct):
if decidingField is None or inundationMax > decidingField:
self._samplingDict['StormSurgeThreat']['decidingField'] = inundationMax
self.debug_print("SARAH: StormSurgeThreat = %s" % (self._samplingDict['StormSurgeThreat']['inputThreatDominant']), 1)
self.debug_print("StormSurgeThreat = %s" % (self._samplingDict['StormSurgeThreat']['inputThreatDominant']), 1)
def _sampleTCVAdvisory(self, advisory):
self.debug_print("SARAH: sampling TCV advisory!", 1)
self.debug_print("sampling TCV advisory!", 1)
for zone in advisory["ZoneData"]:
self.debug_print("-" * 60, 1)
self.debug_print("Looking at zone %s" % (zone), 1)
@ -1055,46 +1058,46 @@ class TextProduct(HLSTCV_Common.TextProduct):
self._samplingDict[key]['inputThreatLow'] = lowThreat
self._samplingDict[key]['inputThreatHigh'] = highThreat
self.debug_print("Sampling dict = %s" % (repr(self._samplingDict)), 1)
self.debug_print("Sampling dict =\n\n%s\n" % (self._pp.pformat(self._samplingDict)), 1)
def _sampleRankedDiscreteValue(self, threatName, statDict):
self.debug_print("-" * 60, 1)
self.debug_print("_sampleRankedDiscreteValue statDict = %s" % (repr(statDict)), 1)
self.debug_print("_sampleRankedDiscreteValue statDict =\n\n%s\n" % (self._pp.pformat(statDict)), 1)
rankedThreatLevels = self.getStats(statDict, threatName + "__rankedDiscreteValue")
self.debug_print("SARAH: sampling %s" % (threatName), 1)
self.debug_print("SARAH: sampleData: rankedThreatLevels = %s" % (repr(rankedThreatLevels)), 1)
self.debug_print("sampling %s" % (threatName), 1)
self.debug_print("sampleData: rankedThreatLevels =\n\n%s\n" % (self._pp.pformat(rankedThreatLevels)), 1)
if rankedThreatLevels is not None:
dominantThreatLevel = self._getDominantThreatLevel(threatName, rankedThreatLevels)
self.debug_print("SARAH: dominantThreatLevel = %s" % (dominantThreatLevel), 1)
self.debug_print("dominantThreatLevel = %s" % (dominantThreatLevel), 1)
currentDominantThreatLevel = self._samplingDict[threatName]['inputThreatDominant']
self.debug_print("SARAH: currentDominantThreatLevel = %s" % (currentDominantThreatLevel), 1)
self.debug_print("currentDominantThreatLevel = %s" % (currentDominantThreatLevel), 1)
self._samplingDict[threatName]['inputThreatDominant'] = self._getHighestThreat(threatName,
dominantThreatLevel,
currentDominantThreatLevel)
self.debug_print("SARAH: new dominant = %s" % (self._samplingDict[threatName]['inputThreatDominant']), 1)
self.debug_print("new dominant = %s" % (self._samplingDict[threatName]['inputThreatDominant']), 1)
def _sampleMostSignificantDiscreteValue(self, threatName, statDict):
self.debug_print("SARAH: _sampleMostSignificantDiscreteValue for %s" % (threatName), 1)
self.debug_print("_sampleMostSignificantDiscreteValue for %s" % (threatName), 1)
threatLevel = self.getStats(statDict, threatName + "__mostSignificantDiscreteValue")
self.debug_print("SARAH: threatLevel = %s" % (threatLevel), 1)
self.debug_print("threatLevel = %s" % (threatLevel), 1)
if threatLevel is not None:
inputThreatLow = self._samplingDict[threatName]['inputThreatLow']
self.debug_print("SARAH: current inputThreatLow = %s" % (inputThreatLow), 1)
self.debug_print("current inputThreatLow = %s" % (inputThreatLow), 1)
if inputThreatLow is None:
self._samplingDict[threatName]['inputThreatLow'] = threatLevel
else:
self._samplingDict[threatName]['inputThreatLow'] = self._getLowestThreat(threatName,
threatLevel,
inputThreatLow)
self.debug_print("SARAH: new inputThreatLow = %s" % (self._samplingDict[threatName]['inputThreatLow']), 1)
self.debug_print("new inputThreatLow = %s" % (self._samplingDict[threatName]['inputThreatLow']), 1)
inputThreatHigh = self._samplingDict[threatName]['inputThreatHigh']
self.debug_print("SARAH: current inputThreatHigh = %s" % (inputThreatHigh), 1)
self.debug_print("current inputThreatHigh = %s" % (inputThreatHigh), 1)
self._samplingDict[threatName]['inputThreatHigh'] = self._getHighestThreat(threatName,
threatLevel,
inputThreatHigh)
self.debug_print("SARAH: new inputThreatHigh = %s" % (self._samplingDict[threatName]['inputThreatHigh']), 1)
self.debug_print("new inputThreatHigh = %s" % (self._samplingDict[threatName]['inputThreatHigh']), 1)
def _getDominantThreatLevel(self, threatName, rankedThreatLevels):
dominantLevelWithHighestRank = None
@ -1147,7 +1150,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
catastrophicThreshold = self._samplingDict[threatName]['catastrophicThreshold']
self.debug_print("-" * 60, 1)
self.debug_print("MATT DEBUG: _setHazardImpactCategories for %s" % (threatName), 1)
self.debug_print("DEBUG: _setHazardImpactCategories for %s" % (threatName), 1)
impactMin = None
impactMax = None
@ -1191,7 +1194,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
impactRangeMax = "none"
self.debug_print(
"MATT DEBUG: impactMin = '%s' impactMax = '%s' impactRangeMax = '%s'" % \
"DEBUG: impactMin = '%s' impactMax = '%s' impactRangeMax = '%s'" % \
(impactMin, impactMax, impactRangeMax), 1)
# Determine dominant impact category for rest of CWA - No impact
@ -1240,7 +1243,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
segment_vtecRecords_tuples = []
for segment in segments:
vtecRecords = self._getVtecRecords(segment)
self.debug_print("SARAH: vtecRecords = %s" % (repr(vtecRecords)))
self.debug_print("vtecRecords =\n\n%s\n" % (self._pp.pformat(vtecRecords)))
segment_vtecRecords_tuples.append((segment, vtecRecords))
productSegmentGroup = {
@ -1281,7 +1284,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
else:
hazardDict[key] = hazardDict[key]+segment
#self.debug_print("hazardList = %s" % (repr(hazardList)), 1)
self.debug_print("hazardList =\n\n%s\n" % (self._pp.pformat(hazardList)), 1)
return hazardList
@ -1417,7 +1420,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
# Storm intensity in mph and the stated intensity trend.
self._stormIntensityTrend = "Storm Intensity " + stormDict.get("StormIntensity","")
self.debug_print("SARAH: BEGIN STORM INFORMATION", 1)
self.debug_print("BEGIN STORM INFORMATION", 1)
self.debug_print("storm dict = %s" % (stormDict), 1)
self.debug_print("storm name = %s" % (self._stormName), 1)
self.debug_print("type = %s" % (self._stormType), 1)
@ -1430,7 +1433,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
self.debug_print("references = %s" % (self._stormLocalReferences), 1)
self.debug_print("movement trend = %s" % (self._stormMovementTrend), 1)
self.debug_print("intensity trend = %s" % (self._stormIntensityTrend), 1)
self.debug_print("SARAH: END STORM INFORMATION", 1)
self.debug_print("END STORM INFORMATION", 1)
def _grabStormInfo(self, tcp):
# Get the storm information from the selected TCP
@ -1555,7 +1558,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
# Assume we only have one NHC reference point by default
nhcReference = dict["StormReference"]
## self.debug_print("referenceIndex = %s" % (referenceIndex), 1)
self.debug_print("referenceIndex = %s" % (referenceIndex), 1)
# If we have more than one NHC reference point
if referenceIndex != -1:
@ -1603,13 +1606,15 @@ class TextProduct(HLSTCV_Common.TextProduct):
# Display some debug info - if flag is set
self.debug_print("storminfoSearch = '%s'" % (stormInfoSearch))
## self.debug_print(repr(stormInfoSearch.groups()), 1)
if stormInfoSearch is not None:
self.debug_print("\n\n%s\n" %
(self._pp.pformat(stormInfoSearch.groups())), 1)
# If we found the storm info section of the product
if stormInfoSearch is not None:
# for group in stormInfoSearch.groups():
# self.debug_print('-'*50, 1)
# self.debug_print("%s\n" % (group), 1)
for group in stormInfoSearch.groups():
self.debug_print('-'*50, 1)
self.debug_print("%s\n" % (group), 1)
# Clean this section up a bit. Keep each paragraph separate
# by a single <CR>, but remove all others as well as extra
@ -1641,7 +1646,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
# If we cannot find the summary, try to find a "repeating" section
if repeatInfo is None:
repeatInfo = re.search("(?is)(REPEATING.+?\.)\n *\n", tcp)
## self.debug_print(repr(repeatInfo), 1)
self.debug_print(self._pp.pformat(repeatInfo), 1)
# If we found the repeated storm information summary
if repeatInfo is not None:
@ -1661,7 +1666,8 @@ class TextProduct(HLSTCV_Common.TextProduct):
# Display some debug info - if flag is set
self.debug_print("locationSearch = '%s'" % (locationSearch), 1)
## self.debug_print(repr(locationSearch.groups()), 1)
if locationSearch is not None:
self.debug_print("\n\n%s\n" % (self._pp.pformat(locationSearch.groups())), 1)
# If we found the storm location section of the product
if locationSearch is not None:
@ -1720,18 +1726,18 @@ class TextProduct(HLSTCV_Common.TextProduct):
#========================================================================
# Display final decoded information from TCP
## self.debug_print("*" *80, 1)
## self.debug_print("Final TCP Info...\n", 1)
## self.debug_print('dict["StormType"] = %s' % (dict["StormType"]), 1)
## self.debug_print('dict["StormName"] = %s' % (dict["StormName"]), 1)
## self.debug_print('dict["StormTime"] = %s' % (dict["StormTime"]), 1)
## self.debug_print('dict["StormLat"] = %s' % (dict["StormLat"]), 1)
## self.debug_print('dict["StormLon"] = %s' % (dict["StormLon"]), 1)
## self.debug_print('dict["StormReference"] = %s' % (dict["StormReference"]), 1)
## self.debug_print('dict["StormIntensity"] = %s' % (dict["StormIntensity"]), 1)
## self.debug_print('dict["StormMotion"] = %s' % (dict["StormMotion"]), 1)
## self.debug_print('dict["StormInfo"] = %s' % (dict["StormInfo"]), 1)
## self.debug_print('dict["StormCenter"] = %s' % (dict["StormCenter"]), 1)
self.debug_print("*" *80, 1)
self.debug_print("Final TCP Info...\n", 1)
self.debug_print('dict["StormType"] = %s' % (dict["StormType"]), 1)
self.debug_print('dict["StormName"] = %s' % (dict["StormName"]), 1)
self.debug_print('dict["StormTime"] = %s' % (dict["StormTime"]), 1)
self.debug_print('dict["StormLat"] = %s' % (dict["StormLat"]), 1)
self.debug_print('dict["StormLon"] = %s' % (dict["StormLon"]), 1)
self.debug_print('dict["StormReference"] = %s' % (dict["StormReference"]), 1)
self.debug_print('dict["StormIntensity"] = %s' % (dict["StormIntensity"]), 1)
self.debug_print('dict["StormMotion"] = %s' % (dict["StormMotion"]), 1)
self.debug_print('dict["StormInfo"] = %s' % (dict["StormInfo"]), 1)
self.debug_print('dict["StormCenter"] = %s' % (dict["StormCenter"]), 1)
# Return the dictionary will all the information we found in the TCP
return dict
@ -1744,7 +1750,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
self._stormReference = ""
self._stormLocalReferences = ""
para = stormDict.get("StormCenter", "")
# self.debug_print("para %d %s" % (len(para), para), 1)
self.debug_print("para %d %s" % (len(para), para), 1)
if len(para)<= 0:
return
@ -1768,13 +1774,15 @@ class TextProduct(HLSTCV_Common.TextProduct):
# Try to find these patterns in the text
coordPtnMatch = coordPtn.search(para)
## self.debug_print("+" * 90, 1)
## self.debug_print("coordinate search...", 1)
## self.debug_print(coordPtnMatch.groups(), 1)
self.debug_print("+" * 90, 1)
self.debug_print("coordinate search...", 1)
if coordPtnMatch is not None:
self.debug_print("\n\n%s|n" % (self._pp.pformat(coordPtnMatch.groups())), 1)
refPtnMatch = refPtn.search(para)
## self.debug_print("reference search...", 1)
## self.debug_print(refPtnMatch.groups(), 1)
self.debug_print("reference search...", 1)
if refPtnMatch is not None:
self.debug_print("\n\n%s|n" % (self._pp.pformat(refPtnMatch.groups())), 1)
# If we found the coordinates we were after
if coordPtnMatch is not None:
@ -1818,12 +1826,12 @@ class TextProduct(HLSTCV_Common.TextProduct):
self._stormLocalReferences = self._calcLocalReferences(
self._stormLat, self._stormLon)
## self.debug_print("stormLocalRefs = %s" % (self._stormLocalReferences), 1)
self.debug_print("stormLocalRefs = %s" % (self._stormLocalReferences), 1)
# Compare the NHC reference to the local references
for localRef in self._stormLocalReferences:
## self.debug_print("self._stormReference = '%s', localRef = '%s'" % (self._stormReference, localRef), 1)
self.debug_print("self._stormReference = '%s', localRef = '%s'" % (self._stormReference, localRef), 1)
# Get the locations from these statements
nhcRef = re.search('(?i)(north|south|east|west) of (.+)',
@ -1831,7 +1839,11 @@ class TextProduct(HLSTCV_Common.TextProduct):
testRef = re.search('(?i)(north|south|east|west) of (.+)',
localRef)
## self.debug_print("nhcRef = '%s'\ttestRef = '%s'" % (nhcRef.group(2), testRef.group(2)), 1)
if nhcRef is not None:
self.debug_print("nhcRef = '%s'" % (nhcRef.group(2)), 1)
if testRef is not None:
self.debug_print("testRef = '%s'" % (testRef.group(2)), 1)
# If we have a local reference that matches the national
# center reference
@ -1870,7 +1882,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
# Remove references to KM e.g.
# 420 KM... 100 KM/HR...
# self.debug_print("words = '%s'" % (words), 1)
self.debug_print("words = '%s'" % (words), 1)
kmSearch = re.compile("\.\.\. *[0-9]+ +(KM|KM/HR?) *\.?\.?\.?")
@ -1883,7 +1895,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
for doubleSpace in doubleSpaces:
words = re.sub(doubleSpace, ' ', words)
# self.debug_print("\tfinal words = '%s'" % (words), 1)
self.debug_print("\tfinal words = '%s'" % (words), 1)
return words
def _cleanText(self, text=''):
@ -1934,7 +1946,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
direction = self._bearing(lat1, lon1, lat0, lon0)
direction = self._dirInEnglish(direction)
localRef ="ABOUT "+distMph_str+" MILES "+direction
# self.debug_print("localRef = %s" % (localRef), 1)
self.debug_print("localRef = %s" % (localRef), 1)
return localRef
# Returns the distance from lat0, lon0 to lat1, lon1 in kilometers
@ -2199,7 +2211,7 @@ class Overview_Dialog(HLSTCV_Common.Common_Dialog):
# pull the data from the tkObject_dict before they get toasted
tkObject_dict = self._tkObject_dict
overviewList = self._parent._overview_list()
print("SARAH: in okCB!")
print("in okCB!")
for infoDict in overviewList:
name = infoDict["name"]
label = infoDict["label"]
@ -2218,7 +2230,7 @@ class Overview_Dialog(HLSTCV_Common.Common_Dialog):
checkList.append((options[i], svar.get()))
else:
if ivarList[i].get():
print("SARAH: adding option = %s" % (repr(options[i])))
print("adding option = %s" % (self._pp.pformat(options[i])))
checkList.append(options[i])
value = checkList
self._setVarDict(name, value)
@ -2255,8 +2267,8 @@ class LegacyFormatter():
@param productParts -- list of instances of the ProductPart class with information about how to format each product part
@return text -- product string
'''
text = ''
print("SARAH: productParts = %s" % (productParts))
text = ""
self._textProduct.debug_print("productParts = %s" % (productParts))
for part in productParts:
valtype = type(part)
if valtype is str:
@ -2264,15 +2276,15 @@ class LegacyFormatter():
elif valtype is tuple:
name = part[0]
infoDicts = part[1]
self.debug_print("SARAH: name = %s" % (str(name)), 1)
self.debug_print("SARAH: infoDicts = %s" % (repr(infoDicts)), 1)
self._textProduct.debug_print("name = %s" % (name), 1)
self._textProduct.debug_print("infoDicts =\n\n%s\n" % (self._pp.pformat(infoDicts)), 1)
newtext = self.processSubParts(productDict.get(name), infoDicts)
self.debug_print("SARAH: newtext type = %s" % (type(newtext)), 1)
self.debug_print("SARAH: newtext = %s" % (repr(newtext)), 1)
self._textProduct.debug_print("newtext type = %s" % (type(newtext)), 1)
self._textProduct.debug_print("newtext =\n\n%s\b" % (self._pp.pformat(newtext)), 1)
text += newtext
continue
elif valtype is list:
self.debug_print('GOT HERE -- found list', 1)
self._textProduct.debug_print('GOT HERE -- found list', 1)
self._tpc.flush()
# TODO THIS SHOULD BE REMOVED AFTER THE REFACTOR OF HazardServicesProductGenerationHandler.JAVA
tup = (part[0], part[1])
@ -2356,8 +2368,8 @@ class LegacyFormatter():
text += '&&\n'
elif name not in self._noOpParts():
textStr = productDict.get(name)
self.debug_print("SARAH: name = %s" % (name), 1)
self.debug_print("SARAH: textStr = '%s'" % (textStr), 1)
self._textProduct.debug_print("name = %s" % (name), 1)
self._textProduct.debug_print("textStr = '%s'" % (textStr), 1)
if textStr:
text += textStr + '\n'
return text
@ -2431,14 +2443,17 @@ class LegacyFormatter():
if hazard['act'] == "CON":
hazardText = "A " + hazard['hdln'] + " remains in effect for " + self._areaWords(hazard['id'])
elif hazard['act'] in ["NEW", "EXA"]:
if hazard.has_key('upgradeFrom') and hazard['upgradeFrom'] is not None:
if isChangesHazards and hazard.has_key('upgradeFrom') and hazard['upgradeFrom'] is not None:
import VTECTable
upgradeRecord = hazard['upgradeFrom']
hazardText = "A " + VTECTable.VTECTable[upgradeRecord['phensig']]['hdln'] + \
" has been upgraded to a " + hazard['hdln'] + \
" for " + self._areaWords(hazard['id'])
else:
hazardText = "A " + hazard['hdln'] + " has been issued for " + self._areaWords(hazard['id'])
if isChangesHazards:
hazardText = "A " + hazard['hdln'] + " has been issued for " + self._areaWords(hazard['id'])
else:
hazardText = "A " + hazard['hdln'] + " is in effect for " + self._areaWords(hazard['id'])
elif hazard['act'] == "CAN":
hazardText = "The " + hazard['hdln'] + " for " + self._areaWords(hazard['id']) + " has been cancelled"
else:
@ -2523,11 +2538,11 @@ class LegacyFormatter():
curAdditionalImpactText = ""
count = 1
print("MATT DEBUG: %d sectionDict['additionalImpactRange'] = '%s'" % (len(sectionDict['additionalImpactRange']), sectionDict['additionalImpactRange']))
self._textProduct.debug_print("DEBUG: %d sectionDict['additionalImpactRange'] = '%s'" % (len(sectionDict['additionalImpactRange']), sectionDict['additionalImpactRange']))
for additionalImpact in sectionDict['additionalImpactRange']:
print("additionalImpact = '%s'" % (additionalImpact))
print("count = %d" % (count))
self._textProduct.debug_print("additionalImpact = '%s'" % (additionalImpact))
self._textProduct.debug_print("count = %d" % (count))
curAdditionalImpactText += \
self._textProduct.indentText(additionalImpact,
@ -2537,7 +2552,7 @@ class LegacyFormatter():
len(curAdditionalImpactText) > 0:
curAdditionalImpactText += "\n"
print("MATT DEBUG: curAdditionalImpactText ='%s'" % (curAdditionalImpactText))
self._textProduct.debug_print("DEBUG: curAdditionalImpactText ='%s'" % (curAdditionalImpactText))
count += 1
@ -2545,7 +2560,7 @@ class LegacyFormatter():
if additionalImpactRangeText.find(curAdditionalImpactText) == -1:
# Add this additional impact text
print("Adding current impact. '%s'" % (curAdditionalImpactText))
self._textProduct.debug_print("Adding current impact. '%s'" % (curAdditionalImpactText))
additionalImpactRangeText += curAdditionalImpactText
text += additionalImpactRangeText
@ -2562,11 +2577,11 @@ class LegacyFormatter():
"""
text = ''
for i in range(len(subParts)):
print("SARAH: subpart subParts[i] = %s" % (subParts[i]))
print("SARAH: subpart infoDicts[i] = %s" % (infoDicts[i]))
self._textProduct.debug_print("subpart subParts[i] = %s" % (subParts[i]))
self._textProduct.debug_print("subpart infoDicts[i] = %s" % (infoDicts[i]))
newtext = self._processProductParts(subParts[i], infoDicts[i].get('partsList'))
print("SARAH: subpart newtext type = %s" % (type(newtext)))
print("SARAH: subpart newtext = '%s'" % (repr(newtext)))
self._textProduct.debug_print("subpart newtext type = %s" % (type(newtext)))
self._textProduct.debug_print("subpart newtext = '%s'" % (self._pp.pformat(newtext)))
text += newtext
return text

View file

@ -1,4 +1,4 @@
# Version 2014.12.12-0
# Version 2015.1.6-0
import GenericHazards
import JsonSupport
@ -170,10 +170,10 @@ class TextProduct(HLSTCV_Common.TextProduct):
"_sectionHeader": 0,
"_lifePropertyThreatSummary": 0,
"_getThreatTrendSentence": 0,
"_getThreatTrendValue": 1,
"_threatDifference": 1,
"_isThreatDecreasing": 1,
"_isThreatIncreasing": 1,
"_getThreatTrendValue": 0,
"_threatDifference": 0,
"_isThreatDecreasing": 0,
"_isThreatIncreasing": 0,
"_advisoryHasValidKey": 0,
"_isMagnitudeIncreasing": 1,
"_calculateThreatStatementTr": 0,
@ -188,7 +188,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
#Unique to each section, but common method name
"sectionParts": 0,
"_forecastSubsection": 0,
"_latestForecastSummary": 1,
"_latestForecastSummary": 0,
"_threatSubsection": 0,
"_threatTrend": 0,
"_threatStatements": 0,
@ -262,7 +262,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
"checkLastArrow": 0,
}
# Definition["debug"] = 1 # turn on ALL debug messages
# Definition["debug"] = 0 # turn off ALL debug messages
Definition["debug"] = 0 # turn off ALL debug messages
def __init__(self):
@ -432,7 +432,6 @@ class TextProduct(HLSTCV_Common.TextProduct):
return analysisList
def _extraRainfallAnalysisList(self):
# The grids for the Surge Section will be intersected with a special edit area
analysisList = [
("QPF", self.accumSum),
]
@ -445,9 +444,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
def generateForecast(self, argDict):
# Generate Text Phrases for a list of edit areas
import pprint
pp = pprint.PrettyPrinter()
self.debug_print("argDict = %s" % (pp.pformat(argDict)), 1)
self.debug_print("argDict = %s" % (self._pp.pformat(argDict)), 1)
error = self._initializeVariables(argDict)
if error is not None:
@ -457,7 +454,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
return "Could not determine the storm name"
self._segmentList = self._determineSegments()
self.debug_print("Segment Information: %s" % (repr(self._segmentList)), 1)
self.debug_print("Segment Information: %s" % (self._pp.pformat(self._segmentList)), 1)
if len(self._segmentList) == 0:
return "NO HAZARDS TO REPORT"
@ -508,7 +505,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
def _setup_segment(self, segmentDict, productSegmentGroup, productSegment):
segment, vtecRecords = productSegment
self.debug_print('setup_segment productSegment %s' % (repr(productSegment)), 1)
self.debug_print('setup_segment productSegment %s' % (self._pp.pformat(productSegment)), 1)
# NOTE -- using _getVtecRecords to change to milliseconds
self._segmentVtecRecords = self._getVtecRecords(segment)
@ -544,14 +541,14 @@ class TextProduct(HLSTCV_Common.TextProduct):
vstr = None
vstr = vtecRecord["vtecstr"]
self.debug_print("vtecRecord = %s" % (repr(vtecRecord)), 1)
self.debug_print("vtecRecord = %s" % (self._pp.pformat(vtecRecord)), 1)
# Post-process some VTEC codes which should not exist
vstr = vstr.replace(".EXT.", ".CON.")
vstr = vstr.replace(".EXB.", ".EXA.")
if vtecRecord["phen"] == "SS":
# SARAH: Temporary? Change the vtec mode for SS hazards to be experimental
# Temporary? Change the vtec mode for SS hazards to be experimental
vstr = vstr[0] + 'X' + vstr[2:]
records.append(vstr)
segmentDict['vtecRecords'] = records
@ -604,7 +601,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
segmentDict['locationsAffected'] += tcv_AreaDictionary[segment]["locationsAffected"]
def _fcstConfidence(self, segmentDict, productSegmentGroup, productSegment):
# SARAH: TODO - Get this from the TCM product potentially? Not included until provided from NHC
# TODO - Get this from the TCM product potentially? Not included until provided from NHC
return ""
def _infoSection(self, segmentDict, productSegmentGroup, productSegment):
@ -682,13 +679,11 @@ class TextProduct(HLSTCV_Common.TextProduct):
timeRangeList,
editArea)
import pprint
pp = pprint.PrettyPrinter()
self.debug_print("*"*80)
self.debug_print("*"*80, 1)
for index in range(len(timeRangeList)):
self.debug_print("editArea =" + editArea, 1)
self.debug_print("timeRange = %s" % (pp.pformat(timeRangeList[index])), 1)
self.debug_print("statList = %s" % (pp.pformat(statList[index])), 1)
self.debug_print("timeRangeList = %s" % (self._pp.pformat(timeRangeList[index])), 1)
self.debug_print("statList = %s" % (self._pp.pformat(statList[index])), 1)
self.debug_print("-"*40, 1)
# These stats are for handling the extra rainfall
@ -721,21 +716,21 @@ class TextProduct(HLSTCV_Common.TextProduct):
# Get the segments based on hazards "overlaid" with combinations file
# Get the segments resulting from Hazards
#self.debug_print("\nRaw Analyzed %s" % (repr(self._hazardsTable.rawAnalyzedTable())), 1)
self.debug_print("Raw Analyzed %s" % (self._pp.pformat(self._hazardsTable.rawAnalyzedTable())), 1)
hazSegments = self.organizeHazards(self._hazardsTable.rawAnalyzedTable())
#self.debug_print("\nSegments from HazardsTable organizeHazards %s" % (repr(hazSegments)), 1)
self.debug_print("Segments from HazardsTable organizeHazards %s" % (self._pp.pformat(hazSegments)), 1)
# Get the forecaster entered combinations
accessor = ModuleAccessor.ModuleAccessor()
# self.debug_print("self._defaultEditAreas = %s" % (repr(self._defaultEditAreas)), 1)
self.debug_print("self._defaultEditAreas = %s" % (self._pp.pformat(self._defaultEditAreas)), 1)
combos = accessor.variable(self._defaultEditAreas, "Combinations")
if combos is None:
LogStream.logVerbose("COMBINATION FILE NOT FOUND: " + self._defaultEditAreas)
return [], None
#self.debug_print("\nSegments from Zone Combiner = %s" % (repr(combos)), 1)
self.debug_print("Segments from Zone Combiner = %s" % (self._pp.pformat(combos)), 1)
# "Overlay" the forecaster-entered combinations onto the segments
segmentList = self._refineSegments(hazSegments, combos)
#self.debug_print("\nNew segments = %s" % (repr(segmentList)), 1)
self.debug_print("New segments = %s" % (self._pp.pformat(segmentList)), 1)
# 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)
@ -763,9 +758,9 @@ class TextProduct(HLSTCV_Common.TextProduct):
# (We need to define self._segmentList for the mapping function
# to use)
self._segmentList = hazSegments
#self.debug_print("self._segmentList = %s" % (repr(self._segmentList)), 1)
self.debug_print("self._segmentList = %s" % (self._pp.pformat(self._segmentList)), 1)
segmentMapping = map(self._findSegment, combo)
#self.debug_print(" segmentMapping = %s" % (repr(segmentMapping)), 1)
self.debug_print(" segmentMapping = %s" % (self._pp.pformat(segmentMapping)), 1)
# segmentDict keys will be the hazSegments and
# we will gather all the areas of the combos that appear
@ -773,21 +768,21 @@ class TextProduct(HLSTCV_Common.TextProduct):
segmentDict = {}
keyList = []
for areaName in combo:
#self.debug_print(" Adding %s" % (areaName), 1)
self.debug_print(" Adding %s" % (areaName), 1)
key = tuple(segmentMapping[combo.index(areaName)])
if key == (): # If no hazard for area, do not include
continue
if key not in keyList:
keyList.append(key)
segmentDict.setdefault(key,[]).append(areaName)
#self.debug_print(" segmentDict = %s" % (repr(segmentDict)), 1)
self.debug_print(" segmentDict = %s" % (self._pp.pformat(segmentDict)), 1)
# Keep track of the areas that we are including
for key in keyList:
segAreas = segmentDict[key]
newAreas = newAreas + segAreas
newSegments.append(segAreas)
#self.debug_print(" newSegments = %s" % (repr(newSegments)), 1)
self.debug_print(" newSegments = %s" % (self._pp.pformat(newSegments)), 1)
# Now add in the hazAreas that have not been accounted for
# in the combinations
for hazSegment in hazSegments:
@ -842,7 +837,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
def _makeSegmentEditAreas(self, argDict):
areasList = self._allAreas()
#self.debug_print("areaList = %s" % (repr(areasList)), 1)
self.debug_print("areasList = %s" % (self._pp.pformat(areasList)), 1)
editAreas = []
self._editAreaDict = {}
for area in areasList:
@ -872,15 +867,15 @@ class TextProduct(HLSTCV_Common.TextProduct):
hazSegments = self.organizeHazards(hazardTable.rawAnalyzedTable())
self.debug_print("Segments from HazardsTable organizeHazards %s" %
(repr(hazSegments)), 1)
(self._pp.pformat(hazSegments)), 1)
combos = [([self._allAreas()], "AllAreas")]
self.debug_print("Segments from Zone Combiner %s" % (repr(combos)), 1)
self.debug_print("Segments from Zone Combiner %s" % (self._pp.pformat(combos)), 1)
# "Overlay" the forecaster-entered combinations onto the segments
segmentList = self._refineSegments(hazSegments, combos)
self.debug_print("SegmentList from refineSegments = %s" %
(repr(segmentList)), 1)
(self._pp.pformat(segmentList)), 1)
allHazards = []
for segment in segmentList:
@ -970,11 +965,11 @@ class TextProduct(HLSTCV_Common.TextProduct):
fileName,
advisoryDict)
self.debug_print("SARAH: Wrote file contents for: %s" % (fileName), 1)
self.debug_print("Wrote file contents for: %s" % (fileName), 1)
self._synchronizeAdvisories()
except Exception, e:
self.debug_print("SARAH Save Exception for %s : %s" % (fileName, e), 1)
self.debug_print("Save Exception for %s : %s" % (fileName, e), 1)
###############################################################
### GUI related methods
@ -1146,7 +1141,7 @@ class SectionCommon():
self._setProductPartValue(segmentDict, 'lifePropertyThreatSummary',
"Threat to Life and Property: " + threatLevel)
# SARAH - this new method will convert the single word threat trend into
# This new method will convert the single word threat trend into
# an appropriate sentence
def _getThreatTrendSentence(self, section, threatTrendValue):
@ -1163,10 +1158,10 @@ class SectionCommon():
threatKey = elementName + "Threat"
forecastKey = elementName + "Forecast"
self._textProduct.debug_print("SARAH: THREAT DEBUG for %s" % elementName, 1)
self._textProduct.debug_print("THREAT DEBUG for %s" % (elementName), 1)
self._textProduct.debug_print("SARAH: getThreatTrendValue _currentAdvisory =\n%s" % (repr(self._stats._currentAdvisory)), 1)
self._textProduct.debug_print("SARAH: getThreatTrendValue _previousAdvisory =\n%s" % (repr(self._stats._previousAdvisory)), 1)
self._textProduct.debug_print("getThreatTrendValue _currentAdvisory =\n%s" % (self._textProduct._pp.pformat(self._stats._currentAdvisory)), 1)
self._textProduct.debug_print("getThreatTrendValue _previousAdvisory =\n%s" % (self._textProduct._pp.pformat(self._stats._previousAdvisory)), 1)
if (self._stats._currentAdvisory is None) or (self._stats._previousAdvisory is None):
# Only compute a threat trend if we have 2 or more advisories
@ -1176,26 +1171,26 @@ class SectionCommon():
previousThreat = self._stats._previousAdvisory[threatKey]
shorterTermTrendDifference = self._threatDifference(currentThreat, previousThreat)
self._textProduct.debug_print("SARAH: currentThreat = %s" % currentThreat, 1)
self._textProduct.debug_print("SARAH: previousThreat = %s" % previousThreat, 1)
self._textProduct.debug_print("SARAH: shorterTermTrendDifference = %s" % shorterTermTrendDifference, 1)
self._textProduct.debug_print("currentThreat = %s" % (self._textProduct._pp.pformat(currentThreat)), 1)
self._textProduct.debug_print("previousThreat = %s" % (self._textProduct._pp.pformat(previousThreat)), 1)
self._textProduct.debug_print("shorterTermTrendDifference = %s" % (shorterTermTrendDifference), 1)
previousPreviousThreat = None
longerTermTrendDifference = None
if self._stats._previousPreviousAdvisory is not None:
self._textProduct.debug_print("SARAH: _previousPreviousAdvisory is not None", 1)
self._textProduct.debug_print("_previousPreviousAdvisory is not None", 1)
previousPreviousThreat = self._stats._previousPreviousAdvisory[threatKey]
self._textProduct.debug_print("SARAH: previousPreviousThreat = %s" % previousPreviousThreat, 1)
self._textProduct.debug_print("previousPreviousThreat = %s" % (self._textProduct._pp.pformat(previousPreviousThreat)), 1)
longerTermTrendDifference = self._threatDifference(currentThreat, previousPreviousThreat)
self._textProduct.debug_print("SARAH: longerTermTrendDifference = %s" % longerTermTrendDifference, 1)
self._textProduct.debug_print("longerTermTrendDifference = %s" % (longerTermTrendDifference), 1)
threatTrendValue = "NEARLY STEADY"
self._textProduct.debug_print("magnitudeIncreaseThreshold = %s forecastKey = '%s'" % (magnitudeIncreaseThreshold, forecastKey), 1)
if self._isThreatDecreasing(shorterTermTrendDifference, longerTermTrendDifference):
self._textProduct.debug_print("SARAH: threat is decreasing", 1)
self._textProduct.debug_print("threat is decreasing", 1)
threatTrendValue = "DECREASING"
elif self._isThreatIncreasing(shorterTermTrendDifference, longerTermTrendDifference):
self._textProduct.debug_print("SARAH: threat is increasing", 1)
self._textProduct.debug_print("threat is increasing", 1)
threatTrendValue = "INCREASING"
elif currentThreat == "Extreme" and \
self._isMagnitudeIncreasing(forecastKey, magnitudeIncreaseThreshold):
@ -1206,8 +1201,8 @@ class SectionCommon():
def _threatDifference(self, threat1, threat2):
threatLevels = self._textProduct._threatKeyOrder()
self._textProduct.debug_print("SARAH: threat1 index = %s" % threatLevels.index(threat1), 1)
self._textProduct.debug_print("SARAH: threat2 index = %s" % threatLevels.index(threat2), 1)
self._textProduct.debug_print("threat1 index = %s" % (threatLevels.index(threat1)), 1)
self._textProduct.debug_print("threat2 index = %s" % (threatLevels.index(threat2)), 1)
return threatLevels.index(threat1) - threatLevels.index(threat2)
def _isThreatDecreasing(self, shorterTermTrendDifference, longerTermTrendDifference):
@ -1215,14 +1210,14 @@ class SectionCommon():
if (shorterTermTrendDifference < 0 and \
longerTermTrendDifference is not None and \
longerTermTrendDifference < 0):
self._textProduct.debug_print("SARAH: the current threat is at least 1 category lower than both previous advisories", 1)
self._textProduct.debug_print("the current threat is at least 1 category lower than both previous advisories", 1)
return True
#Or if the current threat decreased by more than 1 category
elif shorterTermTrendDifference < -1:
self._textProduct.debug_print("SARAH: the current threat decreased by more than 1 category", 1)
self._textProduct.debug_print("the current threat decreased by more than 1 category", 1)
return True
else:
self._textProduct.debug_print("SARAH: the current threat is not decreasing", 1)
self._textProduct.debug_print("the current threat is not decreasing", 1)
return False
def _isThreatIncreasing(self, shorterTermTrendDifference, longerTermTrendDifference):
@ -1230,14 +1225,14 @@ class SectionCommon():
if (shorterTermTrendDifference > 0 and \
longerTermTrendDifference is not None and \
longerTermTrendDifference > 0):
self._textProduct.debug_print("SARAH: the current threat is at least 1 category higher than both previous advisories", 1)
self._textProduct.debug_print("the current threat is at least 1 category higher than both previous advisories", 1)
return True
#Or if the current threat increased by more than 1 category
elif shorterTermTrendDifference > 1:
self._textProduct.debug_print("SARAH: the current threat increased by more than 1 category", 1)
self._textProduct.debug_print("the current threat increased by more than 1 category", 1)
return True
else:
self._textProduct.debug_print("SARAH: the current threat is not increasing", 1)
self._textProduct.debug_print("the current threat is not increasing", 1)
return False
def _advisoryHasValidKey(self, advisory, key):
@ -1247,43 +1242,43 @@ class SectionCommon():
def _isMagnitudeIncreasing(self, forecastKey, threshold):
# currentValue, previousValue, previousPreviousValue
self._textProduct.debug_print("SARAH: _isMagnitudeIncreasing", 1)
self._textProduct.debug_print("SARAH: forecastKey = %s" % forecastKey, 1)
self._textProduct.debug_print("SARAH: threshold = %s" % threshold, 1)
self._textProduct.debug_print("_isMagnitudeIncreasing", 1)
self._textProduct.debug_print("forecastKey = %s" % (forecastKey), 1)
self._textProduct.debug_print("threshold = %s" % (threshold), 1)
if self._advisoryHasValidKey(self._stats._currentAdvisory, forecastKey) and \
self._advisoryHasValidKey(self._stats._previousAdvisory, forecastKey):
currentValue = self._stats._currentAdvisory[forecastKey]
previousValue = self._stats._previousAdvisory[forecastKey]
self._textProduct.debug_print("SARAH: currentValue = %s" % currentValue, 1)
self._textProduct.debug_print("SARAH: previousValue = %s" % previousValue, 1)
self._textProduct.debug_print("currentValue = %s" % (currentValue), 1)
self._textProduct.debug_print("previousValue = %s" % (previousValue), 1)
if (currentValue - previousValue) >= threshold:
self._textProduct.debug_print("SARAH: the current magnitude has increased by more than the threshold since the last advisory", 1)
self._textProduct.debug_print("the current magnitude has increased by more than the threshold since the last advisory", 1)
return True
elif self._advisoryHasValidKey(self._stats._previousPreviousAdvisory, forecastKey):
previousPreviousValue = self._stats._previousPreviousAdvisory[forecastKey]
self._textProduct.debug_print("SARAH: previousPreviousValue = %s" % previousPreviousValue, 1)
self._textProduct.debug_print("previousPreviousValue = %s" % (previousPreviousValue), 1)
if (currentValue - previousPreviousValue) >= threshold:
self._textProduct.debug_print("SARAH: the current magnitude has increased by more than the threshold since the previous previous advisory", 1)
self._textProduct.debug_print("the current magnitude has increased by more than the threshold since the previous previous advisory", 1)
return True
else:
self._textProduct.debug_print("SARAH: the current magnitude does not meet the requirements to be considered increasing", 1)
self._textProduct.debug_print("the current magnitude does not meet the requirements to be considered increasing", 1)
return False
else:
self._textProduct.debug_print("SARAH: the current magnitude did not increase past threshold and could not look at the previous previous advisory", 1)
self._textProduct.debug_print("the current magnitude did not increase past threshold and could not look at the previous previous advisory", 1)
return False
else:
self._textProduct.debug_print("SARAH: the current advisory and/or previous advisory did not have key: %s" % forecastKey, 1)
self._textProduct.debug_print("the current advisory and/or previous advisory did not have key: %s" % (forecastKey), 1)
return False
def _calculateThreatStatementTr(self, onsetHour, endHour, threatTrendValue):
tr = None
self._textProduct.debug_print("SARAH: onset hour = %s" % (onsetHour), 1)
self._textProduct.debug_print("SARAH: end hour = %s" % (endHour), 1)
self._textProduct.debug_print("SHANNON: threatTrendValue = %s" %
self._textProduct.debug_print("onset hour = %s" % (onsetHour), 1)
self._textProduct.debug_print("end hour = %s" % (endHour), 1)
self._textProduct.debug_print("threatTrendValue = %s" %
(threatTrendValue), 1)
if (onsetHour is not None) and \
@ -1304,8 +1299,8 @@ class SectionCommon():
def _setThreatStatementsProductParts(self, segmentDict, productSegment, tr):
self._textProduct.debug_print("SHANNON: tr = %s %s" %
(repr(tr), self._sectionHeaderName), 1)
self._textProduct.debug_print("tr = %s %s" %
(self._textProduct._pp.pformat(tr), self._sectionHeaderName), 1)
# if tr is not None and self._stats._maxThreat is not None:
if tr is not None:
(planning, action, preparation) = self._getThreatStatements(productSegment,
@ -1316,7 +1311,7 @@ class SectionCommon():
self._setProductPartValue(segmentDict, 'threatStatements',
[planning, action, preparation])
else:
self._textProduct.debug_print("SHANNON messed up", 1)
self._textProduct.debug_print("this is not a valid time range", 1)
return
def _getThreatStatements(self, productSegment, sectionName, maxThreat, tr):
@ -1332,7 +1327,7 @@ class SectionCommon():
self._textProduct.debug_print(40*"-", 1)
self._textProduct.debug_print("sectionName = %s, maxThreat = %s, tr = %s" %
(sectionName, maxThreat, repr(tr)), 1)
(sectionName, maxThreat, self._textProduct._pp.pformat(tr)), 1)
# if maxThreat is None:
# maxThreat = "None"
@ -1364,7 +1359,7 @@ class SectionCommon():
return "Potential Impacts: " + impactLevel
def _potentialImpactsStatements(self, segmentDict, productSegmentGroup, productSegment):
self._textProduct.debug_print("SHANNON: segment = %s, elementName = %s, maxThreat = %s" %
self._textProduct.debug_print("segment = %s, elementName = %s, maxThreat = %s" %
(productSegment[0], self._sectionHeaderName, self._stats._maxThreat), 1)
if self._stats._maxThreat is not None:
statements = self._getPotentialImpactsStatements(productSegment, self._sectionHeaderName, self._stats._maxThreat)
@ -1381,7 +1376,7 @@ class SectionCommon():
segment, vtecRecords = productSegment
self._textProduct.debug_print("SHANNON: zone number = %s, elementName = %s, maxThreat = %s" %
self._textProduct.debug_print("zone number = %s, elementName = %s, maxThreat = %s" %
(segment, elementName, maxThreat), 1)
if segment in tcv_AreaDictionary:
@ -1492,7 +1487,7 @@ class WindSection(SectionCommon):
if self._stats._maxGust is not None:
moderatedMaxWindGust = self._ktToMph(self._stats._maxGust, "WindGust")
# # SARAH - we want to round the wind gust to the nearest 5 kt
# # We want to round the wind gust to the nearest 5 kt
# moderatedMaxWindGust = \
# self._textProduct.round(moderatedMaxWindGust, "Nearest", 5)
@ -1533,7 +1528,8 @@ class WindSection(SectionCommon):
windTr = self._calculateThreatStatementTr(self._stats._onset34Hour,
self._stats._end34Hour,
self._threatTrendValue)
# self._textProduct.debug_print("MATT: in _threatStatements tr = %s" % (repr(windTr))
self._textProduct.debug_print("in _threatStatements tr = %s" %
(self._textProduct._pp.pformat(windTr)), 1)
if not hasattr(self._textProduct, "_windThreatStatementsTr"):
self._textProduct._windThreatStatementsTr = dict()
@ -1550,7 +1546,7 @@ class WindSection(SectionCommon):
# if len(subsectionDict) > 0:
# self._setProductPartValue(segmentDict, 'impactsSubsection', subsectionDict)
# SARAH - modified to not include wind impacts during the "recovery" and
# Modified to not include wind impacts during the "recovery" and
# "nothing to see here" phases of the tropical cyclone event
def _impactsSubsection(self, segmentDict, productSegmentGroup, productSegment):
@ -1664,7 +1660,7 @@ class StormSurgeSection(SectionCommon):
words = str(int(max - maxRange)) + "-" + str(int(max)) + " feet above ground"
elif max > 0:
# SARAH - we were getting really weird values of peak surge
# We were getting really weird values of peak surge
# (e.g. "UP TO 1.70000004768 FEET"). This fix will round up
# to the nearest integer value
# words = "Up to " + str(max) + " feet above ground"
@ -1711,7 +1707,7 @@ class StormSurgeSection(SectionCommon):
threatTrendSentence)
def _threatStatements(self, segmentDict, productSegmentGroup, productSegment):
self._textProduct.debug_print("SARAH: Surge Threat Statements", 1)
self._textProduct.debug_print("Surge Threat Statements", 1)
surgeTr = self._calculateThreatStatementTr(self._stats._onsetSurgeHour,
self._stats._endSurgeHour,
self._threatTrendValue)
@ -1731,7 +1727,7 @@ class StormSurgeSection(SectionCommon):
def _potentialImpactsSummary(self, segmentDict, productSegmentGroup, productSegment):
if not self._textProduct._PopulateSurge:
# SARAH - We do not want the '(For plausible worst case)' in the text
# We do not want the '(For plausible worst case)' in the text
# self._setProductPartValue(segmentDict, 'potentialImpactsSummary',
# "Potential Impacts (For plausible worst case): Not available at this time. To be updated shortly.")
self._setProductPartValue(segmentDict, 'potentialImpactsSummary',
@ -1948,28 +1944,28 @@ class SectionCommonStats():
self._currentAdvisory = self._textProduct._currentAdvisory['ZoneData'][self._segment]
self._previousAdvisory = None
# self._textProduct.debug_print("MATT textProduct._previousAdvisory = '%s'" % (textProduct._previousAdvisory))
self._textProduct.debug_print("textProduct._previousAdvisory = '%s'" % (self._textProduct._previousAdvisory))
if self._textProduct._previousAdvisory is not None:
if self._textProduct._previousAdvisory['ZoneData'].has_key(self._segment):
self._previousAdvisory = self._textProduct._previousAdvisory['ZoneData'][self._segment]
# self._textProduct.debug_print("MATT textProduct._previousPreviousAdvisory = '%s'" % \
# (textProduct._previousPreviousAdvisory))
self._textProduct.debug_print("textProduct._previousPreviousAdvisory = '%s'" % \
(self._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):
self._textProduct.debug_print("statDict = '%s'" % (repr(statDict)), 1)
self._textProduct.debug_print("statDict = '%s'" % (self._textProduct._pp.pformat(statDict)), 1)
threatLevel = self._textProduct.getStats(statDict, threatGridName)
if threatLevel is not None:
threatLevels = self._textProduct._threatKeyOrder()
self._textProduct.debug_print("SARAH: updateThreatStats for %s" % (threatGridName), 1)
self._textProduct.debug_print("SARAH: threatLevel = %s" % (threatLevel), 1)
self._textProduct.debug_print("SARAH: maxThreat = %s" % (self._maxThreat), 1)
self._textProduct.debug_print("updateThreatStats for %s" % (threatGridName), 1)
self._textProduct.debug_print("threatLevel = %s" % (threatLevel), 1)
self._textProduct.debug_print("maxThreat = %s" % (self._maxThreat), 1)
if self._maxThreat is None or \
threatLevels.index(threatLevel) > threatLevels.index(self._maxThreat):
self._textProduct.debug_print("SARAH: updating max threat to = %s" % (threatLevel), 1)
self._textProduct.debug_print("updating max threat to = %s" % (threatLevel), 1)
self._maxThreat = threatLevel
def _calculateHourOffset(self, targetTime):
@ -1992,8 +1988,8 @@ class WindSectionStats(SectionCommonStats):
self._windowTS = None
self._windowHU = None
print "*"*90
print "Setting wind stats for %s" % (segment)
self._textProduct.debug_print("*"*90)
self._textProduct.debug_print("Setting wind stats for %s" % (segment), 1)
self._setStats(statList, timeRangeList)
@ -2006,7 +2002,6 @@ class WindSectionStats(SectionCommonStats):
dropFirstGridType = None
droppedFirstGrid = False
periodWithFirstCorrectGrid = None
onsetTime = None
endTime = None
class TimeInfo():
@ -2031,6 +2026,7 @@ class WindSectionStats(SectionCommonStats):
statDict = statList[index]
for periodIndex, periodTr in enumerate(self._textProduct._periodList):
self._textProduct.debug_print("\n\nperiodIndex = %d periodList tr = %s" % (periodIndex, repr(periodTr)), 1)
if (periodIndex == 0) and (tr.startTime().unixTime() < periodTr.startTime().unixTime()):
# If the tr is before the first period, use the first period
currentPeriod = periodIndex
@ -2065,7 +2061,7 @@ class WindSectionStats(SectionCommonStats):
self._onset34Hour = onsetEndInfo.onsetHour
self._end34Hour = onsetEndInfo.endHour
self._textProduct.debug_print("SARAH: Tropical Storm Window:", 1)
self._textProduct.debug_print("Tropical Storm Window:", 1)
self._windowTS = self._createWindow("Tropical Storm",
self._onset34Hour,
self._end34Hour)
@ -2075,7 +2071,7 @@ class WindSectionStats(SectionCommonStats):
self._onset64Hour = onsetEndInfo.onsetHour
self._end64Hour = onsetEndInfo.endHour
self._textProduct.debug_print("SARAH: Hurricane Window:", 1)
self._textProduct.debug_print("Hurricane Window:", 1)
self._windowHU = self._createWindow("Hurricane",
self._onset64Hour,
self._end64Hour)
@ -2091,68 +2087,84 @@ class WindSectionStats(SectionCommonStats):
pwsXXintStats.max = pwsXXint
pwsXXintStats.onsetHour = self._calculateHourOffset(tr.startTime())
self._textProduct.debug_print("SARAH: Window Debug: pwsXXintStats gridName = %s" % (gridName), 1)
self._textProduct.debug_print("SARAH: Window Debug: pwsXXintStats onsetHour = %s" % (pwsXXintStats.onsetHour), 1)
self._textProduct.debug_print("Wind Window Debug: pwsXXintStats gridName = %s" % (gridName), 1)
self._textProduct.debug_print("Wind Window Debug: pwsXXintStats onsetHour = %s" % (pwsXXintStats.onsetHour), 1)
def _updateStatsForPwsTXX(self, tr, statDict, dayGridName, nightGridName, pwsTXXStats, period):
pwsDXX = self._textProduct._getStatValue(statDict, dayGridName, "Max")
pwsNXX = self._textProduct._getStatValue(statDict, nightGridName, "Max")
if pwsTXXStats.firstRun:
self._textProduct.debug_print("SARAH: first run for _updateStatsForPwsTXX!", 1)
self._textProduct.debug_print("SARAH: grids: %s %s" % (dayGridName, nightGridName), 1)
self._textProduct.debug_print("first run for _updateStatsForPwsTXX!", 1)
self._textProduct.debug_print("grids: %s %s" % (dayGridName, nightGridName), 1)
pwsTXXStats.firstRun = False
localtime = time.localtime(self._textProduct._issueTime_secs)
self._textProduct.debug_print("SARAH: localtime = %s" % (localtime), 1)
self._textProduct.debug_print("localtime = %s" % (localtime), 1)
if localtime.tm_hour >= 15: # 3PM to midnight
self._textProduct.debug_print("SARAH: between 3PM and midnight!", 1)
self._textProduct.debug_print("between 3PM and midnight!", 1)
pwsTXXStats.dropFirstGridType = "DAY"
self._textProduct.debug_print("SARAH: need to drop the day grid(s) if they come first", 1)
self._textProduct.debug_print("need to drop the day grid(s) if they come first", 1)
elif localtime.tm_hour >= 3 and localtime.tm_hour < 12: # 3AM to noon
self._textProduct.debug_print("SARAH: between 3AM and noon!", 1)
self._textProduct.debug_print("between 3AM and noon!", 1)
pwsTXXStats.dropFirstGridType = "NIGHT"
self._textProduct.debug_print("SARAH: need to drop the night grid(s) if they come first", 1)
self._textProduct.debug_print("need to drop the night grid(s) if they come first", 1)
else:
self._textProduct.debug_print("SARAH: not dropping any grids!", 1)
self._textProduct.debug_print("not dropping any grids!", 1)
maxPws = None
self._textProduct.debug_print("MATT %s pwsDXX = %s pwsNXX = %s " %
(repr(tr),pwsDXX, pwsNXX), 1)
self._textProduct.debug_print("%s pwsDXX = %s pwsNXX = %s " %
(self._textProduct._pp.pformat(tr),pwsDXX, pwsNXX), 1)
if pwsDXX is not None:
self._textProduct.debug_print("SARAH: Window Debug: pwsTXXStats DAY", 1)
# Determine coversion factor to get DAY and NIGHT in UTC
utcHourOffset = self._calculateUTCandLocalHourOffset()
# See if this hour a valid DAYtime hour
isValidDay = self._isValidDayTime(tr.startTime().hour,
self._textProduct.DAY() + utcHourOffset,
self._textProduct.NIGHT() + utcHourOffset)
# If we have pwsD data, and this is a time period it applies to
if pwsDXX is not None and isValidDay:
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats DAY", 1)
if pwsTXXStats.dropFirstGridType == "DAY":
self._textProduct.debug_print("SARAH: Window Debug: dropping a day grid", 1)
self._textProduct.debug_print("SARAH: Window Debug: tr = %s, period = %s" % (tr, period), 1)
self._textProduct.debug_print("Wind Window Debug: dropping a day grid", 1)
self._textProduct.debug_print("Wind Window Debug: tr = %s, period = %s" % (tr, period), 1)
pwsTXXStats.droppedFirstGrid = True
return
elif pwsTXXStats.dropFirstGridType == "NIGHT":
# We dropped all the necessary grids now that we found a day grid so stop dropping
pwsTXXStats.dropFirstGridType = None
pwsTXXStats.periodWithFirstCorrectGrid = period
self._textProduct.debug_print("SARAH: Window Debug: found day grid; done dropping night grids", 1)
self._textProduct.debug_print("SARAH: Window Debug: tr = %s, period = %s" % (tr, period), 1)
self._textProduct.debug_print("Wind Window Debug: found day grid; done dropping night grids", 1)
self._textProduct.debug_print("Wind Window Debug: tr = %s, period = %s" % (tr, period), 1)
maxPws = pwsDXX
elif pwsNXX is not None:
self._textProduct.debug_print("SARAH: Window Debug: pwsTXXStats NIGHT", 1)
# If we have pwsN data, and this is a time period it applies to
elif pwsNXX is not None and not isValidDay:
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats NIGHT", 1)
if pwsTXXStats.dropFirstGridType == "NIGHT":
self._textProduct.debug_print("SARAH: Window Debug: dropping a night grid", 1)
self._textProduct.debug_print("SARAH: Window Debug: tr = %s, period = %s" % (tr, period), 1)
self._textProduct.debug_print("Wind Window Debug: dropping a night grid", 1)
self._textProduct.debug_print("Wind Window Debug: tr = %s, period = %s" % (tr, period), 1)
pwsTXXStats.droppedFirstGrid = True
return
elif pwsTXXStats.dropFirstGridType == "DAY":
# We dropped all the necessary grids now that we found a night grid so stop dropping
pwsTXXStats.dropFirstGridType = None
pwsTXXStats.periodWithFirstCorrectGrid = period
self._textProduct.debug_print("SARAH: Window Debug: found night grid; done dropping day grids", 1)
self._textProduct.debug_print("SARAH: Window Debug: tr = %s, period = %s" % (tr, period), 1)
self._textProduct.debug_print("Wind Window Debug: found night grid; done dropping day grids", 1)
self._textProduct.debug_print("Wind Window Debug: tr = %s, period = %s" % (tr, period), 1)
maxPws = pwsNXX
elif pwsDXX is not None and tr.startTime().hour in [21, 0, 3]:
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats DAY ignored", 1)
elif pwsNXX is not None and tr.startTime().hour in [9, 12, 15]:
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats NIGHT ignored", 1)
threshold34index = 0
threshold64index = 1
@ -2160,7 +2172,7 @@ class WindSectionStats(SectionCommonStats):
# Don't shift if the period with the first correct grid is period 0
if pwsTXXStats.droppedFirstGrid and pwsTXXStats.periodWithFirstCorrectGrid != 0:
period = period - 1 # We dropped the first grid so we are off-by-one
self._textProduct.debug_print("SARAH: shifting period back 1...new period = %s" %
self._textProduct.debug_print("shifting period back 1...new period = %s" %
(period), 1)
if "64" in dayGridName:
@ -2170,6 +2182,7 @@ class WindSectionStats(SectionCommonStats):
threshold = None
thresholds = self._textProduct.windSpdProb_thresholds(threshold, threshold)
self._textProduct.debug_print("Getting probability threshold for period %s" % (period), 1)
if period == 0:
(thresholdLow, thresholdHigh) = thresholds[period][index]
threshold = thresholdLow
@ -2177,43 +2190,43 @@ class WindSectionStats(SectionCommonStats):
threshold = thresholds[period][index]
if maxPws > threshold:
pwsTXXStats.onsetTime = tr.startTime()
pwsTXXStats.endTime = tr.endTime()
self._textProduct.debug_print("SARAH: Window Debug: pwsTXXStats dayGridName = %s" % (dayGridName), 1)
self._textProduct.debug_print("SARAH: Window Debug: pwsTXXStats nightGridName = %s" % (nightGridName), 1)
self._textProduct.debug_print("SARAH: Window Debug: pwsTXXStats original tr = %s" % (repr(tr)), 1)
self._textProduct.debug_print("SARAH: Window Debug: pwsTXXStats maxPws = %s" %(repr(maxPws)), 1)
self._textProduct.debug_print("SARAH: Window Debug: pwsTXXStats onsetTime = %s" % (repr(pwsTXXStats.onsetTime)), 1)
self._textProduct.debug_print("SARAH: Window Debug: pwsTXXStats endTime = %s" % (repr(pwsTXXStats.endTime)), 1)
self._textProduct.debug_print("Wind Window Debug: probability threshold = %s (period index %s)" % (threshold, period), 1)
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats dayGridName = %s" % (dayGridName), 1)
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats nightGridName = %s" % (nightGridName), 1)
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats original tr = %s" % (self._textProduct._pp.pformat(tr)), 1)
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats maxPws = %s" %(self._textProduct._pp.pformat(maxPws)), 1)
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats endTime = %s" % (self._textProduct._pp.pformat(pwsTXXStats.endTime)), 1)
def _updateWindTimeInfo(self, tr, wind, timeInfo, speed):
if wind >= speed:
timeInfo.endHour = self._calculateHourOffset(tr.endTime())
self._textProduct.debug_print("SARAH: Window Debug: In _updateWindTimeInfo", 1)
self._textProduct.debug_print("SARAH: Window Debug: timeInfo speed = %s" % (speed), 1)
self._textProduct.debug_print("SARAH: Window Debug: timeInfo maxWind = %s" % (self._maxWind), 1)
self._textProduct.debug_print("SARAH: Window Debug: timeInfo tr = %s" % (repr(tr)), 1)
self._textProduct.debug_print("SARAH: Window Debug: timeInfo endHour = %s" % (timeInfo.endHour), 1)
self._textProduct.debug_print("Wind Window Debug: In _updateWindTimeInfo", 1)
self._textProduct.debug_print("Wind Window Debug: timeInfo speed = %s" % (speed), 1)
self._textProduct.debug_print("Wind Window Debug: timeInfo maxWind = %s" % (self._maxWind), 1)
self._textProduct.debug_print("Wind Window Debug: timeInfo tr = %s" % (self._textProduct._pp.pformat(tr)), 1)
self._textProduct.debug_print("Wind Window Debug: timeInfo endHour = %s" % (timeInfo.endHour), 1)
if timeInfo.onsetHour is None:
timeInfo.onsetHour = self._calculateHourOffset(tr.startTime())
self._textProduct.debug_print("SARAH: Window Debug: onsetHour was None", 1)
self._textProduct.debug_print("SARAH: Window Debug: timeInfo speed = %s" % (speed), 1)
self._textProduct.debug_print("SARAH: Window Debug: timeInfo maxWind = %s" % (self._maxWind), 1)
self._textProduct.debug_print("SARAH: Window Debug: timeInfo tr = %s" % (repr(tr)), 1)
self._textProduct.debug_print("SARAH: Window Debug: timeInfo onsetHour = %s" % (timeInfo.onsetHour), 1)
self._textProduct.debug_print("Wind Window Debug: onsetHour was None", 1)
self._textProduct.debug_print("Wind Window Debug: timeInfo speed = %s" % (speed), 1)
self._textProduct.debug_print("Wind Window Debug: timeInfo maxWind = %s" % (self._maxWind), 1)
self._textProduct.debug_print("Wind Window Debug: timeInfo tr = %s" % (self._textProduct._pp.pformat(tr)), 1)
self._textProduct.debug_print("Wind Window Debug: timeInfo onsetHour = %s" % (timeInfo.onsetHour), 1)
def _computeWindOnsetAndEnd(self, windTimeInfo, pwsXXintStats, pwsTXXStats):
onsetEndInfo = self.TimeInfo()
self._textProduct.debug_print("SARAH: Window Debug: In _computeWindOnsetAndEnd", 1)
self._textProduct.debug_print("SARAH: Window Debug: windTimeInfo.onsetHour = %s" % (windTimeInfo.onsetHour), 1)
self._textProduct.debug_print("SARAH: Window Debug: pwsXXintStats.onsetHour = %s" % (pwsXXintStats.onsetHour), 1)
self._textProduct.debug_print("SARAH: Window Debug: windTimeInfo.endHour = %s" % (windTimeInfo.endHour), 1)
self._textProduct.debug_print("SARAH: Window Debug: pwsTXXStats.endTime = %s" % (pwsTXXStats.endTime), 1)
self._textProduct.debug_print("Wind Window Debug: In _computeWindOnsetAndEnd", 1)
self._textProduct.debug_print("Wind Window Debug: windTimeInfo.onsetHour = %s" % (windTimeInfo.onsetHour), 1)
self._textProduct.debug_print("Wind Window Debug: pwsXXintStats.onsetHour = %s" % (pwsXXintStats.onsetHour), 1)
self._textProduct.debug_print("Wind Window Debug: windTimeInfo.endHour = %s" % (windTimeInfo.endHour), 1)
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats.endTime = %s" % (pwsTXXStats.endTime), 1)
if pwsTXXStats.endTime is not None:
self._textProduct.debug_print("Wind Window Debug: pwsTXXStats end hour = %s" % (self._calculateHourOffset(pwsTXXStats.endTime)), 1)
if windTimeInfo.onsetHour is None:
# We won't have a timing window
@ -2240,27 +2253,35 @@ class WindSectionStats(SectionCommonStats):
self._textProduct.debug_print("endTime for pwsTXXStats is not None", 1)
endUnixTime = pwsTXXStats.endTime.unixTime()
endLocalTime = time.localtime(endUnixTime)
startUnixTime = pwsTXXStats.onsetTime.unixTime()
startLocalTime = time.localtime(startUnixTime)
if endLocalTime.tm_hour >= 6 and endLocalTime.tm_hour < 18:
configuredTime = absTimeYMD(endLocalTime.tm_year,
endLocalTime.tm_mon,
endLocalTime.tm_mday,
self._textProduct.DAY())
elif endLocalTime.tm_hour < 6:
# Use 6 PM of previous day
configuredTime = absTimeYMD(startLocalTime.tm_year,
startLocalTime.tm_mon,
startLocalTime.tm_mday,
utcHourOffset = self._calculateUTCandLocalHourOffset()
self._textProduct.debug_print("utcHourOffset = %s" % (utcHourOffset), 1)
self._textProduct.debug_print("endTime for pwsTXXStats in local time is %s" %
(self._textProduct._pp.pformat(endLocalTime)), 1)
# Remember these times are in local time zone, so hour 0 is
# midnight of the current calendar day.
if endLocalTime.tm_hour > 6 and endLocalTime.tm_hour <= 18:
configuredTime = absTimeYMD(pwsTXXStats.endTime.year,
pwsTXXStats.endTime.month,
pwsTXXStats.endTime.day,
self._textProduct.NIGHT())
else:
configuredTime = absTimeYMD(endLocalTime.tm_year,
endLocalTime.tm_mon,
endLocalTime.tm_mday,
self._textProduct.NIGHT())
configuredTime = absTimeYMD(pwsTXXStats.endTime.year,
pwsTXXStats.endTime.month,
pwsTXXStats.endTime.day,
self._textProduct.DAY())
self._textProduct.debug_print("configuredTime (local time) = %s" %
(self._textProduct._pp.pformat(configuredTime)), 1)
# The configured hour is localtime so we need to add an offset to make the entire date UTC
configuredUnixTime = configuredTime.unixTime() + (utcHourOffset * 3600)
configuredTime = AbsTime(configuredUnixTime)
self._textProduct.debug_print("configuredTime (UTC time) = %s" %
(self._textProduct._pp.pformat(configuredTime)), 1)
probEndHour = self._calculateHourOffset(configuredTime)
onsetEndInfo.endHour = int(round(self._textProduct.average(windTimeInfo.endHour, probEndHour)))
self._textProduct.debug_print("endHour = " + str(onsetEndInfo.endHour), 1)
else:
@ -2271,13 +2292,13 @@ class WindSectionStats(SectionCommonStats):
def _createWindow(self, windowName, onsetHour, endHour):
window = "Window for " + windowName + " force winds: "
self._textProduct.debug_print("SARAH: In _createWindow", 1)
self._textProduct.debug_print("SARAH: window stats:", 1)
self._textProduct.debug_print("SARAH: onsetHour = %s" % (onsetHour), 1)
self._textProduct.debug_print("SARAH: endHour = %s" % (endHour), 1)
self._textProduct.debug_print("In _createWindow", 1)
self._textProduct.debug_print("window stats:", 1)
self._textProduct.debug_print("onsetHour = %s" % (onsetHour), 1)
self._textProduct.debug_print("endHour = %s" % (endHour), 1)
if onsetHour is None:
# SARAH - we do not want a statement of a non-existent window
# We do not want a statement of a non-existent window
# window += "None"
window = None
else:
@ -2287,7 +2308,7 @@ class WindSectionStats(SectionCommonStats):
windowPeriod = self._textProduct.makeTimeRange(startTime, endTime)
else:
windowPeriod = self._textProduct.makeTimeRange(startTime, startTime + 1)
self._textProduct.debug_print("SARAH: window period = %s" % (windowPeriod), 1)
self._textProduct.debug_print("window period = %s" % (windowPeriod), 1)
startTimeDescriptor = ""
if onsetHour >= 18:
@ -2320,6 +2341,33 @@ class WindSectionStats(SectionCommonStats):
window += startTimeDescriptor + connector + endTimeDescriptor
return window
def _calculateUTCandLocalHourOffset(self):
utc = time.gmtime()
local = time.localtime()
diffInSeconds = time.mktime(utc) - time.mktime(local)
return int(diffInSeconds // 3600)
def _isValidDayTime(self, trStartHour, utcDay, utcNight):
# Handle case where "night" starts at an "earlier" UTC hour than "day"
# (e.g. DAY = 18Z and NIGHT = 06Z)
if (utcNight < utcDay) and \
(trStartHour >= utcDay or trStartHour < utcNight):
# If we are toward the end of the daytime, and more than 1 hour
# from its end
if (trStartHour < utcNight) and (utcNight - trStartHour) > 1:
return True
# Handle "normal" case where "day" starts before "night" in UTC
elif trStartHour >= utcDay and trStartHour < utcNight and \
(utcNight - trStartHour) > 1:
return True
# If we made it this far, this is not a valid "day" hour
return False
class StormSurgeSectionStats(SectionCommonStats):
@ -2338,7 +2386,7 @@ class StormSurgeSectionStats(SectionCommonStats):
possibleStop = 0
self._textProduct.debug_print("*"*100, 1)
self._textProduct.debug_print("MATT phishStartTime = %s phishEndTime = %s possibleStop = %d" %
self._textProduct.debug_print("phishStartTime = %s phishEndTime = %s possibleStop = %d" %
(str(phishStartTime), str(phishEndTime), possibleStop), 1)
for period in range(len(statList)):
@ -2351,10 +2399,10 @@ class StormSurgeSectionStats(SectionCommonStats):
self._inundationMax = phishPeak
curPhish = self._textProduct._getStatValue(statDict, "InundationTiming", "Max")
self._textProduct.debug_print("MATT tr = %s" % (repr(tr)), 1)
self._textProduct.debug_print("MATT curPhish = '%s' possibleStop = %d" %
self._textProduct.debug_print("tr = %s" % (self._textProduct._pp.pformat(tr)), 1)
self._textProduct.debug_print("curPhish = '%s' possibleStop = %d" %
(str(curPhish), possibleStop), 1)
self._textProduct.debug_print("MATT phishStartTime = %s phishEndTime = %s" %
self._textProduct.debug_print("phishStartTime = %s phishEndTime = %s" %
(str(phishStartTime), str(phishEndTime)), 1)
if curPhish is not None and possibleStop != 2:
@ -2379,15 +2427,15 @@ class StormSurgeSectionStats(SectionCommonStats):
self._onsetSurgeHour = self._calculateHourOffset(phishStartTime)
startTime = AbsTime(self._textProduct._issueTime_secs + self._onsetSurgeHour*60*60)
self._textProduct.debug_print("MATT surge startTime = %s self._onsetSurgeHour = %s " %
(repr(startTime), self._onsetSurgeHour), 1)
self._textProduct.debug_print("surge startTime = %s self._onsetSurgeHour = %s " %
(self._textProduct._pp.pformat(startTime), self._onsetSurgeHour), 1)
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)
self._textProduct.debug_print("SARAH: surge window period = %s" % (windowPeriod), 1)
self._textProduct.debug_print("surge window period = %s" % (windowPeriod), 1)
startTimeDescriptor = self._textProduct._formatPeriod(windowPeriod)
@ -2455,7 +2503,7 @@ class FloodingRainSectionStats(SectionCommonStats):
prevStatDict = extraRainfallStatList[period]
prevStats = self._textProduct.getStats(prevStatDict, "QPF")
print "prevStats = ", prevStats
self._textProduct.debug_print("prevStats = %s" % (prevStats), 1)
if prevStats is not None:
self._prevAccum += prevStats
else:
@ -2497,8 +2545,8 @@ class XMLFormatter():
def execute(self, productDict):
xml = Element('product')
self.dictionary(xml, productDict)
self._textProduct.debug_print("SARAH: XML = %s" % (xml), 1)
self._textProduct.debug_print("SARAH: XML dump = %s", dump(xml), 1)
self._textProduct.debug_print("XML = %s" % (xml), 1)
self._textProduct.debug_print("XML dump = %s", dump(xml), 1)
prettyXML = minidom.parseString(tostring(xml))
return prettyXML.toprettyxml() #tostring(xml)
@ -2602,7 +2650,7 @@ class XMLFormatter():
if "._" in sectionKey:
sectionKey = re.sub(".*\._", "", sectionKey)
self._textProduct.debug_print("SARAH: sectionKey = %s" % (sectionKey), 1)
self._textProduct.debug_print("sectionKey = %s" % (sectionKey), 1)
return sectionKey
def dictionary(self, xml, productDict):
@ -2622,7 +2670,7 @@ class XMLFormatter():
if key not in self.xmlKeys():
sectionKey = self.getSectionKey(key)
if sectionKey not in self.sectionKeys():
self._textProduct.debug_print("SARAH: skipping '%s' in XML" % (key), 1)
self._textProduct.debug_print("skipping '%s' in XML" % (key), 1)
continue
else:
key = sectionKey
@ -2664,8 +2712,8 @@ class XMLFormatter():
if data is not None:
if 'info' in key and 'Section' in key:
subElement = SubElement(xml, key)
self._textProduct.debug_print("SARAH: info key = '%s'" % (key), 1)
self._textProduct.debug_print("SARAH: value = %s" % (data), 1)
self._textProduct.debug_print("info key = '%s'" % (key), 1)
self._textProduct.debug_print("value = %s" % (data), 1)
if isinstance(data, list):
subkey = 'info' + 'Sub' + key[4:]
for value in data:
@ -2714,7 +2762,7 @@ class LegacyFormatter():
@return text -- product string
'''
text = ''
self._textProduct.debug_print("productParts = %s" % (repr(productParts)), 1)
self._textProduct.debug_print("productParts = %s" % (self._textProduct._pp.pformat(productParts)), 1)
for part in productParts:
valtype = type(part)
if valtype is str:
@ -2925,5 +2973,3 @@ class LegacyFormatter():
newtext = self._processProductParts(subParts[i], infoDicts[i].get('partsList'))
text += newtext
return text

View file

@ -42,6 +42,7 @@
# start time from file's timestamp.
# Oct 03, 2013 2402 bsteffen Make PythonDecoder more extendable.
# Jun 10, 2014 3268 dgilling Update location of WclInfo class.
# Dec 17, 2014 4953 randerso Fixed decoding of non-VTEC from command line
# </pre>
#
@ -111,10 +112,10 @@ class StdWarningDecoder():
self._timeOffset = 0
#decode the command line
if text is None and filePath is None:
if command is not None:
self._decodeCommandLine()
self._rawMessage = None
checkForWmo = False
checkForWmo = True
else:
self._rawMessage = text
checkForWmo = True

View file

@ -36,8 +36,13 @@
<setHeader headerName="notifygfe">
<simple>${body?.notifyGFE}</simple>
</setHeader>
<setHeader headerName="drtstring">
<simple>${body?.drtString}</simple>
</setHeader>
<bean ref="practiceVtecDecoder" method="decode"/>
<bean ref="index" method="index"/>
<bean ref="processUtil" method="log"/>
<multicast parallelProcessing="false">
<filter>
<simple>${header?.notifygfe.booleanValue}</simple>

View file

@ -19,7 +19,13 @@
**/
package com.raytheon.uf.edex.activetable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import com.raytheon.edex.esb.Headers;
import com.raytheon.uf.common.activetable.ActiveTableMode;
@ -45,6 +51,8 @@ import com.raytheon.uf.common.time.util.TimeUtil;
* Jul 14, 2009 #2950 njensen Multiple site support
* Dec 21, 2009 #4055 njensen No site filtering
* Jun 17, 2014 3296 randerso Added performance logging
* Dec 09, 2014 3885 dgilling Handle offset time from camel route
* headers.
*
* </pre>
*
@ -80,7 +88,7 @@ public class ActiveTableSrv {
timer.start();
try {
ActiveTable activeTable = threadLocalActiveTable.get();
if (records != null && records.size() > 0) {
if ((records != null) && (records.size() > 0)) {
activeTable.merge(ActiveTableRecord.transformFromWarnings(
records, ActiveTableMode.OPERATIONAL));
}
@ -102,19 +110,12 @@ public class ActiveTableSrv {
*/
public void practiceVtecArrived(List<AbstractWarningRecord> records,
Headers headers) {
Integer offsetSeconds = null;
if (headers != null) {
offsetSeconds = (Integer) headers.get("offsetseconds");
}
if (offsetSeconds == null) {
offsetSeconds = Integer.valueOf(0);
}
if (records != null && records.size() > 0) {
int offsetSeconds = getOffsetTime((String) headers.get("drtstring"));
if ((records != null) && (records.size() > 0)) {
ActiveTable activeTable = threadLocalActiveTable.get();
try {
activeTable.merge(ActiveTableRecord.transformFromWarnings(
records, ActiveTableMode.PRACTICE), offsetSeconds
.intValue());
records, ActiveTableMode.PRACTICE), offsetSeconds);
} catch (Throwable t) {
statusHandler
.handle(Priority.PROBLEM,
@ -123,4 +124,25 @@ public class ActiveTableSrv {
}
}
}
private int getOffsetTime(String drtTimeString) {
if (drtTimeString != null) {
DateFormat drtParse = new SimpleDateFormat("yyyyMMdd_HHmm");
drtParse.setTimeZone(TimeZone.getTimeZone("GMT"));
try {
Date drtTime = drtParse.parse(drtTimeString);
Date currentTime = new Date();
long diffInMillis = drtTime.getTime() - currentTime.getTime();
return (int) TimeUnit.SECONDS.convert(diffInMillis,
TimeUnit.MILLISECONDS);
} catch (ParseException e) {
statusHandler.error("Could not parse DRT time string: "
+ drtTimeString, e);
}
}
return 0;
}
}

View file

@ -46,6 +46,8 @@ import com.raytheon.uf.edex.python.decoder.PythonDecoder;
* used for all practice VTEC products
* Changed to take in the SendPracticeProductRequest
* to simplify spring wiring
* Changed to set the filepath when calling Python decoder
* so _checkForVTEC will work
*
* </pre>
*
@ -103,7 +105,7 @@ public class PracticeVtecDecoder extends PythonDecoder {
// create an argument map to run the decoder
Map<String, Object> decoderArgs = new HashMap<String, Object>(4);
decoderArgs.put("filePath", null);
decoderArgs.put("filePath", file.getAbsolutePath());
decoderArgs.put("command", sb.toString());
return decode(decoderArgs);