Merge branch 'omaha_15.1.1' into omaha_16.1.1

Conflicts:
	edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/reference/MapManager.java


Former-commit-id: c6156764c2c4fb068f994cbb17d1f373d75f7070
This commit is contained in:
Steve Harris 2015-05-05 09:19:28 -05:00
commit 815a30871b
121 changed files with 2059 additions and 1765 deletions

View file

@ -1,14 +1,52 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.alertviz;
import java.io.File;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
/**
* Class for managing configuration context.
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 09 2015 4346 rferrel Added {@link #ALERTVIZ_DIR} and {@link #XML_EXT}.
*
* </pre>
*
* @author
* @version 1.0
*/
public class ConfigContext implements Comparable<ConfigContext> {
private static final String DEFAULT_NAME = "Default";
private static final String DEFAULT_SUBDIR = "configurations";
protected static final String ALERTVIZ_DIR = "alertViz";
protected static final String XML_EXT = ".xml";
protected static final String DEFAULT_NAME = "Default";
protected static final String DEFAULT_SUBDIR = "configurations";
private final String name;
@ -22,11 +60,11 @@ public class ConfigContext implements Comparable<ConfigContext> {
: name;
this.level = level;
String newName = name;
if (newName.endsWith(".xml") == false) {
newName += ".xml";
if (newName.endsWith(XML_EXT) == false) {
newName += XML_EXT;
}
this.localizationFileName = "alertViz" + File.separator + subDirectory
+ File.separator + newName;
this.localizationFileName = ALERTVIZ_DIR + IPathManager.SEPARATOR
+ subDirectory + IPathManager.SEPARATOR + newName;
}

View file

@ -64,6 +64,7 @@ import com.raytheon.uf.viz.alertviz.config.Source;
* Aug 28 2012 13528 Xiaochuan Using setNewConfiguration() to
* re-set configuration data and
* run notifyListeners().
* Apr 07 2015 4346 rferrel Created {@link #retrieveBaseConfiguration()}.
*
* </pre>
*
@ -75,13 +76,18 @@ public class ConfigurationManager {
.getHandler(ConfigurationManager.class, "GDN_ADMIN", "GDN_ADMIN");
public static final ConfigContext DEFAULT_BASE_CONFIG = new ConfigContext(
"Default", LocalizationLevel.BASE);
ConfigContext.DEFAULT_NAME, LocalizationLevel.BASE);
public static final ConfigContext DEFAULT_SITE_CONFIG = new ConfigContext(
"Default", LocalizationLevel.SITE);
ConfigContext.DEFAULT_NAME, LocalizationLevel.SITE);
public static final ConfigContext DEFAULT_WORKSTATION_CONFIG = new ConfigContext(
"Default", LocalizationLevel.WORKSTATION);
ConfigContext.DEFAULT_NAME, LocalizationLevel.WORKSTATION);
private static final String CONFIG_DIR = ConfigContext.ALERTVIZ_DIR
+ IPathManager.SEPARATOR + ConfigContext.DEFAULT_SUBDIR;
private static final String[] EXTENSIONS = { ConfigContext.XML_EXT };
private static ConfigurationManager instance = new ConfigurationManager();
@ -147,7 +153,7 @@ public class ConfigurationManager {
unmarshaller = null;
}
loadFromLocalization();
baseConfiguration = retrieveConfiguration(DEFAULT_BASE_CONFIG);
baseConfiguration = retrieveBaseConfiguration();
}
/**
@ -206,14 +212,14 @@ public class ConfigurationManager {
statusHandler.error("The base configuration "
+ DEFAULT_BASE_CONFIG.getLocalizationFileName()
+ " was not loaded. Check your configuration.");
}
else {
} else {
/*
* merge custom over base then overlay the current config on
* that result. preserve locking from the base configuration.
* that result. preserve locking from the base
* configuration.
*/
Configuration baseCustom = baseConfiguration.mergeUnder(custom,
true);
Configuration baseCustom = baseConfiguration.mergeUnder(
custom, true);
currentConfig = baseCustom.overlayWith(currentConfig, true);
}
}
@ -252,6 +258,7 @@ public class ConfigurationManager {
notifyListeners();
}
/**
* Delete the configuration passed in
*
@ -299,23 +306,36 @@ public class ConfigurationManager {
listeners.remove(listener);
}
/**
* Get files to display in the dialog.
*/
private void loadFromLocalization() {
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext[] contexts = pm
.getLocalSearchHierarchy(LocalizationType.CAVE_STATIC);
String[] extensions = { "xml" };
LocalizationFile[] files = pm.listFiles(contexts, "alertViz" + "/"
+ "configurations", extensions, true, true); // Win32
LocalizationFile[] files = pm.listFiles(contexts, CONFIG_DIR,
EXTENSIONS, true, true); // Win32
for (LocalizationFile file : files) {
LocalizationContext fileContext = file.getContext();
/*
* Do not display BASE xml files that get merged into the
* baseConfiguration.
*/
if ((fileContext.getLocalizationLevel() != LocalizationLevel.BASE)
|| ((fileContext.getLocalizationLevel() == LocalizationLevel.BASE) && DEFAULT_BASE_CONFIG
.getLocalizationFileName().equals(file.getName()))) {
String fileName = file.getName();
LocalizationContext locContext = file.getContext();
String name = fileName.substring(
fileName.lastIndexOf("/") + 1, // win32
fileName.lastIndexOf(IPathManager.SEPARATOR) + 1, // win32
fileName.lastIndexOf("."));
ConfigContext context = new ConfigContext(name, locContext);
configurationMap.put(context, null);
}
}
}
public LocalizationFile getCustomLocalization() {
if (customLocalization == null) {
@ -339,9 +359,42 @@ fileName.lastIndexOf("/") + 1, // win32
public Configuration retrieveConfiguration(ConfigContext configContext) {
LocalizationFile file = getLocalizationFile(configContext);
if (DEFAULT_BASE_CONFIG.equals(configContext)) {
if (baseConfiguration == null) {
baseConfiguration = retrieveBaseConfiguration();
}
return baseConfiguration;
}
return retrieveConfiguration(file);
}
/**
* Get base Default.xml and merge with any other base xml files.
*
* @return configuration
*/
private Configuration retrieveBaseConfiguration() {
LocalizationFile file = getLocalizationFile(DEFAULT_BASE_CONFIG);
Configuration configuration = retrieveConfiguration(file);
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext context = pm.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.BASE);
LocalizationFile[] files = pm.listFiles(context, CONFIG_DIR,
EXTENSIONS, false, true);
for (LocalizationFile f : files) {
// Merge other base files with the default.
if (!DEFAULT_BASE_CONFIG.getLocalizationFileName().equals(
f.getName())) {
Configuration fileConfig = retrieveConfiguration(f);
Configuration mergeConfig = configuration.mergeUnder(
fileConfig, true);
configuration = mergeConfig.overlayWith(configuration, true);
}
}
return configuration;
}
public Configuration retrieveConfiguration(LocalizationFile file) {
Configuration config = null;
if (file != null) {
@ -464,8 +517,9 @@ fileName.lastIndexOf("/") + 1, // win32
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext ctx = pm.getContext(LocalizationType.CAVE_STATIC,
LocalizationLevel.SITE);
LocalizationFile file = pm.getLocalizationFile(ctx, "alertViz"
+ File.separator + "AlertVizForced.xml");
LocalizationFile file = pm.getLocalizationFile(ctx,
ConfigContext.ALERTVIZ_DIR + IPathManager.SEPARATOR
+ "AlertVizForced.xml");
File actualFile = file.getFile();
// Win32: JHB put in check for length
if (actualFile != null && actualFile.exists()

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
This_software_was_developed_and_/_or_modified_by_Raytheon_Company,
pursuant_to_Contract_DG133W-05-CQ-1067_with_the_US_Government.
U.S._EXPORT_CONTROLLED_TECHNICAL_DATA
This_software_product_contains_export-restricted_data_whose
export/transfer/disclosure_is_restricted_by_U.S._law._Dissemination
to_non-U.S._persons_whether_in_the_United_States_or_abroad_requires
an_export_license_or_other_authorization.
Contractor_Name:________Raytheon_Company
Contractor_Address:_____6825_Pine_Street,_Suite_340
________________________Mail_Stop_B8
________________________Omaha,_NE_68106
________________________402.291.0100
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
further_licensing_information.
-->
<!--
The viirs day night band can be displayed with either channelType=DNB or channelType=NCC but the parameter is always the same.
-->
<bundle>
<displayList>
<displays xsi:type="mapRenderableDisplay" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties/>
<resourceData xsi:type="viirsResourceData">
<groupTimeRangeMinutes>${groupTimeRange;30}</groupTimeRangeMinutes>
<metadataMap>
<mapping key="channelType">
<constraint constraintValue="${channelType;DNB}" constraintType="EQUALS"/>
</mapping>
<mapping key="parameter">
<constraint constraintValue="0.7Ref" constraintType="EQUALS"/>
</mapping>
<mapping key="region">
<constraint constraintValue="${region}" constraintType="EQUALS"/>
</mapping>
<mapping key="pluginName">
<constraint constraintValue="viirs" constraintType="EQUALS"/>
</mapping>
</metadataMap>
</resourceData>
</resource>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -59,9 +59,13 @@
menuText="Moderate Band 16 (12.013u)" id="Mod12.013">
<substitute key="parameter" value="12.013BT"/>
</contribute>
<contribute xsi:type="bundleItem" file="bundles/npp/viirs/viirsImagery.xml"
<contribute xsi:type="bundleItem" file="bundles/npp/viirs/viirsDayNightBandImagery.xml"
menuText="Day/Night Band (0.7u)" id="DNB0.7">
<substitute key="parameter" value="0.7Ref"/>
<substitute key="channelType" value="DNB"/>
</contribute>
<contribute xsi:type="bundleItem" file="bundles/npp/viirs/viirsDayNightBandImagery.xml"
menuText="Near Constant Contrast (0.7u)" id="NCC0.7">
<substitute key="channelType" value="NCC"/>
</contribute>
<!-- Uncomment to include sample 'True Color' RGB Composites -->

View file

@ -299,7 +299,7 @@ class TextProduct(GenericHazards.TextProduct):
'''
if self._areaName != '':
self._areaName = ' FOR ' + self._areaName + '\n'
self._areaName = ' for ' + self._areaName + '\n'
# Fill in product dictionary information
productDict = collections.OrderedDict()

View file

@ -38,7 +38,7 @@ from java.io import File
# ------------ ---------- ----------- --------------------------
# 05/29/08 njensen Initial Creation.
# 12/10/14 #14946 ryu Add getTimeZones() function.
#
# 04/20/2015 #4027 randerso Fixes for formatter autotests
#
#
@ -95,7 +95,7 @@ def executeFromJava(databaseID, site, username, dataMgr, forecastList, logFile,
forecasts = runFormatter(databaseID=databaseID, site=site, forecastList=forecastList, testMode=testMode,
cmdLineVarDict=cmdLineVarDict, vtecMode=vtecMode, username=username,
dataMgr=dataMgr, drtTime=drtTime)
dataMgr=dataMgr, drtTime=drtTime, vtecActiveTable=vtecActiveTable)
elapsedTime = (time.time() - startTime)*1000
logger.info("Text Formatter Finished, took: %d ms",elapsedTime)
@ -223,10 +223,9 @@ def runFormatter(databaseID, site, forecastList, cmdLineVarDict, vtecMode,
argDict['creationTime'] = int(time.time()/60)*60.0
# Set the Site Time Zone
#tz = ifpClient.getSiteTimeZone(site)
#os.environ['TZ'] = tz
tz = str(ifpClient.getSiteTimeZone())
os.environ['TZ'] = tz
time.tzset()
# Create the formatter
formatter = TextFormatter.TextFormatter(dataMgr)
@ -239,6 +238,7 @@ def runFormatter(databaseID, site, forecastList, cmdLineVarDict, vtecMode,
forecasts = forecasts + forecast
logger.info("Text:\n" + str(forecasts))
try:
outputFile = argDict["outputFile"]
success = writeToFile(forecasts, outputFile, "w")
@ -426,6 +426,7 @@ def ppDef(definition):
def getVarDict(dspName, dataMgr, issuedBy, dataSource):
tz = str(dataMgr.getClient().getSiteTimeZone())
os.environ['TZ'] = tz
time.tzset()
productDef = displayNameDict[dspName][1]
productDef['database'] = dataSource
vdg = VarDictGroker.VarDictGroker(displayNameDict[dspName][0], productDef, dspName, issuedBy, dataMgr)

View file

@ -47,6 +47,7 @@ import VTECTableUtil, VTECTable
import TimeRange, AbsTime, ActiveTableVtec
import JUtil
from java.util import ArrayList
from com.raytheon.uf.common.activetable import ActiveTableMode
from com.raytheon.uf.common.dataplugin.gfe.db.objects import DatabaseID as JavaDatabaseID
from com.raytheon.uf.common.dataplugin.gfe.reference import ReferenceID
from com.raytheon.uf.common.dataplugin.gfe.discrete import DiscreteKey
@ -82,9 +83,14 @@ class HazardsTable(VTECTableUtil.VTECTableUtil):
self.filterMethod = filterMethod
self.__activeTable = None
self.__allGEOActiveTable = None #not filtered by edit areas
self.__activeTableName = activeTableName
self.__vtecMode = vtecMode
self.__etnCache = {}
if activeTableName == "PRACTICE":
self.__activeTableMode = ActiveTableMode.PRACTICE
else:
self.__activeTableMode = ActiveTableMode.OPERATIONAL
if hazardEndTime is None:
self.__hazardEndTime = None
else:
@ -192,9 +198,8 @@ class HazardsTable(VTECTableUtil.VTECTableUtil):
# make a copy and change the key if we need to
newH = copy.deepcopy(h)
newH['id'] = eaList # preserve the old list of areas
# strip segments
if (newH['phen'], newH['sig']) not in self.__ncKeys or \
self.__siteID4 == 'PGUM':
# strip segments - updated to make sure GUM TRW/A hazards keep local ETN
if ((newH['phen'], newH['sig']) not in self.__ncKeys):
if string.find(newH['phensig'], ":") >= 0:
newH['phensig'] = newH['phen'] + '.' + newH['sig']
@ -722,7 +727,7 @@ class HazardsTable(VTECTableUtil.VTECTableUtil):
# Local WFOs do not assign these numbers, so they should have
# numbers < 1000
if phensig not in self.__tpcKeys or self.__siteID4 in self.__sitesIgnoreNatlEtn:
etn_base = GFEVtecUtil.getNextEtn(self.__siteID4, '.'.join(phensig), False).getNextEtn() - 1
etn_base = GFEVtecUtil.getNextEtn(self.__siteID4, '.'.join(phensig), False, self.__activeTableMode).getNextEtn() - 1
else:
presentyear = time.gmtime(self.__time)[0]
for active in activeTable:
@ -923,13 +928,9 @@ class HazardsTable(VTECTableUtil.VTECTableUtil):
def __getActiveTable(self):
#Uses the IFPClient interface to get the VTEC active table from
#the server. Returns None on failure.
from com.raytheon.uf.common.activetable import ActiveTableMode
try:
if self.__activeTableName != "PRACTICE":
table = self.__ifpClient.getVTECActiveTable(self.__dataMgr.getSiteID())
else:
table = self.__ifpClient.getVTECActiveTable(self.__dataMgr.getSiteID(), ActiveTableMode.PRACTICE)
table = self.__ifpClient.getVTECActiveTable(self.__dataMgr.getSiteID(), self.__activeTableMode)
table = ActiveTableVtec.transformActiveTableToPython(table)
return table

View file

@ -706,15 +706,15 @@ A Winter Weather Advisory for snow means that periods of snow will cause primari
]
def ctaPilCFW(self):
return [("***RIP CURRENTS CTA", """RIP CURRENTS ARE POWERFUL CHANNELS OF WATER FLOWING QUICKLY AWAY FROM SHORE...WHICH OCCUR MOST OFTEN AT LOW SPOTS OR BREAKS IN THE SANDBAR AND IN THE VICINITY OF STRUCTURES SUCH AS GROINS...JETTIES AND PIERS. HEED THE ADVICE OF LIFEGUARDS...BEACH PATROL FLAGS AND SIGNS.
return [("***RIP CURRENTS CTA", """Rip currents are powerful channels of water flowing quickly away from shore...which occur most often at low spots or breaks in the sandbar and in the vicinity of structures such as groins...jetties and piers. Heed the advice of lifeguards...beach patrol flags and signs.
IF YOU BECOME CAUGHT IN A RIP CURRENT...YELL FOR HELP. REMAIN CALM...do not exhaust yourself and stay afloat while waiting for help. If you have to swim out of a rip current...SWIM PARALLEL TO SHORE and back toward the beach when possible. DO NOT ATTEMPT TO SWIM DIRECTLY AGAINST A RIP CURRENT as you will tire quickly."""),
If you become caught in a rip current...yell for help. Remain calm...do not exhaust yourself and stay afloat while waiting for help. If you have to swim out of a rip current...SWIM PARALLEL TO SHORE and back toward the beach when possible. Do not attempt to swim directly against a rip current as you will tire quickly."""),
("***LONGSHORE CURRENTS CTA", """Longshore currents commonly occur when waves approach the shoreline at an angle. They can be particularly dangerous near a jetty or pier."""),
("***SNEAKER WAVES CTA", """Add cta here."""),
("***RED TIDE CTA", """Add cta here"""),
("***SEA NETTLES CTA", """Add cta here"""),
("***TSUNAMI DEBRIS CTA", """Add cta here"""),
("***OTHER BEACH HAZARDS CTA", """Add cta here"""),
("***SNEAKER WAVES CTA", """Add CTA here."""),
("***RED TIDE CTA", """Add CTA here"""),
("***SEA NETTLES CTA", """Add CTA here"""),
("***TSUNAMI DEBRIS CTA", """Add CTA here"""),
("***OTHER BEACH HAZARDS CTA", """Add CTA here"""),
]
def ctaPilCWF(self):

View file

@ -145,12 +145,12 @@ class CombinedPhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRe
def useSkyPopWx_consolidation(self, tree, node):
# If set to 1, the skyPopWx phrase will consolidate weather keys that
# span all time ranges to produce:
# PARTLY CLOUDY WITH A CHANCE OF RAIN.
# SNOW IN THE MORNING...THEN SLEET IN THE AFTERNOON.
# Partly cloudy with a chance of rain.
# Snow in the morning...then sleet in the afternoon.
#
# instead of:
# PARTLY CLOUDY. CHANCE OF RAIN AND SNOW IN THE MORNING
# ...THEN A CHANCE OF RAIN AND SLEET IN THE AFTERNOON.
# Partly cloudy. Chance of rain and snow in the morning
# ...then a chance of rain and sleet in the afternoon.
return 0
def skyPopWx_excludePoP_flag(self, tree, node):
@ -256,6 +256,9 @@ class CombinedPhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRe
subkeyDict[subkey] = 1
else:
subkeyDict[subkey] += 1
if self.__dict__.get("_leDebug", 0):
print "subkeyDict", subkeyDict
# Find subkeys to disable in first phrase and second phrase,
# respectively
list1 = []
@ -266,7 +269,10 @@ class CombinedPhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRe
list2.append(subkey)
else:
list1.append(subkey)
if self.__dict__.get("_leDebug", 0): print "list1, list2", list1, list2
if self.__dict__.get("_leDebug", 0):
print "list1", list1
print "list2", list2
if len(list1) > 0 and len(list2) > 0:
newPhrase = self.splitWxPhrase(
tree, node, list1, list2,
@ -516,20 +522,20 @@ class CombinedPhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRe
# Number of sub-phrases (length) Wx Sky includeSky
#
# 1 similar similar 1
# MOSTLY SUNNY WITH A 50 PERCENT CHANCE OF RAIN.
# Mostly sunny with a 50 percent chance of rain.
#
# 2 different similar 0
# MOSTLY SUNNY. A CHANCE OF RAIN THEN A SLIGHT CHANCE OF SNOW
# IN THE AFTERNOON.
# Mostly sunny. A chance of rain then a slight chance of snow
# in the afternoon.
#
# 1 similar different 0
# MOSTLY SUNNY IN THE MORNING THEN BECOMING PARTLY CLOUDY. A
# 50 PERCENT CHANCE OF RAIN.
# Mostly sunny in the morning then becoming partly cloudy. A
# 50 percent chance of rain.
#
# 2 different different 1
# MOSTLY SUNNY WITH A CHANCE OF RAIN THEN PARTLY CLOUDY WITH
# A SLIGHT CHANCE OF SNOW IN THE AFTERNOON. A 50 PERCENT CHANCE
# OF RAIN AND SNOW.
# Mostly sunny with a chance of rain then partly cloudy with
# a slight chance of snow in the afternoon. A 50 percent chance
# of rain and snow.
#
# Compare sky for similarity in the 1st and 2nd half of the period.
# Note: We can't count on Sky having a temporal resolution of [6],

View file

@ -123,7 +123,7 @@ class ConfigVariables(TextUtils.TextUtils):
"SKY/WEATHER.........":"SKY/WEATHER.........",
" 24 HR TREND......":" 24 HR TREND......",
"unchanged":"unchanged",
"missing":"missing",
"missing":"MISSING",
"MinT":"lows",
"MaxT":"highs",
"MinT_FireWx": "MIN TEMPERATURE.....",
@ -145,23 +145,23 @@ class ConfigVariables(TextUtils.TextUtils):
"CWR.................":"CHC OF WETTING RAIN.",
"MARINE LAYER........":"MARINE LAYER........",
# Used for Headlines
"EXPECTED" : "EXPECTED",
"IN EFFECT" : "IN EFFECT",
"EXPECTED" : "expected",
"IN EFFECT" : "in effect",
# Used for single values
"around": "around",
"through the day": "through the day",
"through the night": "through the night",
# Used for Tropical
"iminHR":"HURRICANE CONDITIONS",
"iminTS":"TROPICAL STORM CONDITIONS",
"iminTSposHR":"TROPICAL STORM CONDITIONS WITH HURRICANE CONDITIONS POSSIBLE",
"posTS":"TROPICAL STORM CONDITIONS POSSIBLE",
"posTSbcmgposHR":"TROPICAL STORM CONDITIONS POSSIBLE WITH HURRICANE CONDITIONS ALSO POSSIBLE",
"expTS":"TROPICAL STORM CONDITIONS EXPECTED",
"posHR":"HURRICANE CONDITIONS POSSIBLE",
"expHR":"HURRICANE CONDITIONS EXPECTED",
"expTSposHR":"TROPICAL STORM CONDITIONS EXPECTED WITH HURRICANE CONDITIONS POSSIBLE",
"posTSorHR":"TROPICAL STORM OR HURRICANE CONDITIONS POSSIBLE" ,
"iminHR":"Hurricane conditions",
"iminTS":"Tropical storm conditions",
"iminTSposHR":"Tropical storm conditions with hurricane conditions possible",
"posTS":"Tropical storm conditions possible",
"posTSbcmgposHR":"Tropical storm conditions possible with hurricane conditions also possible",
"expTS":"Tropical storm conditions expected",
"posHR":"Hurricane conditions possible",
"expHR":"Hurricane conditions expected",
"expTSposHR":"Tropical storm conditions expected with hurricane conditions possible",
"posTSorHR":"Tropical storm or hurricane conditions possible" ,
}
def phrase_descriptor(self, tree, node, key, value):
@ -523,12 +523,12 @@ class ConfigVariables(TextUtils.TextUtils):
def highValue_threshold_dict(self, tree, node):
# If high wind conditions report both "becoming" and
# "increasing/decreasing"
# SOUTHEAST WINDS AROUND 70 MPH BECOMING SOUTH
# AND INCREASING TO AROUND 105 MPH
# Southeast winds around 70 mph becoming south
# and increasing to around 105 mph
# Otherwise, it will just be reported with "increasing"
# or "becoming":
# SOUTHEAST WINDS AROUND 20 MPH BECOMING SOUTH
# AROUND 15 MPH
# Southeast winds around 20 mph becoming south
# around 15 mph
return {
"Wind": 45, # knots or mph depending on product
"Wind20ft": 45, # knots or mph depending on product
@ -818,8 +818,8 @@ class ConfigVariables(TextUtils.TextUtils):
def embedded_vector_descriptor_flag_dict(self, tree, node):
# If set to 1, the descriptor will be embedded in the phrase:
# such as "NORTH WINDS 20 to 25 KNOTS BECOMING LIGHT AND VARIABLE"
# instead of "WINDS NORTH 20 to 25 KNOTS BECOMING LIGHT AND VARIABLE"
# such as "North winds 20 to 25 knots becoming light and variable"
# instead of "Winds north 20 to 25 knots becoming light and variable"
return {
"Wind": 1,
"Wind20ft": 1,
@ -960,9 +960,9 @@ class ConfigVariables(TextUtils.TextUtils):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.

View file

@ -27,6 +27,14 @@
#
# Author: hansen
# ----------------------------------------------------------------------------
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 04/28/2016 4027 randerso Changes for mixed case
#
##
import PhraseBuilder
import ModuleAccessor
@ -168,7 +176,6 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
if headlineWords == "": # Don't process the "<None>" key
continue
hookWords = self.hazard_hook(tree, node, key, "", "",tr.startTime(), tr.endTime())
headlineWords = self.convertToLower(headlineWords)
headlinePhrase = "..." + headlineWords + timeDescriptor +hookWords + "...\n"
words = words + headlinePhrase
@ -682,7 +689,7 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description = etext[0]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
return endPrefix + ' ' + hourStr + ' ' + hourTZstr + ' ' + \
description
@ -691,13 +698,13 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description = etext[0]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = endPrefix + ' ' + hourStr + ' ' + hourTZstr + ' '
for x in xrange(1, len(etext)):
hourStr, hourTZstr, othDescription = etext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + description
return s
@ -722,11 +729,11 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
#special cases NOON
if shourStr == "12 PM":
shourStr = "Noon"
shourStr = "noon"
#special cases NOON
if ehourStr == "12 PM":
ehourStr = "Noon"
ehourStr = "noon"
# special case EARLY THIS MORNING and THIS MORNING, replace with
# just THIS MORNING
@ -755,14 +762,14 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description = stext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + endPrefix + ' ' + ehourStr + ' ' + ehourTZstr + ' '
for x in xrange(1, len(etext)):
hourStr, hourTZstr, description = etext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + edescription
return s
@ -774,7 +781,7 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description = stext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + sdescription + ' ' + endPrefix + ' ' + ehourStr + \
' ' + ehourTZstr + ' '
@ -782,7 +789,7 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description = etext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + edescription
return s
@ -797,13 +804,13 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description0 = stext[0]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = startPrefix + ' ' + hourStr + ' ' + hourTZstr + ' '
for x in xrange(1, len(stext)):
hourStr, hourTZstr, description = stext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + description0 + ' '
@ -849,13 +856,13 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description0 = stext[0]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = startPrefix + ' ' + hourStr + ' ' + hourTZstr + ' '
for x in xrange(1, len(stext)):
hourStr, hourTZstr, description = stext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + description0 + ' '
@ -910,13 +917,13 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description0 = etext[0]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + endPrefix + ' ' + hourStr + ' ' + hourTZstr + ' '
for x in xrange(1, len(etext)):
hourStr, hourTZstr, description = etext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + description0 + ' '
@ -1244,7 +1251,7 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
(0*HR, 24*HR, "<dayOfWeek>"),] #midnght-1159pm
subsequentDay = [
(0*HR, 0*HR+1, "<dayOfWeek-1> Night"), #midnght
(0*HR, 0*HR+1, "<dayOfWeek-1> night"), #midnght
(0*HR, 24*HR, "<dayOfWeek>"),] #midnght-1159pm
@ -1303,11 +1310,11 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
#special cases NOON
if hourStr == "12 PM" and description == "today":
hourStr = "Noon"
hourStr = "noon"
#special cases MIDNIGHT
if hourStr == "12 AM":
hourStr = "Midnight"
hourStr = "midnight"
os.environ["TZ"] = myTimeZone # reset the defined time zone
@ -1602,7 +1609,6 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
#assemble the hazard type
hazStr = hazard['hdln']
hazStr = self.convertToLower(hazStr)
# if the hazard is a convective watch, tack on the etn
phenSig = hazard['phen'] + "." + hazard['sig']
@ -2061,16 +2067,16 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
# test mode
if argDict.get('testMode', 0):
phrase = 'TEST ' + name #test mode, prepend "TEST"
phrase = 'Test ' + name #test mode, prepend "TEST"
else:
phrase = name
# want A or AN?
if addA:
if phrase[0] in ['A','E','I','O','U','a','e','i','o','u']:
phrase = "AN " + phrase
phrase = "an " + phrase
else:
phrase = "A " + phrase
phrase = "a " + phrase
return phrase

View file

@ -150,8 +150,8 @@ Definition["outputFile"] = "{prddir}/TEXT/FWS.txt"
# Definitions to insert unrepresentativeness of the forecast
# instructions for the user.
Definition["insertUnrepresentStatement"] = 1 # Use 1 for yes, 0 for no
Definition["unrepresentStatement"] = "IF CONDITIONS BECOME UNREPRESENTATIVE..." + \
"CONTACT THE NATIONAL WEATHER\nSERVICE."
Definition["unrepresentStatement"] = "If conditions become unrepresentative..." + \
"contact the National Weather\nService."
# Definitions to insert the FWF discussion from a separate file.
# Discussion is edited separately in XNOW for the FWF forecast.
# Advantage of this is to have a first guess for the discussion in
@ -188,8 +188,8 @@ Definition["stqPil"] = "STQ<site>" # STQ pil
# Definitions to insert unrepresentativeness of the forecast
# instructions for the user.
#Definition["insertUnrepresentStatement"] = 0 # Use 1 for yes, 0 for no
#Definition["unrepresentStatement"] = "IF CONDITIONS BECOME UNREPRESENTATIVE..." + \
# "CONTACT THE NATIONAL WEATHER\nSERVICE."
#Definition["unrepresentStatement"] = "If conditions become unrepresentative..." + \
# "contact the National Weather\nService."
# wind20ftHeader: This definition set to "1" allows offices to
# format winds in this format...
@ -1848,7 +1848,7 @@ class FWS_Overrides:
# Code to ensure the wildfireElementList parameters are included in
# the FWS product (if this is a wildfire incident) was added to this
# method.
if self._fireType == "WILDFIRE":
if self._fireType.upper() == "WILDFIRE":
for element in self._wildfireElementList:
for elementList in elementLists:
if element not in elementList and len(elementList) != 0:
@ -2008,7 +2008,7 @@ class FWS_Overrides:
self._fireTime + ' ' + self._fireDate + ' ' + rtz,
'%H%M %m/%d/%y %Z')
fcst = fcst + time.strftime(
'FORECAST IS BASED ON ' + requestWords + ' TIME OF %H%M %Z ON %B %d. ',
'Forecast is based on ' + requestWords + ' time of %H%M %Z on %B %d. ',
self._fireDateTime)
else:
offset = 0
@ -2063,7 +2063,7 @@ class FWS_Overrides:
fireDateTime = time.strptime(
self._fireTime + ' ' + self._fireDate, '%H%M %m/%d/%y')
fcst = fcst + time.strftime(
'FORECAST IS BASED ON ' + requestWords + ' TIME OF %H%M ' + rtz + ' ON %B %d. ',
'Forecast is based on ' + requestWords + ' time of %H%M ' + rtz + ' on %B %d. ',
fireDateTime)
fcst = fcst + "\n"
self._makeFireTimeRange()
@ -2085,18 +2085,18 @@ class FWS_Overrides:
# This is a new method that Matt Davis wrote. Figures out whether or not
# we are using a ignition time, request time, or incident time.
def _getRequestWords(self):
if self._fireType == "WILDFIRE":
return "REQUEST"
elif self._fireType == "PRESCRIBED":
return "IGNITION"
if self._fireType.upper() == "WILDFIRE":
return "request"
elif self._fireType.upper() == "PRESCRIBED":
return "ignition"
else:
return "INCIDENT"
return "incident"
# Import the discussion from a previously edited discussion file.
def _makeDiscussion(self, fcst, argDict):
discussionHeader = ""
discussionHeader = ".DISCUSSION...\n"
discussionHeader = ".Discussion...\n"
if self._insertDiscussionFromFile == 1:
discussion = ""
@ -2109,7 +2109,7 @@ class FWS_Overrides:
discussion = string.join(string.split(discussion,"\n\n"),"\n")
return fcst + discussionHeader + discussion + "\n"
else:
discussion = "...PUT DISCUSSION TEXT HERE..."
discussion = "...Put discussion text here..."
return fcst + discussionHeader + discussion + "\n\n"
elif self._insertDiscussionFromFile == 2:
version = 0
@ -2121,7 +2121,7 @@ class FWS_Overrides:
disFlag = 0
foundDiscussion = 0
for line in product:
if string.find(line,"DISCUSSION...") != -1:
if string.find(line,"Discussion...") != -1:
disFlag = 1
foundDiscussion = 1
try:
@ -2138,7 +2138,7 @@ class FWS_Overrides:
if foundDiscussion:
return fcst + discussion + "\n\n"
else:
discussion = "...PUT DISCUSSION TEXT HERE..."
discussion = "...Put discussion text here..."
return fcst + discussionHeader + discussion + "\n\n"
else:
return fcst + discussionHeader + "\n\n\n"
@ -2290,7 +2290,7 @@ class FWS_Overrides:
if "Include Day 8-14 Outlook?" not in self._extendedQuestions:
return fcst
outlookHeader = ".OUTLOOK FOR " + self._outlookDay8Label + " THROUGH " \
outlookHeader = ".Outlook for " + self._outlookDay8Label + " through " \
+ self._outlookDay14Label + "...\n"
outlookHeader = string.upper(outlookHeader)
@ -2305,7 +2305,7 @@ class FWS_Overrides:
outlook = string.join(string.split(outlook,"\n\n"),"\n")
return fcst + outlookHeader + outlook + "\n"
else:
outlook = "...PUT 8 TO 14 DAY OUTLOOK TEXT HERE..."
outlook = "...Put 8 to 14 day outlook text here..."
return fcst + outlookHeader + outlook + "\n\n"
elif self._insertDiscussionFromFile == 2:
version = 0
@ -2327,7 +2327,7 @@ class FWS_Overrides:
if foundOutlook:
return fcst + outlookHeader + outlook + "\n\n"
else:
outlook = "...PUT 8 TO 14 DAY OUTLOOK TEXT HERE..."
outlook = "...Put 8 to 14 day outlook text here..."
return fcst + outlookHeader + outlook + "\n\n"
else:
return fcst + outlookHeader + "\n\n\n"
@ -2341,17 +2341,18 @@ class FWS_Overrides:
newFireName = self._fireName + "..." + self._otherAgencyName
else:
newFireName = self._fireName + "..." + self._requestingAgency
productLabel = self._productName + " FOR " + newFireName
productLabel = self._productName + " for " + newFireName
productLabel = self.checkTestMode(argDict, productLabel)
issuedByString = self.getIssuedByString()
# Product header
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" + productLabel + \
"\nNATIONAL WEATHER SERVICE " + self._wfoCityState + \
"\nNational Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# Add time disclaimer
self._fireTR = None
@ -2378,9 +2379,9 @@ in the future. *|''' % self._timeLabel
tagLineString = ""
else:
tagLineString = ".TAG " + self._webSiteTag + "/" + self._wfoID + "\n"
fcst = fcst + "$$\nFORECASTER..." + forecasterString + "\n" + \
"REQUESTED BY..." + self._agencyContact + "\n" + \
"TYPE OF REQUEST..." + self._fireType + "\n" + tagLineString
fcst = fcst + "$$\nForecaster..." + forecasterString + "\n" + \
"Requested by..." + self._agencyContact + "\n" + \
"Type of request..." + self._fireType + "\n" + tagLineString
#self.storeAWIPS(fcst, self._awipsProductID)
self.setProgressPercentage(100)
self.progressMessage(0, 100, self._displayName + " Complete")
@ -2516,39 +2517,39 @@ in the future. *|''' % self._timeLabel
pass
return [
("Next Day", 24 + self.DAY(), 24 + self.NIGHT(), 24 + self.NIGHT(),
".TODAY...", "early in the morning", "late in the afternoon",
".Today...", "early in the morning", "late in the afternoon",
1, narrativeDef),
("Morning", self.DAY(), self.NIGHT(), self.NIGHT(),
".TODAY...", "early in the morning", "late in the afternoon",
".Today...", "early in the morning", "late in the afternoon",
1, narrativeDef),
("Morning Update", "issuanceHour", self.NIGHT(), self.NIGHT(),
".REST OF TODAY...", "early in the morning", "late in the afternoon",
".Rest of Today...", "early in the morning", "late in the afternoon",
1, narrativeDef),
("Afternoon Update", "issuanceHour", self.NIGHT(), self.NIGHT(),
".REST OF TODAY...", "early in the morning","late in the afternoon",
".Rest of Today...", "early in the morning","late in the afternoon",
1, narrativeDef),
# End times are tomorrow:
("Afternoon", self.NIGHT(), 24 + self.DAY(), 24 + self.DAY(),
".TONIGHT...", "late in the night", "early in the evening",
".Tonight...", "late in the night", "early in the evening",
1, narrativeDef),
("Afternoon with 4 periods", self.NIGHT(), 24 + self.DAY(), 24 + self.DAY(),
".TONIGHT...", "late in the night", "early in the evening",
".Tonight...", "late in the night", "early in the evening",
1, narrativeDef),
("Evening Update", "issuanceHour", 24 + self.DAY(), 24 + self.DAY(),
".REST OF TONIGHT...", "late in the night","early in the evening",
".Rest of Tonight...", "late in the night","early in the evening",
1, narrativeDef),
("Evening Update with 4 periods", "issuanceHour", 24 + self.DAY(), 24 + self.DAY(),
".REST OF TONIGHT...", "late in the night","early in the evening",
".Rest of Tonight...", "late in the night","early in the evening",
1, narrativeDef),
# For the early morning update, this produces:
# REST OF TONIGHT:
# MONDAY
# MONDAY NIGHT
# Rest of Tonight:
# Monday
# Monday Night
("Early Morning Update", "issuanceHour", self.DAY(), self.DAY(),
".REST OF TONIGHT...", "early in the morning","late in the afternoon",
".Rest of Tonight...", "early in the morning","late in the afternoon",
0, narrativeDef),
("Early Morning Update with 4 periods", "issuanceHour", self.DAY(), self.DAY(),
".REST OF TONIGHT...", "early in the morning","late in the afternoon",
".Rest of Tonight...", "early in the morning","late in the afternoon",
0, narrativeDef),
]
@ -2961,11 +2962,11 @@ in the future. *|''' % self._timeLabel
if self._withIgnitionTimes == "yes":
dayNight = self.getPeriod(node.getTimeRange(), 1)
if dayNight == self.DAYTIME():
tempElement = "MAX"
rhElement = "MIN"
tempElement = "Max"
rhElement = "Min"
else:
tempElement = "MIN"
rhElement = "MAX"
tempElement = "Min"
rhElement = "Max"
if elementName == "MaxT" or elementName == "MinT":
ignitionElement = "T"
elementType = tempElement
@ -2978,7 +2979,7 @@ in the future. *|''' % self._timeLabel
if ignitionStats is not None:
ignitionPhrase = `int(self.getValue(ignitionStats))`
reqType = self._getRequestWords()
words = ignitionPhrase + units + " AT " + reqType + "..." + elementType + " " + igWords
words = ignitionPhrase + units + " at " + reqType + "..." + elementType + " " + igWords
else:
words = elementType + " " + igWords
else:
@ -3019,7 +3020,7 @@ in the future. *|''' % self._timeLabel
igMagStr = `int(ignitionWindStats[0])`
igDirStr = self.vector_dir(int(ignitionWindStats[1]))
reqType = self._getRequestWords()
igWords = "WINDS " + igDirStr + " AT " + igMagStr + " MPH AT " + reqType + "...OTHERWISE "
igWords = "Winds " + igDirStr + " at " + igMagStr + " mph at " + reqType + "...otherwise "
words = igWords + words
node.set("descriptor", "")
@ -3127,11 +3128,11 @@ in the future. *|''' % self._timeLabel
dayNight = self.getPeriod(node.getTimeRange(), 1)
if dayNight == self.DAYTIME():
vr = int(maxVal)
ventType = "MAX"
ventType = "Max"
mergeMethod = "Max"
else:
vr = int(minVal)
ventType = "MIN"
ventType = "Min"
mergeMethod = "Min"
vrCat = self.smokeDispersal_valueStr(vr)
words = ventType + "..." + vrCat + " " + " /" + `vr` + " knot-ft/"
@ -3139,7 +3140,7 @@ in the future. *|''' % self._timeLabel
ignitionDispersal = tree.stats.get(
"VentRate", self._fireTR, node.getAreaLabel(), mergeMethod=mergeMethod)
vrCat = self.smokeDispersal_valueStr(ignitionDispersal)
igWords = vrCat + " /" + `int(ignitionDispersal)` + " KNOT-FT/ AT " + reqType + ". \n"
igWords = vrCat + " /" + `int(ignitionDispersal)` + " knot-ft/ at " + reqType + ". \n"
words = igWords + " " + words
else:
# Handle phrase with range if not including ignition time
@ -3193,17 +3194,17 @@ in the future. *|''' % self._timeLabel
# Single Value input
if mix1 == mix2:
words = `mix1` + " " + outUnits + " agl"
words = `mix1` + " " + outUnits + " AGL"
# Range
else:
words = `mix1`+ "-" + `mix2` + " " + outUnits + " agl"
words = `mix1`+ "-" + `mix2` + " " + outUnits + " AGL"
# Handle ignition time
if self._checkFireTR(node.getTimeRange()):
reqType = self._getRequestWords()
ignitionMixStats = tree.stats.get(
"MixHgt", self._fireTR, node.getAreaLabel(), mergeMethod="Max")
igWords = `int(ignitionMixStats)` + " " + outUnits + " agl at " + reqType +"...otherwise "
igWords = `int(ignitionMixStats)` + " " + outUnits + " AGL at " + reqType +"...otherwise "
words = igWords + words
return self.setWords(node, words)
@ -3250,7 +3251,7 @@ in the future. *|''' % self._timeLabel
reqType = self._getRequestWords()
hainesDict = self.hainesDict()
words = ignitionPhrase + " " + hainesDict[int(ignitionPhrase)] + \
" AT " + reqType + "...MAX " + `haines1`
" at " + reqType + "...max " + `haines1`
ignitionFlag = 1
if not ignitionFlag:
haines1, haines2 = self.getValue(stats, "MinMax")
@ -3409,23 +3410,23 @@ in the future. *|''' % self._timeLabel
if height is None:
return self.setWords(node.parent, "MISSING")
if dir >= 22.5 and dir < 67.5:
dirWords = "NORTHEAST"
dirWords = "northeast"
elif dir >= 67.5 and dir < 112.5:
dirWords = "EAST"
dirWords = "east"
elif dir >= 112.5 and dir < 157.5:
dirWords = "SOUTHEAST"
dirWords = "southeast"
elif dir >= 157.5 and dir < 202.5:
dirWords = "SOUTH"
dirWords = "south"
elif dir >= 202.5 and dir < 247.5:
dirWords = "SOUTHWEST"
dirWords = "southwest"
elif dir >= 247.5 and dir < 292.5:
dirWords = "WEST"
dirWords = "west"
elif dir >= 292.5 and dir < 337.5:
dirWords = "NORTHWEST"
dirWords = "northwest"
else:
dirWords = "NORTH"
dirWords = "north"
heightWords = `int(height + 0.5)`
words = dirWords + " SWELL " + heightWords + " FEET"
words = dirWords + " swell " + heightWords + " feet"
return self.setWords(node, words)
def ceiling_phrase(self):

View file

@ -597,7 +597,7 @@ class FirePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRelate
### Humidity
def humidityRecovery_percentage(self, tree, node):
# If the maximum humidity is greater than this percentage,
# humidity recovery will be EXCELLENT.
# humidity recovery will be Excellent.
return 50
def humidityRecovery_phrase(self):
@ -634,7 +634,7 @@ class FirePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRelate
return self.setWords(node.parent, "MISSING")
maxRH = self.getValue(curStats, "Max")
if maxRH > self.humidityRecovery_percentage(tree, node):
return self.setWords(node, "EXCELLENT")
return self.setWords(node, "Excellent")
timeRange = node.getTimeRange()
prevTimeRange = self.adjustTimeRange(timeRange, -24)
prevStats = tree.stats.get(elementName, prevTimeRange, node.getAreaLabel(),
@ -660,15 +660,15 @@ class FirePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRelate
# editAreaNames = ["area1", "area2"]
# if self.currentAreaContains(tree, editAreaNames):
# return [
# (15, "POOR"),
# (20, "FAIR"),
# (30, "GOOD"),
# (15, "Poor"),
# (20, "Fair"),
# (30, "Good"),
# ]
return [
(25, "POOR"),
(55, "MODERATE"),
(70, "GOOD"),
(100,"EXCELLENT"),
(25, "Poor"),
(55, "Moderate"),
(70, "Good"),
(100,"Excellent"),
]
### LAL
@ -865,10 +865,10 @@ class FirePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRelate
# Single Value input
if mix1 == mix2:
words = `mix1` + " " + outUnits + " agl"
words = `mix1` + " " + outUnits + " AGL"
# Range
else:
words = `mix1`+ "-" + `mix2` + " " + outUnits + " agl"
words = `mix1`+ "-" + `mix2` + " " + outUnits + " AGL"
return self.setWords(node, words)
###---------------------------------------------------------

View file

@ -536,7 +536,7 @@ class Header(EditAreaUtils.EditAreaUtils, StringUtils.StringUtils):
lineLength=66, areaDictName="AreaDictionary", addPeriod = False,
forceAlphaSort=False):
# Returns a list of cities (from the AreaDictionary)
# Appends an " AND " instead of "..." for the last city mentioned.
# Appends an " and " instead of "..." for the last city mentioned.
# Access the UGC information for the area(s) if available
areaDict = ModuleAccessor.ModuleAccessor().variable(areaDictName, "AreaDictionary")
@ -557,7 +557,7 @@ class Header(EditAreaUtils.EditAreaUtils, StringUtils.StringUtils):
for c in cities:
cityString = cityString + "..." + c
cityString = self.replaceLast(cityString, "...", " AND ")
cityString = self.replaceLast(cityString, "...", " and ")
if len(cityString) == 0:
return ""
else:
@ -687,7 +687,7 @@ class Header(EditAreaUtils.EditAreaUtils, StringUtils.StringUtils):
first = 0
else:
result = result + "..." + county
result = self.replaceLast(result, "...", " AND ")
result = self.replaceLast(result, "...", " and ")
return result
def replaceLast(self, str, str1, str2):

View file

@ -403,6 +403,7 @@ class MarinePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRela
#print "\n in swell words"
periodFlag = node.getAncestor("periodFlag")
statDict = node.getStatDict()
#Check for Swell alone
swell2 = self.getStats(statDict, "Swell2")
if swell2 is None:
@ -526,28 +527,28 @@ class MarinePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRela
fcst = re.sub(r'(?i)(\W)SOUTHEAST(\W)', r'\1SE\2',fcst)
fcst = re.sub(r'(?i)(\W)SOUTHWEST(\W)', r'\1SW\2',fcst)
fcst = re.sub(r'(?i)(\W)NORTHWEST(\W)', r'\1NW\2',fcst)
fcst = re.sub(r'(?i)(\W)KNOTS?(\W)', r'\1KT\2',fcst)
fcst = re.sub(r'(?i)(\W)KNOTS?(\W)', r'\1kt\2',fcst)
## fcst = re.sub(r'(?i)(\W)FOOT(\W)', r'\1FT\2',fcst)
fcst = re.sub(r'(?i)(\W)FEET(\W)', r'\1FT\2',fcst)
fcst = re.sub(r'(?i)(\W)FEET(\W)', r'\1ft\2',fcst)
fcst = re.sub(r'(?i)(\W)POSITION(\W)', r'\1PSN\2',fcst)
fcst = re.sub(r'(?i)(\W)VISIBILITY(\W)', r'\1VSBY\2',fcst)
fcst = re.sub(r'(?i)(\W)THUNDERSTORM', r'\1TSTM',fcst)
fcst = re.sub(r'(?i)(\W)AVERAGE(\W)', r'\1AVG\2',fcst)
fcst = re.sub(r'(?i)(\W)NAUTICAL MILES?(\W)', r'\1NM\2',fcst)
fcst = re.sub(r'(?i)(\W)NAUTICAL MILES?(\W)', r'\1nm\2',fcst)
fcst = re.sub(r'(?i)(\W)ATLANTIC(\W)', r'\1ATLC\2',fcst)
fcst = re.sub(r'(?i)(\W)FATHOMS?(\W)', r'\1FM\2',fcst)
fcst = re.sub(r'(?i)(\W)FATHOMS?(\W)', r'\1fm\2',fcst)
fcst = re.sub(r'(?i)(\W)LONGITUDE(\W)', r'\1LONG\2',fcst)
fcst = re.sub(r'(?i)(\W)PACIFIC(\W)', r'\1PAC\2',fcst)
fcst = re.sub(r'(?i)(\W)DEGREES?(\W)', r'\1DEG\2',fcst)
fcst = re.sub(r'(?i)(\W)MILLIBARS?(\W)', r'\1MB\2',fcst)
fcst = re.sub(r'(?i)(\W)DEGREES?(\W)', r'\1deg\2',fcst)
fcst = re.sub(r'(?i)(\W)MILLIBARS?(\W)', r'\1mb\2',fcst)
fcst = re.sub(r'(?i)(\W)PRESSURE(\W)', r'\1PRES\2',fcst)
fcst = re.sub(r'(?i)(\W)SUNDAY(\W)', r'\1SUN\2',fcst)
fcst = re.sub(r'(?i)(\W)MONDAY(\W)', r'\1MON\2',fcst)
fcst = re.sub(r'(?i)(\W)TUESDAY(\W)', r'\1TUE\2',fcst)
fcst = re.sub(r'(?i)(\W)WEDNESDAY(\W)', r'\1WED\2',fcst)
fcst = re.sub(r'(?i)(\W)THURSDAY(\W)', r'\1THU\2',fcst)
fcst = re.sub(r'(?i)(\W)FRIDAY(\W)', r'\1FRI\2',fcst)
fcst = re.sub(r'(?i)(\W)SATURDAY(\W)', r'\1SAT\2',fcst)
fcst = re.sub(r'(?i)(\W)SUNDAY(\W)', r'\1Sun\2',fcst)
fcst = re.sub(r'(?i)(\W)MONDAY(\W)', r'\1Mon\2',fcst)
fcst = re.sub(r'(?i)(\W)TUESDAY(\W)', r'\1Tue\2',fcst)
fcst = re.sub(r'(?i)(\W)WEDNESDAY(\W)', r'\1Wed\2',fcst)
fcst = re.sub(r'(?i)(\W)THURSDAY(\W)', r'\1Thu\2',fcst)
fcst = re.sub(r'(?i)(\W)FRIDAY(\W)', r'\1Fri\2',fcst)
fcst = re.sub(r'(?i)(\W)SATURDAY(\W)', r'\1Sat\2',fcst)
fcst = re.sub(r'^ ', r'',fcst)
return fcst

View file

@ -32,6 +32,7 @@
# 12/28/2012 DR 15596 J.Zeng Added checkWeatherSimilarity
# for two lists based on Virgil's
# suggestion
# 04/20/2015 4027 randerso Changes for mixed case product generation.
# ----------------------------------------------------------------------------
import types
@ -3571,6 +3572,7 @@ class PhraseBuilder(ConfigVariables.ConfigVariables,
# Initialize so that we are ready to use the thenConnector
# if appropriate
phrase.set("useThenConnector", 1)
useThenConnector = phrase.get("useThenConnector")
prevEnd = prev.getTimeRange().endTime()
# If the start time of this subPhrase is the same
@ -3585,6 +3587,8 @@ class PhraseBuilder(ConfigVariables.ConfigVariables,
# Can re-set connector so we are ready to use the
# then connector on the next subPhrase
phrase.set("useThenConnector", 1)
subPhrase.set("words", subPhrase.get("words").capitalize())
return connector
def visConnector(self, tree, subPhrase):
@ -3677,8 +3681,8 @@ class PhraseBuilder(ConfigVariables.ConfigVariables,
else:
# If high wind conditions report both "becoming" and
# "increasing/decreasing"
# SOUTHEAST WINDS AROUND 70 MPH BECOMING SOUTH
# AND INCREASING TO AROUND 105 MPH
# Southeast winds around 70 mph becoming south
# and increasing to around 105 mph
increasing = mag1 < mag2
if max(mag1, mag2) > self.highValue_threshold(
tree, subPhrase, elementName, elementName):

View file

@ -697,12 +697,12 @@ class TextProduct(AreaFcst.TextProduct):
def useSkyPopWx_consolidation(self, tree, node):
# If set to 1, the skyPopWx phrase will consolidate weather keys that
# span all time ranges to produce:
# PARTLY CLOUDY WITH A CHANCE OF RAIN.
# SNOW IN THE MORNING...THEN SLEET IN THE AFTERNOON.
# Partly cloudy with a chance of rain.
# Snow in the morning...then sleet in the afternoon.
#
# instead of:
# PARTLY CLOUDY. CHANCE OF RAIN AND SNOW IN THE MORNING
# ...THEN A CHANCE OF RAIN AND SLEET IN THE AFTERNOON.
# Partly cloudy. Chance of rain and snow in the morning
# ...then a chance of rain and sleet in the afternoon.
#return 1
return 0

View file

@ -338,7 +338,7 @@ class SAF_Overrides:
# Clean up the area label to avoid possibly
# repeat "forecast for"
e=re.compile('.*forecast for',re.IGNORECASE)
intro = "again, the forecast for " + \
intro = "Again, the forecast for " + \
e.sub("",areaLabel).strip()
# Now strip off any punctuation on the area label
# and add the period label, ie, today, tonight
@ -391,7 +391,7 @@ class SAF_Overrides:
return finalFcst
def setLabel(self, tree, component):
exLabel= "\n\nand now the extended forecast for the radio listening area.\n"
exLabel= "\n\nAnd now the extended forecast for the radio listening area.\n"
component.set("words", exLabel)
return self.DONE()
@ -745,7 +745,7 @@ class SAF_Overrides:
# dz 031010 - from Brian Walawender
# Code below sets the start time for the afternoon update
# Local Noon or the current hour (whichever is greater)
# Local noon or the current hour (whichever is greater)
currentTime = time.time()
updateHour = self.DAY() + 6

View file

@ -312,7 +312,7 @@ class ScalarPhrases(PhraseBuilder.PhraseBuilder):
# Used IF the areal_sky_flag is 1.
# Weather types that are related to sky cover and will be included in the
# sky phrase if their areal coverage matches the sky areal coverage.
# For example: AREAS OF LOW CLOUDS AND FOG IN THE MORNING...THEN MOSTLY SUNNY.
# For example: areas of low clouds and fog in the morning...then mostly sunny.
return ["F", "L"]
def disableSkyRelatedWx(self, tree, node):
@ -955,7 +955,7 @@ class ScalarPhrases(PhraseBuilder.PhraseBuilder):
elif digitMin >= upperMin and digitMax <= lowerMax and maxVal - minVal <= 10:
roundedMax = int(self.round(maxVal, "Nearest", 10))
return self.constructTempException("near %max", minVal, roundedMax)
# return 50s AND 60s (not LOWER 50s TO UPPER 60s)
# return 50s and 60s (not lower 50s to upper 60s)
elif digitMin <= lowerMax and digitMax >= upperMin:
return "in the " + decadeMinStr + " to " + decadeMaxStr
digitMinPhrase = digitMinStr + " " + decadeMinStr

View file

@ -25,13 +25,13 @@
# SRF_850, SRF_853, SRF_856
#
# surfAreas:
# NorthCoast1 (listed with FLZ039), SouthCoast (along GMZ850)
# NorthCoast2 (listed with FLZ042), SouthCoast (along GMZ850)
# NorthCoast1 (listed with FLZ139), SouthCoast (along GMZ850)
# NorthCoast2 (listed with FLZ142), SouthCoast (along GMZ850)
#
# TBW always runs with the same combinations:
# FLZ039-FLZ042-FLZ048-FLZ049
# FLZ050-FLZ051-FLZ055-FLZ060
# FLZ062-FLZ065
# FLZ139-FLZ142-FLZ148-FLZ149
# FLZ050-FLZ151-FLZ155-FLZ160
# FLZ162-FLZ165
# Thus, additional entries need only be listed for at least one zone
# in each combination.
#
@ -39,50 +39,59 @@
# for each zone and the system will take care to combine them appropriately.
# For example, note that the "surfAreas" are listed for both FLZ039 and FLZ042.
# When they are combined, the surfAreas are reported just once, as desired.
# ----------------------------------------------------------------------------
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 04/28/2016 4027 randerso Changes for mixed case
#
##
AreaDictionary = {
'FLZ039': {'fullStateName': 'Florida',
'FLZ139': {'fullStateName': 'Florida',
'partOfState': 'northern',
'stateAbbr': 'FL',
'ugcCityString': '...Cedar Key...Hudson Beach...McKethan Pine Island Park',
'ugcCode': 'FLZ039',
'ugcCode': 'FLZ139',
'ugcName': 'Levy',
'ugcTimeZone': 'EST5EDT',
'landSeaArea': 'SRF_850',
'marineArea': 'GMZ850',
'surfAreas': [
('NorthCoast1', 'Surf along north facing reefs.............'),
('SouthCoast', 'Surf along south facing reefs.............')
('NorthCoast1', 'SURF ALONG NORTH FACING REEFS.............'),
('SouthCoast', 'SURF ALONG SOUTH FACING REEFS.............')
],
'uviCity': "Tampa", # City for which UVI should be listed
'tideTables': ["Cedar Key", "Venice Inlet"],
},
'FLZ042': {'fullStateName': 'Florida',
'FLZ142': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '',
'ugcCode': 'FLZ042',
'ugcCode': 'FLZ142',
'ugcName': 'Citrus',
'ugcTimeZone': 'EST5EDT',
'surfAreas': [
('NorthCoast2', 'Surf along north facing reefs.............'),
('SouthCoast', 'Surf along south facing reefs.............')
('NorthCoast2', 'SURF ALONG NORTH FACING REEFS.............'),
('SouthCoast', 'SURF ALONG SOUTH FACING REEFS.............')
],
},
'FLZ048': {'fullStateName': 'Florida',
'FLZ148': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '',
'ugcCode': 'FLZ048',
'ugcCode': 'FLZ148',
'ugcName': 'Hernando',
'ugcTimeZone': 'EST5EDT'},
'FLZ049': {'fullStateName': 'Florida',
'FLZ149': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': "",
'ugcCode': 'FLZ049',
'ugcCode': 'FLZ149',
'ugcName': 'Pasco',
'ugcTimeZone': 'EST5EDT'},
@ -91,7 +100,7 @@ AreaDictionary = {
'FLZ050': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '...Bradenton Beach...Clearwater Beach...Siesta Key...Saint pete Beach...Venice Beach',
'ugcCityString': '...Bradenton Beach...Clearwater Beach...Siesta Key...Saint Pete Beach...Venice Beach',
'ugcCode': 'FLZ050',
'ugcName': 'Pinellas',
'ugcTimeZone': 'EST5EDT',
@ -101,35 +110,35 @@ AreaDictionary = {
'uviCity': "Tampa",
'tideTables': ["Saint Petersburg", "Fort Myers"],
},
'FLZ051': {'fullStateName': 'Florida',
'FLZ151': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '',
'ugcCode': 'FLZ051',
'ugcCode': 'FLZ151',
'ugcName': 'Hillsborough',
'ugcTimeZone': 'EST5EDT'},
'FLZ055': {'fullStateName': 'Florida',
'FLZ155': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '',
'ugcCode': 'FLZ055',
'ugcCode': 'FLZ155',
'ugcName': 'Manatee',
'ugcTimeZone': 'EST5EDT'},
'FLZ060': {'fullStateName': 'Florida',
'FLZ160': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '',
'ugcCode': 'FLZ060',
'ugcCode': 'FLZ160',
'ugcName': 'Sarasota',
'ugcTimeZone': 'EST5EDT'},
###################
'FLZ062': {'fullStateName': 'Florida',
'FLZ162': {'fullStateName': 'Florida',
'partOfState': 'Southwest',
'stateAbbr': 'FL',
'ugcCityString': '...Boca Grande...Englewood',
'ugcCode': 'FLZ062',
'ugcCode': 'FLZ162',
'ugcName': 'Charlotte',
'ugcTimeZone': 'EST5EDT',
'landSeaArea': 'SRF_856',
@ -138,11 +147,11 @@ AreaDictionary = {
'uviCity': "Tampa",
'tideTables': ["Venice Inlet"],
},
'FLZ065': {'fullStateName': 'Florida',
'FLZ165': {'fullStateName': 'Florida',
'partOfState': 'Southwest',
'stateAbbr': 'FL',
'ugcCityString': '...Fort Myers Beach...Sanibel Island',
'ugcCode': 'FLZ065',
'ugcCode': 'FLZ165',
'ugcName': 'Lee',
'ugcTimeZone': 'EST5EDT',
},

View file

@ -702,8 +702,10 @@ class TextUtils:
if newTimeZone is None:
newTimeZone = myTimeZone
os.environ["TZ"] = newTimeZone # set the new time zone
time.tzset()
timeZoneStr = time.strftime(format, time.localtime(gmTime))
os.environ["TZ"] = myTimeZone # set the time zone back
time.tzset()
return timeZoneStr # return the time as a string
# Adopted from ER 8/04

View file

@ -92,7 +92,7 @@ class TimeDescriptor(TimeRangeUtils.TimeRangeUtils, Interfaces.Interfaces):
# timeRanges 24 hours long so that getWeekday_descriptor
# will honor the splitDay24HourLabel setting and leave
# weekdays as simply the weekday name e.g.
# SATURDAY instead of SATURDAY AND SATURDAY NIGHT
# Saturday instead of Saturday and Saturday night
if splitDay24HourLabel:
# Make 12-hour start and end timeRanges
durHours1 = 12
@ -132,12 +132,12 @@ class TimeDescriptor(TimeRangeUtils.TimeRangeUtils, Interfaces.Interfaces):
# holidayModule: file containing holiday dates
# nextDay24HourLabel: if 1, a 24-hour time period starting
# after 1600, will be labeled as the next day.
# This is to accomodate 24 extended periods that go from
# This is to accommdate 24 extended periods that go from
# 6pm-6pm.
# splitDay24HourLabel: if 0, a 24-hour period will be labeled with
# simply the weekday name (e.g. SATURDAY)
# simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
#
# If the time range is for today AND is less than 12 hours,
# we must accurately describe the period.
@ -296,14 +296,14 @@ class TimeDescriptor(TimeRangeUtils.TimeRangeUtils, Interfaces.Interfaces):
4 : "Friday",
5 : "Saturday"
},
"Now": "Now",
"Today":"Today",
"Tonight": "Tonight",
"Rest of Today":"Rest of Today",
"Rest of Tonight": "Rest of Tonight",
"Night": "Night",
"Evening": "Evening",
"Afternoon": "This Afternoon",
"Now": "now",
"Today":"today",
"Tonight": "tonight",
"Rest of Today":"rest of today",
"Rest of Tonight": "rest of tonight",
"Night": "night",
"Evening": "evening",
"Afternoon": "this afternoon",
},
"Worded": {
"PrePunctuation": "",
@ -380,14 +380,14 @@ class TimeDescriptor(TimeRangeUtils.TimeRangeUtils, Interfaces.Interfaces):
4 : "Fri",
5 : "Sat"
},
"Now": "Now",
"Today":"Today",
"Tonight": "Tonight",
"Rest of Today":"Rest of Today",
"Rest of Tonight": "Rest of Tonight",
"Night": "Night",
"Evening": "Evening",
"Afternoon": "This Afternoon",
"Now": "now",
"Today":"today",
"Tonight": "tonight",
"Rest of Today":"rest of today",
"Rest of Tonight": "rest of tonight",
"Night": "night",
"Evening": "evening",
"Afternoon": "this afternoon",
},
"CapsAbbreviated": {
"PrePunctuation": "",

View file

@ -443,7 +443,7 @@ Expression = [
('Saturday',"Samedi","Sabado"),
('Sunday',"Dimanche","Domingo"),
("Tonight", "Ce soir", "Esta noche"),
('Today', "Aujourd'Hui", "HOY"),
('Today', "Aujourd'Hui", "Hoy"),
('Night', "Soir", "Noche"),
('Monday',"Lundi","Lunes"),
('Tuesday',"Mardi", "Martes"),
@ -479,7 +479,7 @@ Expression = [
('FreeWind(mph)','VentLibre(mph)','VientoLibre(mph)'),
('Haines','Haines','Haines'),
('TransWind(mph)','VentTrans(mph)','VientoTrans(mph)'),
('MixHgt(ft agl)','ElevMelang(ft agl)','AltuMezcl(ft agl)'),
('MixHgt(ft AGL)','ElevMelang(ft AGL)','AltuMezcl(ft AGL)'),
('City','Ville', 'Ciudad'),
('County','Comte', 'Condado'),
('Nowcast','Previsions Courantes','Pronostico Sobre Tiempo'),
@ -669,7 +669,7 @@ if __name__ == '__main__':
"High winds in the afternoon. Partly cloudy. Very heavy rain showers likely. Snow accumulation of 1 inch. Lows in the mid 30s. East winds at 75 mph. Probability of precipitation 65 percent.",
"Mostly sunny. Widespread heavy volcanic ash. Snow accumulation of 1 to 20 inches. Highs around 120. Probability of precipitation 99 percent.",
"High winds. Partly cloudy. Slight chance of very heavy rain showers. Snow accumulation of 1 inch. Lows in the mid 30s. East winds at 75 mph. Probability of precipitation 1 percent. Southwest winds up to 15 mph.",
"SKY/WEATHER...Mostly cloudy with scattered rain showers and thunderstorms\nLAL...........3-4\nTEMPERATURE...Lows in the mid 30s\nHUMIDITY......70 pct\nWIND - 20 FT..Northwest to Southeast in the evening\n VALLEYS...\n RIDGES....\nHAINES INDEX..4 low\nSMOKE DISPERSAL:\n MIXING HEIGHT...Decreasing to 500-1,000 ft agl\n TRANSPORT WIND..Northeast to southeast 3-8 mph",
"SKY/WEATHER...Mostly cloudy with scattered rain showers and thunderstorms\nLAL...........3-4\nTEMPERATURE...Lows in the mid 30s\nHUMIDITY......70 pct\nWIND - 20 FT..Northwest to Southeast in the evening\n VALLEYS...\n RIDGES....\nHAINES INDEX..4 low\nSMOKE DISPERSAL:\n MIXING HEIGHT...Decreasing to 500-1,000 ft AGL\n TRANSPORT WIND..Northeast to southeast 3-8 mph",
"High winds. Decreasing cloudiness. Widely scattered light sleet. Snow accumulation of 1 to 50 inches. Low 0. Northwest winds at 90 to 100 mph becoming southwest at 80 to 90 mph. Probability of precipitation 110 percent." ]
for forecast in forecastList:

View file

@ -31,17 +31,33 @@ from com.raytheon.uf.common.dataplugin.gfe.weather import WeatherSubKey as JavaW
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 09/09/08 njensen Initial Creation.
#
#
# 04/20/2015 4027 randerso Added __eq__ and __hash__ so WeatherSubKey works
# correctly when used as key in a dict.
# Changed several methods which were static methods in Java
#
class WeatherSubKey:
def __init__(self, javaSubKey):
self.__key = javaSubKey
def __repr__(self):
return str(self.__key.toString())
def __str__(self):
return str(self.__key.toString())
def __eq__(self, other):
try:
return self.__key.equals(other.__key)
except:
return False
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return self.__key.hashCode()
def wxType(self):
return self.__key.getType()
@ -55,30 +71,30 @@ class WeatherSubKey:
return self.__key.getVisibility()
def attributes(self):
return JUtil.javaStringListToPylist(self.__key.getAttributes())
return JUtil.javaObjToPyVal(self.__key.getAttributes())
def wxDef(self):
return WxDefinition.WxDefinition(self.__key.wxDef())
def availableCoverages(self, dataMgr, wxType):
def availableCoverages(dataMgr, wxType):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableCoverages(siteId, wxType))
return JUtil.javaObjToPyVal(JavaWeatherSubKey.availableCoverages(siteId, wxType))
def availableAttributes(self, dataMgr, wxType):
def availableAttributes(dataMgr, wxType):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableAttributes(siteId, wxType))
return JUtil.javaObjToPyVal(JavaWeatherSubKey.availableAttributes(siteId, wxType))
def availableIntensities(self, dataMgr, wxType):
def availableIntensities(dataMgr, wxType):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableIntensities(siteId, wxType))
return JUtil.javaObjToPyVal(JavaWeatherSubKey.availableIntensities(siteId, wxType))
def availableVisibilities(self, dataMgr):
def availableVisibilities(dataMgr):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableVisibilities(siteId))
return JUtil.javaObjToPyVal(JavaWeatherSubKey.availableVisibilities(siteId))
def availableWxTypes(self, dataMgr):
def availableWxTypes(dataMgr):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableWxTypes(siteId))
return JUtil.javaObjToPyVal(JavaWeatherSubKey.availableWxTypes(siteId))
def weatherSubKey(dataMgr, coverage, wxType, intensity, vis, attrList):
siteId = dataMgr.getSiteID()

View file

@ -1045,15 +1045,15 @@ class WxPhrases(PhraseBuilder.PhraseBuilder):
# If the number of sub-phrases is greater than this limit, the weather
# phrase will use 6-hour instead of the higher resolution to produce:
#
# OCCASIONAL SNOW POSSIBLY MIXED WITH SLEET AND FREEZING
# DRIZZLE IN THE MORNING...THEN A CHANCE OF RAIN POSSIBLY MIXED WITH SNOW
# AND SLEET AND FREEZING DRIZZLE IN THE AFTERNOON.
# Occasional snow possibly mixed with sleet and freezing
# drizzle in the morning...then a chance of rain possibly mixed wiht snow
# and sleet and freezing drizzle in the afternoon.
#
# instead of:
# OCCASIONAL SNOW IN THE MORNING. CHANCE OF LIGHT SLEET AND
# SLIGHT CHANCE OF LIGHT FREEZING DRIZZLE IN THE LATE MORNING AND
# EARLY AFTERNOON. CHANCE OF SNOW EARLY IN THE AFTERNOON. CHANCE OF
# RAIN IN THE AFTERNOON.
# Occasional snow in the morning. Chance of light sleet and
# slight chance of light freezing drizzle in the late morning and
# early afternoon. Chance of snow early in the afternoon. Chance of
# rain in the afternoon.
return 3

View file

@ -24,7 +24,7 @@
# Edit Areas: solicited from user
# Weather Elements: You must have these Weather elements defined in
# your server: Sky, LAL, RelHum, MaxT, MinT, FreeWind,
# Haines, TransWind, MixHgt(ft agl)
# Haines, TransWind, MixHgt(ft AGL)
# To Run:
# Set GFE Time Range
# Products-->Generate Products
@ -36,7 +36,7 @@
## Fire Period Table for Feb 29 00 17:00:00 GMT - Mar 01 00 11:00:00 GMT.
## Edit Area Sky (%) LAL RelHum (%) MaxT MinT FreeWind(mph) Haines TransWind(mph) MixHgt(ft agl)
## Edit Area Sky (%) LAL RelHum (%) MaxT MinT FreeWind(mph) Haines TransWind(mph) MixHgt(ft AGL)
## COAdams 36-23 46 26
## COArapahoe 34-24 46 26
@ -102,7 +102,7 @@ Definition = {
"vectorRange",
"range2Value",
"Vector", 1, "ktToMph"),
("MixHgt", "MixHgt(ft agl)",
("MixHgt", "MixHgt(ft AGL)",
"minMax",
"range2Value",
"Scalar",10,None),

View file

@ -297,7 +297,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
if digit > 3 or digit <= 9:
RH1 = ten + 5
RH2 = RH1 + 10
words = `RH1` + " TO " + `RH2` + " PERCENT"
words = `RH1` + " to " + `RH2` + " percent"
return self.setWords(node, words)
def _windChill_heatIndex_compoundPhrase(self):
@ -316,7 +316,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
if words is None:
return
if words == "":
words = "NOT A FACTOR"
words = "not a factor"
node.set("descriptor", "")
statsWC = tree.stats.get("WindChill", node.getTimeRange(),
node.getAreaLabel(), mergeMethod="Min")
@ -364,11 +364,11 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
maxWind, dir = self.getValue(stats, "Max", self.VECTOR())
chopphrase = ""
if maxWind >= 26.1:
chopphrase = "HEAVY CHOP EXPECTED ON AREA RIVERS AND LAKES"
chopphrase = "Heavy chop expected on area rivers and lakes"
elif maxWind >= 21.7:
chopphrase = "MODERATE CHOP EXPECTED ON AREA RIVERS AND LAKES"
chopphrase = "Moderate chop expected on area rivers and lakes"
elif maxWind >= 17.4:
chopphrase = "LIGHT CHOP EXPECTED ON AREA RIVERS AND LAKES"
chopphrase = "Light chop expected on area rivers and lakes"
if chopphrase != "":
words = words + ". " + chopphrase
return self.setWords(node, words)
@ -408,10 +408,10 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
QPFwords = "\n"
words = WXwords
elif (QPFrange0 == "0.0"):
QPFwords = "AMOUNTS UP TO " + QPFrange1 + " OF AN INCH"
QPFwords = "Amounts up to " + QPFrange1 + " of an inch"
words = WXwords + ". " + QPFwords
else:
QPFwords = "AMOUNTS BETWEEN " + QPFrange0 + " AND " + QPFrange1 + " OF AN INCH"
QPFwords = "Amounts between " + QPFrange0 + " and " + QPFrange1 + " of an inch"
words = WXwords + ". " + QPFwords
return self.setWords(node, words)
@ -441,15 +441,15 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
if wxType == "T":
cov = subkey.coverage()
if cov in ["Num", "Wide", "Ocnl", "Brf", "Frq", "Pds", "Inter", "Lkly", "Def"]:
words = "LIKELY"
elif cov in ["Sct", "Chc"] and words not in ["LIKELY"]:
words = "SCATTERED"
elif cov in ["Iso", "SChc"] and words not in ["LIKELY", "SCATTERED"]:
words = "ISOLATED"
elif words not in ["LIKELY", "SCATTERED", "ISOLATED"]:
words = "POSSIBLE"
elif words not in ["LIKELY", "SCATTERED", "ISOLATED", "POSSIBLE"]:
words = "NONE"
words = "likely"
elif cov in ["Sct", "Chc"] and words not in ["likely"]:
words = "scattered"
elif cov in ["Iso", "SChc"] and words not in ["likely", "scattered"]:
words = "isolated"
elif words not in ["likely", "scattered", "isolated"]:
words = "possible"
elif words not in ["likely", "scattered", "isolated", "possible"]:
words = "none"
#print words
return self.setWords(node, words)

View file

@ -98,8 +98,8 @@ public class GfeClient extends AbstractAWIPSComponent {
}
}
if (gfeClientArgStartIndex == -1
|| gfeClientArgStartIndex == args.length) {
if ((gfeClientArgStartIndex == -1)
|| (gfeClientArgStartIndex == args.length)) {
System.err.println("No python script specified to run - exiting");
return;
}
@ -130,7 +130,6 @@ public class GfeClient extends AbstractAWIPSComponent {
GfeCavePyIncludeUtil.getAutotestIncludePath(),
GfeCavePyIncludeUtil.getTextUtilitiesIncludePath(includeUser),
GfeCavePyIncludeUtil.getTextProductsIncludePath(includeUser),
GfeCavePyIncludeUtil.getTextProductsTemplatesIncludePath(),
GfeCavePyIncludeUtil.getCombinationsIncludePath(includeUser),
GfeCavePyIncludeUtil.getTestsIncludePath(),
GfeCavePyIncludeUtil.getProceduresIncludePath(includeUser));

View file

@ -103,6 +103,7 @@ import com.raytheon.viz.gfe.textformatter.TextProductManager;
* 05/22/2014 3110 randerso Attach router to edex.alerts.gfe earlier
* 09/09/2014 3592 randerso Added call to SampleSetManager.dispose()
* 10/30/2014 3775 randerso Added parmCacheInit to initStatus
* 04/20/2015 4027 randerso Let TextProductManager know we are not running in a GUI
*
* </pre>
*
@ -213,6 +214,8 @@ public class DataManager {
*
* @param factory
* @param discriminator
* used as key for this instance of DataManager in the factory's
* instance map. Normally this is the window GFE is running in.
* @throws GFEServerException
*/
DataManager(DataManagerFactory factory, Object discriminator)
@ -236,7 +239,7 @@ public class DataManager {
strInitJob.setSystem(true);
strInitJob.schedule();
initializeScriptControllers();
initializeScriptControllers(discriminator);
procJobPool = new ProcedureJobPool(4, 4, this);
toolJobPool = new SmartToolJobPool(3, 3, this);
@ -510,7 +513,7 @@ public class DataManager {
this.gridManager = gridManager;
}
private void initializeScriptControllers() {
private void initializeScriptControllers(final Object discriminator) {
// it would be really nice to be able to spawn the construction of these
// two heavy objects into another thread. Unfortunately, Jep requires
// creation and all subsequent access to happen on the same thread. So
@ -539,7 +542,8 @@ public class DataManager {
"Error initializing smart tool interface", e);
}
DataManager.this.textProductMgr = new TextProductManager();
DataManager.this.textProductMgr = new TextProductManager(
discriminator != null);
}
});
}

View file

@ -690,7 +690,7 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements
TabItem newTab = new TabItem(tabFolder, SWT.NONE);
newTab.setText(tabName);
setTabImage(newTab, ConfigData.productStateEnum.New);
setTabImage(newTab, ConfigData.ProductStateEnum.New);
newTab.setImage(newTabImg);
ProductAreaComp comp = new ProductAreaComp(tabFolder, this,
@ -874,7 +874,7 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements
* Name of the tab.
*/
@Override
public void setTabState(ConfigData.productStateEnum state, String tabName) {
public void setTabState(ConfigData.ProductStateEnum state, String tabName) {
TabItem[] items = tabFolder.getItems();
for (int i = 0; i < items.length; i++) {
@ -893,18 +893,18 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements
* @param state
* Product state.
*/
private void setTabImage(TabItem ti, ConfigData.productStateEnum state) {
if (state == ConfigData.productStateEnum.New) {
private void setTabImage(TabItem ti, ConfigData.ProductStateEnum state) {
if (state == ConfigData.ProductStateEnum.New) {
ti.setImage(newTabImg);
} else if (state == ConfigData.productStateEnum.Queued) {
} else if (state == ConfigData.ProductStateEnum.Queued) {
ti.setImage(queuedImg);
} else if (state == ConfigData.productStateEnum.Running) {
} else if (state == ConfigData.ProductStateEnum.Running) {
ti.setImage(runningImg);
} else if (state == ConfigData.productStateEnum.Finished) {
} else if (state == ConfigData.ProductStateEnum.Finished) {
ti.setImage(finishedImg);
} else if (state == ConfigData.productStateEnum.Transmitted) {
} else if (state == ConfigData.ProductStateEnum.Transmitted) {
ti.setImage(transmittedImg);
} else if (state == ConfigData.productStateEnum.Failed) {
} else if (state == ConfigData.ProductStateEnum.Failed) {
ti.setImage(failedImg);
}
}

View file

@ -27,6 +27,7 @@ package com.raytheon.viz.gfe.dialogs.formatterlauncher;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 18 APR 2008 ### lvenable Initial creation
* 20 APR 2015 4027 randerso Added a flag to the enum's to indicate which are final states
*
* </pre>
*
@ -46,8 +47,19 @@ public final class ConfigData {
* @author lvenable
*
*/
public enum productStateEnum {
New, Queued, Running, Finished, Transmitted, Failed;
public enum ProductStateEnum {
New(false), Queued(false), Running(false), Finished(true), Transmitted(
true), Failed(true);
private boolean complete;
private ProductStateEnum(boolean complete) {
this.complete = complete;
}
public boolean isComplete() {
return complete;
}
}
/**

View file

@ -27,6 +27,7 @@ package com.raytheon.viz.gfe.dialogs.formatterlauncher;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 18 APR 2008 ### lvenable Initial creation
* 20 APR 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -50,7 +51,7 @@ public interface IProductTab {
* Product state.
* @param productName
*/
void setTabState(ConfigData.productStateEnum state, String productName);
void setTabState(ConfigData.ProductStateEnum state, String productName);
/**
* Update the status from the component.

View file

@ -29,6 +29,7 @@ package com.raytheon.viz.gfe.dialogs.formatterlauncher;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 22, 2010 #2861 lvenable Initial creation
* Apr 20, 2015 #4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -36,5 +37,5 @@ package com.raytheon.viz.gfe.dialogs.formatterlauncher;
* @version 1.0
*/
public interface ITransmissionState {
void setTransmissionState(ConfigData.productStateEnum state);
void setTransmissionState(ConfigData.ProductStateEnum state);
}

View file

@ -38,7 +38,7 @@ import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID;
import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.dialogs.FormatterLauncherDialog;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.productStateEnum;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.ProductStateEnum;
import com.raytheon.viz.gfe.tasks.AbstractGfeTask;
import com.raytheon.viz.gfe.tasks.TaskManager;
import com.raytheon.viz.gfe.textformatter.FormatterUtil;
@ -67,6 +67,7 @@ import com.raytheon.viz.gfe.textformatter.TextProductManager;
* 05 FEB 2014 2591 randerso Added dataManager to ZoneCombinerComp constructor
* Passed dataMgr instance to FormatterUtil.runFormatterScript
* 12 FEB 2014 2801 randerso Added prompting if formatter is run against non-normal database
* 20 APR 2015 4027 randerso Fixes for GFE formatter auto tests to support mixed case WA
*
* </pre>
*
@ -380,6 +381,15 @@ public class ProductAreaComp extends Composite implements
if (formattingCbo.isVisible()) {
vtecMode = formattingCbo.getText();
} else {
// TODO: part of fix for SS RM DR #14813
// String pil = (String) textProductMgr
// .getDefinitionValue(productName, "pil");
// if (pil != null) {
// pil = pil.substring(0, 3);
// vtecMode = textProductMgr
// .getVtecMessageType(pil);
// }
int hazIndex = productName.indexOf("Hazard_");
if (hazIndex > -1) {
String category = productName.substring(
@ -640,14 +650,13 @@ public class ProductAreaComp extends Composite implements
}
@Override
public void textProductQueued() {
productTabCB.setTabState(ConfigData.productStateEnum.Queued,
productName);
public void textProductQueued(ConfigData.ProductStateEnum state) {
productTabCB.setTabState(state, productName);
}
@Override
public void textProductFinished(String productText,
ConfigData.productStateEnum state) {
ConfigData.ProductStateEnum state) {
if (isTabClosed == true) {
return;
@ -657,7 +666,7 @@ public class ProductAreaComp extends Composite implements
runFormatterBtn.setEnabled(true);
// closeTabBtn.setEnabled(true);
outputLogBtn.setEnabled(true);
if (state == ConfigData.productStateEnum.Finished) {
if (state == ConfigData.ProductStateEnum.Finished) {
if (productText != null) {
productEditorComp.retrieveActiveVTEC();
productEditorComp.setProductText(productText);
@ -668,14 +677,14 @@ public class ProductAreaComp extends Composite implements
productEditorBtn.setSelection(true);
productEditorBtnSelected();
} else if (state == ConfigData.productStateEnum.Failed) {
} else if (state == ConfigData.ProductStateEnum.Failed) {
outputLogBtn.setSelection(true);
outputLogBtnSelected();
}
}
@Override
public void startProgressBar(ConfigData.productStateEnum state) {
public void startProgressBar(ConfigData.ProductStateEnum state) {
if (isTabClosed == true) {
return;
}
@ -685,7 +694,7 @@ public class ProductAreaComp extends Composite implements
}
@Override
public void stopProgressBar(ConfigData.productStateEnum state) {
public void stopProgressBar(ConfigData.ProductStateEnum state) {
if (isTabClosed == true) {
return;
}
@ -695,7 +704,7 @@ public class ProductAreaComp extends Composite implements
}
@Override
public void setTransmissionState(productStateEnum state) {
public void setTransmissionState(ProductStateEnum state) {
productTabCB.setTabState(state, productName);
}

View file

@ -115,7 +115,7 @@ import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.GFEPreference;
import com.raytheon.viz.gfe.constants.StatusConstants;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.productStateEnum;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.ProductStateEnum;
import com.raytheon.viz.gfe.product.ProductFileUtil;
import com.raytheon.viz.gfe.product.TextDBUtil;
import com.raytheon.viz.ui.dialogs.ICloseCallback;
@ -165,6 +165,8 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
* for the local time zones for each segment.
* 01/28/2015 #4018 randerso Code cleanup.
* 02/04/2014 17039 ryu Removed menu item related to the HighlighFramingCodes feature.
* 04/20/2015 4027 randerso Renamed ProductStateEnum with an initial capital
* Expunged Calendar from ActiveTableRecord
* </pre>
*
* @author lvenable
@ -1387,7 +1389,7 @@ public class ProductEditorComp extends Composite implements
// check if the segment is still valid
int started = 0;
for (ActiveTableRecord atr : activeRecs) {
if (atr.getStartTime().getTimeInMillis() <= transmissionTime
if (atr.getStartTime().getTime() <= transmissionTime
.getTime()) {
started++;
}
@ -1419,7 +1421,7 @@ public class ProductEditorComp extends Composite implements
for (ActiveTableRecord r : activeRecs) {
// need to change the action to CON if
// the end time did not change
if (r.getEndTime().getTimeInMillis() == vtecEnd
if (r.getEndTime().getTime() == vtecEnd
.getTime()) {
if (!newActions.contains("CON")) {
newActions.add("CON");
@ -1499,7 +1501,7 @@ public class ProductEditorComp extends Composite implements
// Check start and ending time for end later than start
if ((vtecStart != null) && (vtecEnd != null)
&& (vtecStart.getTime() >= vtecEnd.getTime())) {
setTabColorFunc(productStateEnum.New);
setTabColorFunc(ProductStateEnum.New);
String msg = "VTEC ending time is before "
+ "starting time. Product is invalid and must"
+ " be regenerated.";
@ -1516,7 +1518,7 @@ public class ProductEditorComp extends Composite implements
if ((vtecEnd != null)
&& (vtecEnd.getTime() <= transmissionTime.getTime())) {
setTabColorFunc(productStateEnum.New);
setTabColorFunc(ProductStateEnum.New);
String msg = "VTEC ends before current time."
+ " Product is invalid and must be regenerated.";
throw new VizException(msg);
@ -2426,7 +2428,7 @@ public class ProductEditorComp extends Composite implements
clearProductText();
setProductText(draft.getProductText());
setTabColorFunc(productStateEnum.Finished);
setTabColorFunc(ProductStateEnum.Finished);
setStatusText('R', productId + " draft loaded.");
if (productDefinition.get("brain") != null) {
@ -2437,7 +2439,7 @@ public class ProductEditorComp extends Composite implements
+ "after the draft was originally saved.\nThis causes VTEC to "
+ "be suspect. You must re-run the formatter.";
setStatusText('U', msg);
setTabColorFunc(productStateEnum.New);
setTabColorFunc(ProductStateEnum.New);
} else {
revive();
retrieveActiveVTEC();
@ -2827,13 +2829,13 @@ public class ProductEditorComp extends Composite implements
setStatusText('U', msg1);
// set tab back to gray
setTabColorFunc(productStateEnum.New);
setTabColorFunc(ProductStateEnum.New);
// special *ALL* case
} else if (allFound) {
brain();
// set tab back to gray
setTabColorFunc(productStateEnum.New);
setTabColorFunc(ProductStateEnum.New);
}
}
@ -2900,7 +2902,7 @@ public class ProductEditorComp extends Composite implements
/**
* @param string
*/
private void setTabColorFunc(productStateEnum state) {
private void setTabColorFunc(ProductStateEnum state) {
transmissionCB.setTransmissionState(state);
}

View file

@ -88,6 +88,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* Nov 14, 2014 4953 randerso Cleaned up practice product requests
* Feb 26, 2015 4126 randerso Ensure transmit/store is properly cancelled if dialog is closed
* Code cleanup
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -441,7 +442,7 @@ public class StoreTransmitDlg extends CaveSWTDialog {
} catch (VizException e) {
statusHandler.handle(Priority.CRITICAL,
"Error preparing product for transmission.", e);
sendTransmissionStatus(ConfigData.productStateEnum.Failed);
sendTransmissionStatus(ConfigData.ProductStateEnum.Failed);
StoreTransmitDlg.this.parentEditor.revive();
}
}
@ -578,14 +579,14 @@ public class StoreTransmitDlg extends CaveSWTDialog {
Priority p = null;
if (!resp.hasFailure()) {
p = Priority.EVENTA;
sendTransmissionStatus(ConfigData.productStateEnum.Transmitted);
sendTransmissionStatus(ConfigData.ProductStateEnum.Transmitted);
} else {
// determine the failure type and priority
ConfigData.productStateEnum state = null;
ConfigData.ProductStateEnum state = null;
if (resp.isSendLocalSuccess()) {
state = ConfigData.productStateEnum.Transmitted;
state = ConfigData.ProductStateEnum.Transmitted;
} else {
state = ConfigData.productStateEnum.Failed;
state = ConfigData.ProductStateEnum.Failed;
}
p = Priority.EVENTA;
if (!resp.isAttempted()) {
@ -619,14 +620,14 @@ public class StoreTransmitDlg extends CaveSWTDialog {
this.parentEditor.brain();
} catch (VizException e) {
statusHandler.handle(Priority.CRITICAL, "Error sending product", e);
sendTransmissionStatus(ConfigData.productStateEnum.Failed);
sendTransmissionStatus(ConfigData.ProductStateEnum.Failed);
this.parentEditor.revive();
}
SEQ_NUMBER++;
}
private void sendTransmissionStatus(ConfigData.productStateEnum status) {
private void sendTransmissionStatus(ConfigData.ProductStateEnum status) {
if (!isStoreDialog) {
transmissionCB.setTransmissionState(status);
}

View file

@ -20,11 +20,11 @@
package com.raytheon.viz.gfe.smarttool;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import com.raytheon.uf.common.dataplugin.gfe.python.GfePyIncludeUtil;
import com.raytheon.uf.common.localization.IPathManager;
@ -33,6 +33,7 @@ import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.localization.exception.LocalizationException;
import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException;
import com.raytheon.uf.common.python.PythonFileFilter;
import com.raytheon.viz.gfe.GFEOperationFailedException;
@ -46,6 +47,7 @@ import com.raytheon.viz.gfe.GFEOperationFailedException;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 28, 2009 njensen Initial creation
* Apr 20, 2015 4027 randerso Changes to support GFE formatter auto tests
*
* </pre>
*
@ -87,6 +89,14 @@ public class TextFileUtil {
return file;
}
public static LocalizationFile getUserTextFile(LocalizationFile source) {
LocalizationContext ctx = PATH_MGR.getContext(source.getContext()
.getLocalizationType(), LocalizationLevel.USER);
LocalizationFile destLf = getTextFile(ctx, source.getName());
return destLf;
}
private static String getPathFromType(String filename, String fileType) {
String name = null;
if (fileType.equalsIgnoreCase("TextUtility")) {
@ -102,7 +112,8 @@ public class TextFileUtil {
name = "gfe" + File.separator + "editAreaGroups" + File.separator
+ filename + ".txt";
} else if (fileType.equalsIgnoreCase("Reference")) {
name = "editAreas" + File.separator + filename + ".xml";
name = "gfe" + File.separator + "editAreas" + File.separator
+ filename + ".xml";
}
return name;
}
@ -115,49 +126,50 @@ public class TextFileUtil {
public static void makeWritableCopy(String source, String fileType,
String dest, boolean deleteFlag) throws IOException,
GFEOperationFailedException {
LocalizationFile lf = getTextFile(source, fileType);
if (lf.getContext().getLocalizationLevel() == LocalizationLevel.BASE
|| lf.getContext().getLocalizationLevel() == LocalizationLevel.SITE) {
File srcFile = lf.getFile();
LocalizationFile srcLf = getTextFile(source, fileType);
if ((srcLf.getContext().getLocalizationLevel() == LocalizationLevel.BASE)
|| (srcLf.getContext().getLocalizationLevel() == LocalizationLevel.CONFIGURED)
|| (srcLf.getContext().getLocalizationLevel() == LocalizationLevel.SITE)) {
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationContext ctx = pathMgr.getContext(lf.getContext()
LocalizationContext ctx = pathMgr.getContext(srcLf.getContext()
.getLocalizationType(), LocalizationLevel.USER);
LocalizationFile destLf = getTextFile(ctx,
getPathFromType(dest, fileType));
File destFile = destLf.getFile();
copy(srcFile, destFile);
try {
copy(srcLf, destLf);
destLf.save();
} catch (Exception e) {
throw new GFEOperationFailedException(
"Unable to save localization file", e);
}
} else if (lf.getContext().getLocalizationLevel() == LocalizationLevel.USER) {
} else if (srcLf.getContext().getLocalizationLevel() == LocalizationLevel.USER) {
if (deleteFlag) {
try {
lf.delete();
srcLf.delete();
} catch (Exception e) {
throw new GFEOperationFailedException(
"Unable to delete localization file "
+ lf.toString(), e);
+ srcLf.toString(), e);
}
} else {
System.out.println("USER version already exists " + source);
}
} else {
throw new GFEOperationFailedException(
"No file found at base or site level for " + source + " "
+ fileType);
"No file found at base, configured or site level for "
+ source + " " + fileType);
}
}
private static void copy(File src, File dest) throws IOException {
File dir = new File(dest.getParent());
dir.mkdir();
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
private static void copy(LocalizationFile srcLf, LocalizationFile destLf)
throws IOException, LocalizationException {
File dir = destLf.getFile(false).getParentFile();
Files.createDirectories(dir.toPath());
try (InputStream in = srcLf.openInputStream();
OutputStream out = destLf.openOutputStream()) {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
@ -165,13 +177,24 @@ public class TextFileUtil {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
public static void deleteTextFile(LocalizationFile lf)
throws LocalizationOpFailedException {
throws LocalizationOpFailedException, IOException {
if (lf.getContext().getLocalizationLevel()
.equals(LocalizationLevel.USER)
&& lf.getContext().getContextName().equals("GFETEST")) {
lf.delete();
String path = lf.getFile().getAbsolutePath();
if (path.endsWith(".py")) {
path = path + "o";
Files.deleteIfExists(Paths.get(path));
}
} else {
throw new IllegalArgumentException(
"Can only delete USER level files owned by GFETEST: " + lf);
}
}
}

View file

@ -30,6 +30,7 @@ import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.gfe.python.GfeCavePyIncludeUtil;
/**
* Builds text formatter script objects
@ -38,7 +39,9 @@ import com.raytheon.uf.viz.core.exception.VizException;
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 2, 2008 njensen Initial creation
* Jun 02, 2008 njensen Initial creation
* Apr 20, 2015 4027 randerso Remove unused TextProductsTemplates path and added
* Tests path for GFE formatter auto tests
*
* </pre>
*
@ -67,9 +70,9 @@ public class FormatterScriptFactory {
GfePyIncludeUtil.getHeadlineIncludePath(),
GfePyIncludeUtil.getTextUtilitiesIncludePath(),
GfePyIncludeUtil.getTextProductsIncludePath(),
GfePyIncludeUtil.getTextProductsTemplatesIncludePath(),
GfePyIncludeUtil.getUtilitiesIncludePath(),
GfePyIncludeUtil.getCombinationsIncludePath());
GfePyIncludeUtil.getCombinationsIncludePath(),
GfeCavePyIncludeUtil.getTestsIncludePath());
return new FormatterScript(runnerPath, include,
FormatterScript.class.getClassLoader());

View file

@ -22,6 +22,7 @@ package com.raytheon.viz.gfe.textformatter;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import com.raytheon.uf.common.activetable.ActiveTableMode;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.time.SimulatedTime;
@ -43,6 +44,8 @@ import com.raytheon.viz.gfe.tasks.TaskManager;
* Sep 05, 2013 2329 randerso Removed save of combinations file
* Feb 12, 2014 2591 randerso Passed dataMgr instance to FormatterUtil.runFormatterScript
* Removed call to TextProductManager.reloadModule
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
* Fixed hard coded active table mode in runFormatterScript
*
* </pre>
*
@ -79,8 +82,12 @@ public class FormatterUtil {
String vtecMode, TextProductFinishListener finish) {
int testMode = 0;
if (dataMgr.getOpMode().equals(CAVEMode.TEST)) {
ActiveTableMode atMode = ActiveTableMode.OPERATIONAL;
CAVEMode caveMode = dataMgr.getOpMode();
if (caveMode.equals(CAVEMode.TEST)) {
testMode = 1;
} else if (caveMode.equals(CAVEMode.PRACTICE)) {
atMode = ActiveTableMode.PRACTICE;
}
String shortVtec = null;
@ -103,7 +110,6 @@ public class FormatterUtil {
String varDict = productMgr.getVarDict(productName, dataMgr, dbId);
if (varDict != null) {
// run the formatter with the normal active table
String time = null;
if (!SimulatedTime.getSystemTime().isRealTime()) {
SimpleDateFormat gmtFormatter = new SimpleDateFormat(
@ -113,11 +119,11 @@ public class FormatterUtil {
time = gmtFormatter.format(SimulatedTime.getSystemTime()
.getTime());
}
runFormatterScript(name, shortVtec, dbId, varDict, "Operational",
runFormatterScript(name, shortVtec, dbId, varDict, atMode.name(),
time, testMode, finish);
} else {
finish.textProductFinished("Formatter canceled",
ConfigData.productStateEnum.Finished);
ConfigData.ProductStateEnum.Finished);
}
}
@ -128,7 +134,7 @@ public class FormatterUtil {
varDict, vtecActiveTable, drtTime, testMode, finish);
// Thread thread = new Thread(formatter);
// thread.start();
finish.textProductQueued();
finish.textProductQueued(ConfigData.ProductStateEnum.Queued);
TaskManager.getInstance().queueFormatter(formatter);
}

View file

@ -35,7 +35,7 @@ import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.productStateEnum;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.ProductStateEnum;
import com.raytheon.viz.gfe.sampler.SamplerGridSliceCache;
import com.raytheon.viz.gfe.tasks.AbstractGfeTask;
@ -53,6 +53,7 @@ import com.raytheon.viz.gfe.tasks.AbstractGfeTask;
* non-UI thread
* Dec 1, 2010 6130 ryu Set proper state and invoke callback
* May 29, 2014 2841 randerso Handle failure to queue due to pending limit
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -73,7 +74,7 @@ public class TextFormatter extends AbstractGfeTask {
private HashMap<String, Object> argMap;
private ConfigData.productStateEnum state;
private ConfigData.ProductStateEnum state;
/**
* Constructor
@ -103,7 +104,7 @@ public class TextFormatter extends AbstractGfeTask {
argMap.put(ArgDictConstants.VTEC_ACTIVE_TABLE, vtecActiveTable);
argMap.put("drtTime", drtTime);
listener = finish;
this.state = ConfigData.productStateEnum.Queued;
this.state = ConfigData.ProductStateEnum.Queued;
}
@Override
@ -114,7 +115,7 @@ public class TextFormatter extends AbstractGfeTask {
VizApp.runSyncIfWorkbench(new Runnable() {
@Override
public void run() {
state = ConfigData.productStateEnum.Running;
state = ConfigData.ProductStateEnum.Running;
listener.startProgressBar(state);
}
});
@ -130,11 +131,11 @@ public class TextFormatter extends AbstractGfeTask {
perfLog.logDuration("Text Formatter " + productName,
timer.getElapsedTime());
state = ConfigData.productStateEnum.Finished;
state = ConfigData.ProductStateEnum.Finished;
} catch (Throwable t) {
statusHandler.handle(Priority.PROBLEM,
"Error generating text product", t);
state = ConfigData.productStateEnum.Failed;
state = ConfigData.ProductStateEnum.Failed;
} finally {
SamplerGridSliceCache.remove(this.getId());
SamplerGridSliceCache.remove(UI_THREAD_ID);
@ -149,8 +150,8 @@ public class TextFormatter extends AbstractGfeTask {
VizApp.runSyncIfWorkbench(new Runnable() {
@Override
public void run() {
listener.textProductFinished(text, state);
listener.stopProgressBar(state);
listener.textProductFinished(text, state);
}
});
}
@ -167,9 +168,9 @@ public class TextFormatter extends AbstractGfeTask {
// TODO: this is deprecated and probably not a good thing to do.
// we really need to get formatters running in their own process
// so we can kill them safely
if (this.state.equals(productStateEnum.Queued)
|| this.state.equals(productStateEnum.New)) {
state = ConfigData.productStateEnum.Failed;
if (this.state.equals(ProductStateEnum.Queued)
|| this.state.equals(ProductStateEnum.New)) {
state = ConfigData.ProductStateEnum.Failed;
cleanUp(null);
this.finishedTime = SimulatedTime.getSystemTime().getTime();

View file

@ -29,6 +29,8 @@ import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 15, 2008 njensen Initial creation
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
* @author njensen
@ -38,12 +40,12 @@ import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
public interface TextProductFinishListener {
public void textProductFinished(String productText,
ConfigData.productStateEnum state);
ConfigData.ProductStateEnum state);
public void startProgressBar(ConfigData.productStateEnum state);
public void startProgressBar(ConfigData.ProductStateEnum state);
public void stopProgressBar(ConfigData.productStateEnum state);
public void stopProgressBar(ConfigData.ProductStateEnum state);
public void textProductQueued();
public void textProductQueued(ConfigData.ProductStateEnum state);
}

View file

@ -20,6 +20,7 @@
package com.raytheon.viz.gfe.textformatter;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.ProductStateEnum;
/**
* Listens for a text product to finish and then returns the product with
@ -32,6 +33,7 @@ import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 30, 2009 njensen Initial creation
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -43,7 +45,7 @@ public class TextProductFinishWaiter implements TextProductFinishListener {
private String product;
private boolean wait = true;
private ProductStateEnum state;
/*
* (non-Javadoc)
@ -53,8 +55,8 @@ public class TextProductFinishWaiter implements TextProductFinishListener {
* ()
*/
@Override
public void startProgressBar(ConfigData.productStateEnum state) {
wait = true;
public void startProgressBar(ConfigData.ProductStateEnum state) {
this.state = state;
}
/*
@ -65,8 +67,8 @@ public class TextProductFinishWaiter implements TextProductFinishListener {
* ()
*/
@Override
public void stopProgressBar(ConfigData.productStateEnum state) {
wait = false;
public void stopProgressBar(ConfigData.ProductStateEnum state) {
this.state = state;
}
/*
@ -76,8 +78,8 @@ public class TextProductFinishWaiter implements TextProductFinishListener {
* textProductQueued()
*/
@Override
public void textProductQueued() {
wait = true;
public void textProductQueued(ConfigData.ProductStateEnum state) {
this.state = state;
}
/*
@ -88,16 +90,22 @@ public class TextProductFinishWaiter implements TextProductFinishListener {
*/
@Override
public void textProductFinished(String productText,
ConfigData.productStateEnum state) {
ConfigData.ProductStateEnum state) {
this.product = productText;
wait = false;
this.state = state;
}
public String waitAndGetProduct() throws InterruptedException {
while (wait) {
Thread.sleep(50);
while (!state.isComplete()) {
Thread.sleep(100);
}
if (state == ConfigData.ProductStateEnum.Failed) {
product = "";
}
return product;
}
public ConfigData.ProductStateEnum getState() {
return this.state;
}
}

View file

@ -62,6 +62,8 @@ import com.raytheon.viz.gfe.core.DataManager;
* Apr 24, 2013 1936 dgilling Remove unused imports.
* Feb 12, 2014 2591 randerso Removed reloadModule method
* Dec 15, 2014 #14946 ryu Add getTimeZones() method.
* Apr 20, 2015 4027 randerso Made fileObservers conditional as they are not needed
* in a non-GUI environment like GFE formatter auto-tests
*
* </pre>
*
@ -89,9 +91,9 @@ public class TextProductManager {
private TextProductListener listener;
public TextProductManager() {
public TextProductManager(boolean startListener) {
try {
init();
init(startListener);
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM,
"Exception initializing TextProductManager", e);
@ -101,7 +103,7 @@ public class TextProductManager {
}
}
private void init() throws VizException, JepException {
private void init(boolean startListener) throws VizException, JepException {
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext configContext = pm.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.CONFIGURED);
@ -116,10 +118,12 @@ public class TextProductManager {
GfePyIncludeUtil.TEXT_PRODUCTS);
lfUserDir = pm.getLocalizationFile(userContext,
GfePyIncludeUtil.TEXT_PRODUCTS);
if (startListener) {
listener = new TextProductListener();
lfConfigDir.addFileUpdatedObserver(listener);
lfSiteDir.addFileUpdatedObserver(listener);
lfUserDir.addFileUpdatedObserver(listener);
}
script = FormatterScriptFactory.buildFormatterScript();
@ -136,10 +140,10 @@ public class TextProductManager {
HashMap<String, Object> map = new HashMap<String, Object>();
String paths = configDir.getPath();
if (siteDir != null && siteDir.exists()) {
if ((siteDir != null) && siteDir.exists()) {
paths = siteDir + ":" + paths;
}
if (userDir != null && userDir.exists()) {
if ((userDir != null) && userDir.exists()) {
paths = userDir + ":" + paths;
}
map.put("paths", paths);
@ -170,7 +174,7 @@ public class TextProductManager {
public String getCombinationsFileName(String productName) {
String filename = null;
Object obj = getDefinitionValue(productName, "defaultEditAreas");
if (obj != null && obj instanceof String) {
if ((obj != null) && (obj instanceof String)) {
filename = (String) obj;
} else {
filename = "NONE";
@ -181,7 +185,7 @@ public class TextProductManager {
public boolean isSingleZoneSelect(String productName) {
boolean isSingle = false;
Object obj = getDefinitionValue(productName, "singleComboOnly");
if (obj != null && obj instanceof Integer) {
if ((obj != null) && (obj instanceof Integer)) {
if ((Integer) obj == 1) {
isSingle = true;
}
@ -245,12 +249,13 @@ public class TextProductManager {
statusHandler.handle(Priority.PROBLEM,
"Exception getting VTECMessageType", e);
}
if (vtec == null) {
vtec = "";
}
return vtec;
}
public List<String> getTimeZones(List<String> zones,
String officeTimeZone) {
public List<String> getTimeZones(List<String> zones, String officeTimeZone) {
List<String> timeZones = Collections.emptyList();
HashMap<String, Object> map = new HashMap<String, Object>(2);
map.put("zones", zones);

View file

@ -29,6 +29,7 @@ import java.util.Map;
import java.util.regex.Matcher;
import com.google.common.collect.ImmutableSet;
import com.raytheon.uf.common.activetable.ActiveTableMode;
import com.raytheon.uf.common.activetable.response.GetNextEtnResponse;
import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.common.util.StringUtil;
@ -63,6 +64,7 @@ import com.raytheon.viz.texteditor.util.VtecUtil;
* Dec 18, 2013 #2641 dgilling Force ordering of items returned by
* getVtecLinesThatNeedEtn().
* Feb 05, 2014 #2774 dgilling Additional correction to previous fix.
* Apr 28, 2015 #4027 randerso Added getNextEtn parameter to specify ActiveTableMode
*
* </pre>
*
@ -134,6 +136,33 @@ public class GFEVtecUtil {
return getNextEtn(office, phensig, lockEtn, false, false, null);
}
/**
* Gets the next available ETN for a specific product and office.
*
* @param office
* The 4-character site ID of the office.
* @param phensig
* The phenomenon and significance of the hazard concatenated
* with a '.' (e.g., TO.W or DU.Y)
* @param lockEtn
* Whether or not to request an exclusive ETN--if true, this will
* cause the server to increment its running ETN sequence to the
* next number after determining the next ETN for this request.
* If false, the next ETN will be returned, but it will not
* increment the server's running sequence, so the ETN return
* could be used by another client that makes a
* GetNextEtnRequest.
* @param mode
* Indicates which active table to query
* @return The next ETN in sequence, given the office and phensig.
* @throws VizException
* If an error occurred sending the request to the server.
*/
public static GetNextEtnResponse getNextEtn(String office, String phensig,
boolean lockEtn, ActiveTableMode mode) throws VizException {
return getNextEtn(office, phensig, lockEtn, false, false, null, mode);
}
/**
* Gets the next available ETN for a specific product and office.
*
@ -206,6 +235,50 @@ public class GFEVtecUtil {
reportOnlyConflict, etnOverride);
}
/**
* Gets the next available ETN for a specific product and office.
*
* @param office
* The 4-character site ID of the office.
* @param phensig
* The phenomenon and significance of the hazard concatenated
* with a '.' (e.g., TO.W or DU.Y)
* @param lockEtn
* Whether or not to request an exclusive ETN--if true, this will
* cause the server to increment its running ETN sequence to the
* next number after determining the next ETN for this request.
* If false, the next ETN will be returned, but it will not
* increment the server's running sequence, so the ETN return
* could be used by another client that makes a
* GetNextEtnRequest.
* @param performISC
* Whether or not to collaborate with neighboring sites to
* determine the next ETN. See {@link
* GetNextEtnUtil#getNextEtnFromPartners(String, ActiveTableMode,
* String, Calendar, List<IRequestRouter>)} for more information.
* @param reportOnlyConflict
* Affects which kinds of errors get reported back to the
* requestor. If true, only cases where the value of
* <code>etnOverride</code> is less than or equal to the last ETN
* used by this site or any of its partners will be reported.
* Else, all significant errors will be reported back.
* @param etnOverride
* Allows the user to influence the next ETN assigned by using
* this value unless it is less than or equal to the last ETN
* used by this site or one of its partners.
* @param mode
* Indicates which active table to query
* @return The next ETN in sequence, given the office and phensig.
* @throws VizException
* If an error occurred sending the request to the server.
*/
public static GetNextEtnResponse getNextEtn(String office, String phensig,
boolean lockEtn, boolean performISC, boolean reportOnlyConflict,
Integer etnOverride, ActiveTableMode mode) throws VizException {
return VtecUtil.getNextEtn(office, phensig, lockEtn, performISC,
reportOnlyConflict, etnOverride, mode);
}
/**
* Reads through a GFE VTEC product and returns VTEC lines with NEW action
* codes that need to be assigned an ETN.

View file

@ -48,6 +48,7 @@ import com.raytheon.viz.ghg.monitor.data.GhgConfigData.SelectionEnum;
* ------------ ---------- ----------- --------------------------
* 25 MAR 2008 N/A lvenable Initial creation
* 30 JUL 2010 6721 mpduff WFO now from officeid column.
* 28 APR 2015 4027 randerso Expunged Calendar from ActiveTableRecord
*
* </pre>
*
@ -234,13 +235,13 @@ public class GhgData implements Comparable<GhgData> {
sig = warning.getSig();
hazard = getHazardDescription(getPhenSig());
try {
startDate = warning.getStartTime().getTime();
startDate = warning.getStartTime();
} catch (Exception e) {
startDate = now;
}
endDate = warning.getEndTime().getTime();
purgeDate = warning.getPurgeTime().getTime();
issueTime = warning.getIssueTime().getTime();
endDate = warning.getEndTime();
purgeDate = warning.getPurgeTime();
issueTime = warning.getIssueTime();
pil = warning.getPil();
segNum = String.valueOf(warning.getSeg());
wfo = warning.getOfficeid();
@ -933,7 +934,7 @@ public class GhgData implements Comparable<GhgData> {
@Override
public int hashCode() {
int hash = 1;
hash = hash * 31 + hazard.hashCode();
hash = (hash * 31) + hazard.hashCode();
return hash;
}

View file

@ -19,11 +19,15 @@
**/
package com.raytheon.viz.satellite.inventory;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.measure.unit.Unit;
import javax.measure.unit.UnitFormat;
import org.geotools.coverage.grid.GridEnvelope2D;
@ -33,11 +37,15 @@ import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
import com.raytheon.uf.common.dataplugin.satellite.units.generic.GenericPixel;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.geospatial.interpolation.GridDownscaler;
import com.raytheon.uf.common.inventory.data.AbstractRequestableData;
import com.raytheon.uf.common.inventory.exception.DataCubeException;
import com.raytheon.viz.satellite.tileset.SatDataRetriever;
/**
* Satellite record which performs derived parameter calculations to get data
@ -50,6 +58,7 @@ import com.raytheon.uf.common.inventory.exception.DataCubeException;
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Apr 09, 2014 2947 bsteffen Initial creation
* Apr 15, 2014 4388 bsteffen Set Fill Value.
*
* </pre>
*
@ -134,15 +143,56 @@ public class DerivedSatelliteRecord extends SatelliteRecord {
throw new DataCubeException(e);
}
gridGeometry = new GridGeometry2D(range, env);
} else if (req.getType() == Request.Type.POINT
&& req.getPoints().length == 1) {
Point p = req.getPoints()[0];
GridEnvelope2D range = new GridEnvelope2D(p.x, p.y, 1, 1);
Envelope env;
try {
env = gridGeometry.gridToWorld(range);
} catch (TransformException e) {
throw new DataCubeException(e);
}
gridGeometry = new GridGeometry2D(range, env);
} else if (req.getType() != Request.Type.ALL) {
throw new DataCubeException(
"Unsupported request type for derived satellite data: "
+ req.getType());
}
Object dataValue = requestableData.getDataValue(gridGeometry);
setDerivedFillValue(dataValue);
setMessageData(dataValue);
}
/**
* Set a fill value on the dataValue if applicable. Some derived parameters
* operate on unsigned byte data and return signed byte data and need a fill
* value set to composite properly.
*/
private void setDerivedFillValue(Object dataValue) {
IDataRecord dataRecord = null;
if (dataValue instanceof IDataRecord[]) {
IDataRecord[] dataRecords = (IDataRecord[]) dataValue;
if (dataRecords.length == 1) {
dataRecord = dataRecords[0];
}
} else if (dataValue instanceof IDataRecord) {
dataRecord = (IDataRecord) dataValue;
}
if (dataRecord instanceof ByteDataRecord) {
Unit<?> unit = SatDataRetriever.getRecordUnit(this);
if (unit instanceof GenericPixel) {
dataRecord.setFillValue(Byte.MIN_VALUE);
Map<String, Object> attributes = dataRecord.getDataAttributes();
if (attributes == null) {
attributes = new HashMap<String, Object>();
}
attributes.put(SatelliteRecord.SAT_SIGNED_FLAG, Boolean.TRUE);
dataRecord.setDataAttributes(attributes);
}
}
}
private static Set<SatelliteRecord> findBaseRecords(
AbstractRequestableData data) {
if (data instanceof SatelliteRequestableData) {

View file

@ -21,7 +21,6 @@ package com.raytheon.viz.satellite.inventory;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Map;
import javax.measure.unit.Unit;
@ -61,6 +60,7 @@ import com.raytheon.viz.satellite.tileset.SatDataRetriever;
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Apr 09, 2014 2947 bsteffen Initial creation
* Apr 15, 2014 4388 bsteffen Set Fill Value.
*
* </pre>
*
@ -153,20 +153,13 @@ public class SatelliteRequestableData extends AbstractRequestableData {
} catch (FactoryException e) {
throw new DataCubeException(e);
}
Map<String, Object> attrs = dataRecord.getDataAttributes();
Number fillValue = dataRecord.getFillValue();
dataRecord = DataStoreFactory.createStorageRecord(
dataRecord.getName(), dataRecord.getGroup(),
dest.getArray(), 2, new long[] { requestRange.width,
requestRange.height });
dataRecord.setFillValue(0);
if (attrs != null) {
Number fill = (Number) attrs
.get(SatelliteRecord.SAT_FILL_VALUE);
if (fill != null) {
dataRecord.setFillValue(fill);
}
}
dataRecord.setFillValue(fillValue);
return dataRecord;
} else {
return CubeUtil.retrieveData(record, record.getPluginName(),

View file

@ -38,6 +38,8 @@ import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.colormap.ColorMapException;
import com.raytheon.uf.common.colormap.ColorMapLoader;
import com.raytheon.uf.common.colormap.IColorMap;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters.PersistedParameters;
@ -45,10 +47,16 @@ import com.raytheon.uf.common.colormap.prefs.DataMappingPreferences;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
import com.raytheon.uf.common.dataplugin.satellite.units.generic.GenericPixel;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.data.GeographicDataSource;
import com.raytheon.uf.common.inventory.exception.DataCubeException;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.style.ParamLevelMatchCriteria;
import com.raytheon.uf.common.style.StyleException;
import com.raytheon.uf.common.style.StyleManager;
@ -62,7 +70,6 @@ import com.raytheon.uf.common.style.level.SingleLevel;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.drawables.ColorMapLoader;
import com.raytheon.uf.viz.core.drawables.IRenderable;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension.ImageProvider;
@ -79,6 +86,7 @@ import com.raytheon.uf.viz.core.rsc.interrogation.InterrogateMap;
import com.raytheon.uf.viz.core.rsc.interrogation.InterrogationKey;
import com.raytheon.uf.viz.core.rsc.interrogation.Interrogator;
import com.raytheon.uf.viz.core.rsc.interrogation.StringInterrogationKey;
import com.raytheon.uf.viz.datacube.DataCubeContainer;
import com.raytheon.viz.satellite.SatelliteConstants;
import com.raytheon.viz.satellite.inventory.DerivedSatelliteRecord;
import com.raytheon.viz.satellite.tileset.SatDataRetriever;
@ -127,7 +135,7 @@ import com.raytheon.viz.awipstools.IToolChangedListener;
* Oct 15, 2014 3681 bsteffen create renderable in interrogate if necessary.
* Feb 17, 2015 4135 bsteffen Set no data value for derived products.
* Mar 3, 2015 DCS 14960 jgerth Retrieve legend from style rules if available
*
* Apr 15, 2014 4388 bsteffen Use fill value from record.
*
* </pre>
*
@ -333,6 +341,57 @@ public class SatResource extends
cmName = colorMapParameters.getColorMapName();
}
}
Unit<?> unit = SatDataRetriever.getRecordUnit(record);
/*
* TODO default to NaN instead of 0. 0 is the default to support older
* data(before the gini decoder set a fill value), when all decoders and
* all decoded data has a proper fill value this should be changed to
* Double.NaN.
*/
double fillValue = 0;
double defaultMin = 0;
double defaultMax = 0xff;
try {
String dataSetName = DataStoreFactory.createDataSetName(null,
SatelliteRecord.SAT_DATASET_NAME, 0);
IDataRecord dataRecord = DataCubeContainer.getDataRecord(record,
Request.buildPointRequest(new java.awt.Point(0, 0)),
dataSetName)[0];
Number fillObj = dataRecord.getFillValue();
if (fillObj != null) {
fillValue = fillObj.doubleValue();
}
if (dataRecord instanceof ShortDataRecord) {
if (SatDataRetriever.isSigned(dataRecord)) {
defaultMin = Short.MIN_VALUE;
defaultMax = Short.MAX_VALUE;
} else {
defaultMin = 0;
defaultMax = 0xFFFF;
fillValue = ((int) fillValue) & 0xFFFF;
}
} else if (dataRecord instanceof ByteDataRecord) {
if (SatDataRetriever.isSigned(dataRecord)) {
defaultMin = Byte.MIN_VALUE;
defaultMax = Byte.MAX_VALUE;
} else {
defaultMin = 0;
defaultMax = 0xFF;
fillValue = ((int) fillValue) & 0xFF;
}
}
Unit<?> dataUnit = SatDataRetriever.getDataUnit(unit, dataRecord);
if (dataUnit != null && unit != null && dataUnit.isCompatible(unit)) {
UnitConverter converter = dataUnit.getConverterTo(unit);
defaultMin = converter.convert(defaultMin);
defaultMax = converter.convert(defaultMax);
}
} catch (DataCubeException e) {
statusHandler.handle(Priority.WARN,
"Unable to request sample record", e);
}
SingleLevel level = new SingleLevel(Level.LevelType.SURFACE);
String physicalElement = record.getPhysicalElement();
@ -342,7 +401,6 @@ public class SatResource extends
match.setParameterName(Arrays.asList(physicalElement));
match.setLevels(Arrays.asList((Level) level));
match.setCreatingEntityNames(Arrays.asList(record.getCreatingEntity()));
Unit<?> unit = SatDataRetriever.getRecordUnit(record);
String lg = null;
try {
StyleRule sr = StyleManager.getInstance().getStyleRule(
@ -360,8 +418,8 @@ public class SatResource extends
}
DataScale range = new DataScale();
range.setScaleType(DataScale.Type.LINEAR);
range.setMinValue(0.0);
range.setMaxValue(255.0);
range.setMinValue(defaultMin);
range.setMaxValue(defaultMax);
preferences.setDataScale(range);
} else {
preferences = (ImagePreferences) sr.getPreferences();
@ -392,7 +450,11 @@ public class SatResource extends
if (cmName == null) {
cmName = "Sat/VIS/ZA (Vis Default)";
}
try {
colorMap = ColorMapLoader.loadColorMap(cmName);
} catch (ColorMapException e) {
throw new VizException("Unable to load clormap: " + cmName, e);
}
}
if (colorMap != null) {
@ -402,18 +464,9 @@ public class SatResource extends
if (persisted != null) {
colorMapParameters.applyPersistedParameters(persisted);
}
if (colorMapParameters.getDataMapping() == null) {
if (unit instanceof GenericPixel) {
/**
* Generic Pixel only comes from derived parameter which used
* signed data so 0 is valid but -128 is used as a no data
* value.
*/
colorMapParameters.setNoDataValue(Byte.MIN_VALUE);
} else {
colorMapParameters.setNoDataValue(0);
}
if (colorMapParameters.getDataMapping() == null) {
colorMapParameters.setNoDataValue(fillValue);
}
getCapability(ColorMapCapability.class).setColorMapParameters(

View file

@ -34,7 +34,6 @@ import javax.measure.unit.UnitFormat;
import com.raytheon.uf.common.colormap.image.ColorMapData;
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
import com.raytheon.uf.common.dataplugin.satellite.units.generic.GenericPixel;
import com.raytheon.uf.common.dataplugin.satellite.units.goes.PolarPrecipWaterPixel;
import com.raytheon.uf.common.dataplugin.satellite.units.water.BlendedTPWPixel;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
@ -66,6 +65,7 @@ import com.raytheon.viz.satellite.SatelliteConstants;
* data record attributes for unit
* Apr 09, 2014 2947 bsteffen Improve flexibility of sat derived
* parameters.
* Apr 15, 2014 4388 bsteffen Add method to get signed vs. unsigned from data record.
*
* </pre>
*
@ -118,7 +118,7 @@ public class SatDataRetriever implements IColorMapDataRetrievalCallback {
data = FloatBuffer.wrap((float[]) record.getDataObject());
}
Unit<?> recordUnit = getRecordUnit(this.record);
signed = recordUnit instanceof GenericPixel;
signed = isSigned(record);
dataUnit = getDataUnit(recordUnit, record);
}
} catch (DataCubeException e) {
@ -209,6 +209,18 @@ public class SatDataRetriever implements IColorMapDataRetrievalCallback {
return units;
}
public static boolean isSigned(IDataRecord record) {
Map<String, Object> attrs = record.getDataAttributes();
if (attrs != null) {
Boolean signed = (Boolean) attrs
.get(SatelliteRecord.SAT_SIGNED_FLAG);
if (signed != null && signed) {
return true;
}
}
return false;
}
/*
* (non-Javadoc)
*

View file

@ -35,10 +35,14 @@ import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.colormap.image.ColorMapData;
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
import com.raytheon.uf.common.geospatial.data.GeographicDataSource;
import com.raytheon.uf.common.numeric.buffer.BufferWrapper;
import com.raytheon.uf.common.numeric.buffer.ByteBufferWrapper;
import com.raytheon.uf.common.numeric.buffer.ShortBufferWrapper;
import com.raytheon.uf.common.numeric.filter.UnsignedFilter;
import com.raytheon.uf.common.numeric.source.DataSource;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IGraphicsTarget;
@ -61,11 +65,12 @@ import com.vividsolutions.jts.geom.Coordinate;
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* ------------- -------- ----------- --------------------------
* Jun 19, 2013 mschenke Initial creation
* Jun 19, 2014 3238 bsteffen Add method to create a DataSource for
* a tile level.
* Oct 15, 2014 3681 bsteffen Allow asynchronous interrogation.
* May 04, 2015 4426 bsteffen Fix unsigned interrogation.
*
* </pre>
*
@ -248,6 +253,11 @@ public class SatTileSetRenderable extends RecordTileSetRenderable {
Rectangle rect = tile.getRectangle();
DataSource source = BufferWrapper.wrap(data.getBuffer(),
rect.width, rect.height);
if (data.getDataType() == ColorMapDataType.BYTE) {
source = UnsignedFilter.apply((ByteBufferWrapper) source);
} else if (data.getDataType() == ColorMapDataType.UNSIGNED_SHORT) {
source = UnsignedFilter.apply((ShortBufferWrapper) source);
}
dataValue = source.getDataValue(tilex, tiley);
dataUnit = data.getDataUnit();
}

View file

@ -33,6 +33,7 @@ import com.raytheon.uf.common.activetable.GetActiveTableResponse;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.requests.ThriftClient;
import com.raytheon.viz.core.mode.CAVEMode;
@ -52,6 +53,7 @@ import com.raytheon.viz.ui.dialogs.SWTMessageBox;
* tables names.
* Dec 20, 2010 7210 cjeanbap Added non-blocking dialog.
* Apr 25, 2014 DR 16668 D. Friedman Handle partial cancellations
* Apr 28, 2015 4027 randerso Expunged Calendar from ActiveTableRecord
* </pre>
*
* @author jsanchez
@ -65,7 +67,7 @@ public class NotifyExpirationTask extends TimerTask {
/**
* Miliseconds in two days
*/
private static final long TWO_DAYS = 48 * 60 * 60 * 1000;
private static final long TWO_DAYS = 2 * TimeUtil.MILLIS_PER_DAY;
private String office;
@ -90,9 +92,11 @@ public class NotifyExpirationTask extends TimerTask {
+ dateFormat.format(vtecObject.getEndTime().getTime());
}
@Override
public void run() {
if (!isCanceled()) {
parentShell.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
SWTMessageBox mb = new SWTMessageBox(
NotifyExpirationTask.this.parentShell,
@ -126,8 +130,8 @@ public class NotifyExpirationTask extends TimerTask {
activeTable = resp.getActiveTable();
} catch (VizException e) {
statusHandler.handle(Priority.ERROR,
"Error querying active table for " + office + "."
+ phenSig + "." + etn, e);
"Error querying active table for " + office + "." + phenSig
+ "." + etn, e);
}
if (activeTable != null) {
@ -135,15 +139,16 @@ public class NotifyExpirationTask extends TimerTask {
for (ActiveTableRecord record : activeTable) {
if (record != null) {
/*
* textNotifyExpiration.tcl ln 106: If any of the found products are
* less than 48 hours old,return true.
* textNotifyExpiration.tcl ln 106: If any of the found
* products are less than 48 hours old,return true.
*/
if ("CAN".equals(record.getAct())
&& (System.currentTimeMillis()
- record.getIssueTime().getTimeInMillis() < TWO_DAYS)) {
&& ((System.currentTimeMillis() - record
.getIssueTime().getTime()) < TWO_DAYS)) {
haveCAN = true;
} else if ("CON".equals(record.getAct())) {
/* If there CANs and the event is still active, there
/*
* If there CANs and the event is still active, there
* should be some CONs. Thus, it is not necessary to
* check for every other kind of non-terminal action.
*/
@ -160,7 +165,7 @@ public class NotifyExpirationTask extends TimerTask {
private String pad(int value) {
String rval = "";
String str = Integer.toString(value);
for (int i = 0; i < 4 - str.length(); i++) {
for (int i = 0; i < (4 - str.length()); i++) {
rval += "0";
}

View file

@ -20,6 +20,7 @@
package com.raytheon.viz.texteditor.util;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.regex.Matcher;
@ -46,6 +47,9 @@ import com.raytheon.viz.core.mode.CAVEMode;
* May 08, 2013 #1842 dgilling Code cleanup.
* Aug 29, 2013 #1843 dgilling Use new GetNextEtnRequest constructor.
* Oct 21, 2013 #1843 dgilling Use new GetNextEtnResponse.
* Apr 28, 2015 #4027 randerso Expunged Calendar from ActiveTableRecord
* Added getNextEtn method with parameter to specify
* activeTableMode
*
* </pre>
*
@ -103,7 +107,7 @@ public class VtecUtil {
return message;
}
VtecObject vtec = parseMessage(message);
if (vtec == null || vtec.getAction() == null) {
if ((vtec == null) || (vtec.getAction() == null)) {
return message;
}
@ -181,13 +185,57 @@ public class VtecUtil {
public static GetNextEtnResponse getNextEtn(String office, String phensig,
boolean lockEtn, boolean performISC, boolean reportOnlyConflict,
Integer etnOverride) throws VizException {
Calendar currentTime = Calendar.getInstance();
currentTime.setTime(SimulatedTime.getSystemTime().getTime());
ActiveTableMode activeTable = (CAVEMode.getMode()
.equals(CAVEMode.PRACTICE)) ? ActiveTableMode.PRACTICE
ActiveTableMode mode = (CAVEMode.getMode().equals(CAVEMode.PRACTICE)) ? ActiveTableMode.PRACTICE
: ActiveTableMode.OPERATIONAL;
GetNextEtnRequest req = new GetNextEtnRequest(office, activeTable,
phensig, currentTime, lockEtn, performISC, reportOnlyConflict,
return getNextEtn(office, phensig, lockEtn, performISC,
reportOnlyConflict, etnOverride, mode);
}
/**
* Gets the next available ETN for a specific product and office.
*
* @param office
* The 4-character site ID of the office.
* @param phensig
* The phenomenon and significance of the hazard concatenated
* with a '.' (e.g., TO.W or DU.Y)
* @param lockEtn
* Whether or not to request an exclusive ETN--if true, this will
* cause the server to increment its running ETN sequence to the
* next number after determining the next ETN for this request.
* If false, the next ETN will be returned, but it will not
* increment the server's running sequence, so the ETN return
* could be used by another client that makes a
* GetNextEtnRequest.
* @param performISC
* Whether or not to collaborate with neighboring sites to
* determine the next ETN. See {@link
* GetNextEtnUtil#getNextEtnFromPartners(String, ActiveTableMode,
* String, Calendar, List<IRequestRouter>)} for more information.
* @param reportOnlyConflict
* Affects which kinds of errors get reported back to the
* requestor. If true, only cases where the value of
* <code>etnOverride</code> is less than or equal to the last ETN
* used by this site or any of its partners will be reported.
* Else, all significant errors will be reported back.
* @param etnOverride
* Allows the user to influence the next ETN assigned by using
* this value unless it is less than or equal to the last ETN
* used by this site or one of its partners.
* @param mode
* Indicates which active table to query
* @return The next ETN in sequence, given the office and phensig.
* @throws VizException
* If an error occurs while submitting or processing the remote
* request.
*/
public static GetNextEtnResponse getNextEtn(String office, String phensig,
boolean lockEtn, boolean performISC, boolean reportOnlyConflict,
Integer etnOverride, ActiveTableMode mode) throws VizException {
Date currentTime = SimulatedTime.getSystemTime().getTime();
GetNextEtnRequest req = new GetNextEtnRequest(office, mode, phensig,
currentTime, lockEtn, performISC, reportOnlyConflict,
etnOverride);
GetNextEtnResponse resp = (GetNextEtnResponse) ThriftClient
@ -197,6 +245,13 @@ public class VtecUtil {
return rval;
}
/**
* Parse a VTEC message
*
* @param message
* the message
* @return the parsed VtecObject
*/
public static VtecObject parseMessage(String message) {
VtecObject rval = null;
Matcher m = VTEC_REGEX.matcher(message);
@ -215,7 +270,7 @@ public class VtecUtil {
*
* @param message
* the message to modify
* @param obj
* @param vtec
* new VTEC for the message
*
* @return the modified message

View file

@ -85,6 +85,7 @@ import com.vividsolutions.jts.geom.Polygon;
* /missing (part of state, state abbreviation) which resulted from
* extension of a watch to counties which are of same/different fe_area.
* Sep 25, 2014 ASM #16783 D. Friedman Do not use VTEC action to determine Watch uniqueness.
* Apr 28, 2015 RODO #4027 randerso Expunged Calendar from ActiveTableRecord
* </pre>
*
* @author jsanchez
@ -324,12 +325,12 @@ public class WatchUtil {
* fixed the underlying system. request.addConstraint("act", new
* RequestConstraint("CAN", ConstraintType.NOT_EQUALS));
*/
if (action != WarningAction.CAN && action != WarningAction.EXP) {
if ((action != WarningAction.CAN) && (action != WarningAction.EXP)) {
ActiveTableRecord record = entityClass.newInstance();
record.setIssueTime((Calendar) result.get(ISSUE_TIME_FIELD));
record.setStartTime((Calendar) result.get(START_TIME_FIELD));
record.setEndTime((Calendar) result.get(END_TIME_FIELD));
record.setEndTime((Calendar) result.get(END_TIME_FIELD));
record.setIssueTime((Date) result.get(ISSUE_TIME_FIELD));
record.setStartTime((Date) result.get(START_TIME_FIELD));
record.setEndTime((Date) result.get(END_TIME_FIELD));
record.setEndTime((Date) result.get(END_TIME_FIELD));
record.setUgcZone(String.valueOf(result.get(UGC_ZONE_FIELD)));
record.setPhensig(String.valueOf(result.get(PHEN_SIG_FIELD)));
record.setEtn(String.valueOf(result.get(ETN)));
@ -348,10 +349,12 @@ public class WatchUtil {
}
}
// remove ActiveTableRecord from records whose etn, ugcZone, and phensig is same as
// canceled or expired.
/*
* remove ActiveTableRecord from records whose etn, ugcZone, and phensig
* is same as canceled or expired.
*/
String etn, ugczone, phensig;
for (Pair<String, String> etnPhensig: removedUgczones.keySet()) {
for (Pair<String, String> etnPhensig : removedUgczones.keySet()) {
ugczones = removedUgczones.get(etnPhensig);
etn = etnPhensig.getFirst();
phensig = etnPhensig.getSecond();
@ -361,8 +364,9 @@ public class WatchUtil {
Iterator<ActiveTableRecord> iterator = records.iterator();
while (iterator.hasNext()) {
ActiveTableRecord atr = iterator.next();
if (atr.getEtn().equals(etn) && atr.getUgcZone().equals(ugczone) &&
atr.getPhensig().equals(phensig)) {
if (atr.getEtn().equals(etn)
&& atr.getUgcZone().equals(ugczone)
&& atr.getPhensig().equals(phensig)) {
iterator.remove();
}
}
@ -371,9 +375,12 @@ public class WatchUtil {
Collections.sort(records, PEUI);
// Filters out extra ActiveTableRecords that have same phenSig, etn, and ugcZone.
/*
* Filters out extra ActiveTableRecords that have same phenSig, etn, and
* ugcZone.
*/
Map<String, ActiveTableRecord> atrMap = new LinkedHashMap<String, ActiveTableRecord>();
for (ActiveTableRecord atr: records) {
for (ActiveTableRecord atr : records) {
String key = atr.getPhensig() + atr.getEtn() + atr.getUgcZone();
atrMap.put(key, atr);
}
@ -419,7 +426,7 @@ public class WatchUtil {
String ugcZone = ar.getUgcZone();
String state = null;
if (marineUgcs != null && marineUgcs.contains(ugcZone)) {
if ((marineUgcs != null) && marineUgcs.contains(ugcZone)) {
// Just leave state == null
} else {
state = getStateName(ugcZone.substring(0, 2));
@ -430,12 +437,11 @@ public class WatchUtil {
String phenSig = ar.getPhensig();
String etn = ar.getEtn();
Date startTime = ar.getStartTime().getTime();
Date endTime = ar.getEndTime().getTime();
Date startTime = ar.getStartTime();
Date endTime = ar.getEndTime();
if (validUgcZones.contains(ugcZone)) {
Watch watch = new Watch(state, phenSig, etn, startTime,
endTime);
Watch watch = new Watch(state, phenSig, etn, startTime, endTime);
List<String> areas = map.get(watch);
if (areas == null) {
areas = new ArrayList<String>();
@ -460,9 +466,9 @@ public class WatchUtil {
}
}
/* Sorts the watches based on ETN, then state. Marine areas
* have a null state value so they appear at the end of each
* watch.
/*
* Sorts the watches based on ETN, then state. Marine areas have a null
* state value so they appear at the end of each watch.
*/
Collections.sort(watches, new Comparator<Watch>() {
@ -471,37 +477,44 @@ public class WatchUtil {
String etn1 = watch1.getEtn();
String etn2 = watch2.getEtn();
int c;
if (etn1 == etn2)
if (etn1 == etn2) {
c = 0;
else if (etn1 == null)
} else if (etn1 == null) {
return 1;
else if (etn2 == null)
} else if (etn2 == null) {
return -1;
else
} else {
c = etn1.compareTo(etn2);
if (c != 0)
}
if (c != 0) {
return c;
}
String state1 = watch1.getState();
String state2 = watch2.getState();
if (state1 == state2)
if (state1 == state2) {
return 0;
else if (state1 == null)
} else if (state1 == null) {
return 1; // null state is greater; put at end
else if (state2 == null)
} else if (state2 == null) {
return -1;
else
} else {
return state1.compareTo(state2);
}
}
});
// Filters out extra Watches that have different startTime but same phenSig, etn, state, partOfState, endTime, and marineArea.
/*
* Filters out extra Watches that have different startTime but same
* phenSig, etn, state, partOfState, endTime, and marineArea.
*/
Map<String, Watch> watchMap = new LinkedHashMap<String, Watch>();
for (Watch w: watches) {
List<String> pos = w.getPartOfState() != null ?
new ArrayList<String>(w.getPartOfState()) : null;
if (pos != null)
for (Watch w : watches) {
List<String> pos = w.getPartOfState() != null ? new ArrayList<String>(
w.getPartOfState()) : null;
if (pos != null) {
Collections.sort(pos);
}
String key = String.valueOf(w.getPhenSig())
+ String.valueOf(w.getEtn()) + String.valueOf(w.getState())
+ String.valueOf(pos) + String.valueOf(w.getEndTime());
@ -540,9 +553,10 @@ public class WatchUtil {
return affectedPortions;
}
private List<Watch> generateMarineWatchItems(Watch template, List<String> areas) {
private List<Watch> generateMarineWatchItems(Watch template,
List<String> areas) {
ArrayList<Watch> result = new ArrayList<Watch>();
for (String area: areas) {
for (String area : areas) {
Watch watch = new Watch(template.getState(), template.getPhenSig(),
template.getEtn(), template.getStartTime(),
template.getEndTime());
@ -553,7 +567,7 @@ public class WatchUtil {
}
private List<String> determineMarineAreas(List<String> areas) {
HashSet<Pair<Integer, String>> groupedAreas = new HashSet<Pair<Integer,String>>();
HashSet<Pair<Integer, String>> groupedAreas = new HashSet<Pair<Integer, String>>();
for (String area : areas) {
int entryIndex = 0;
for (MarineWordingEntry entry : marineWordingConfig.getEntries()) {
@ -573,9 +587,12 @@ public class WatchUtil {
entryIndex++;
}
}
ArrayList<Pair<Integer, String>> sorted = new ArrayList<Pair<Integer,String>>(groupedAreas);
ArrayList<Pair<Integer, String>> sorted = new ArrayList<Pair<Integer, String>>(
groupedAreas);
Collections.sort(sorted, new Comparator<Pair<Integer, String>>() {
public int compare(Pair<Integer, String> o1, Pair<Integer, String> o2) {
@Override
public int compare(Pair<Integer, String> o1,
Pair<Integer, String> o2) {
int r = o1.getFirst().compareTo(o2.getFirst());
return r != 0 ? r : o1.getSecond().compareTo(o2.getSecond());
};
@ -702,7 +719,7 @@ public class WatchUtil {
if (((nn > 0) && (ss > 0)) || ((ee > 0) && (ww > 0))) {
return abrev;
}
if (nnn + sss + eee + www == 3) {
if ((nnn + sss + eee + www) == 3) {
if (www == 0) {
abrev = "e";
} else if (eee == 0) {
@ -724,7 +741,7 @@ public class WatchUtil {
return abrev;
}
}
if (m == 1 + cc) {
if (m == (1 + cc)) {
abrev += partAbrev + " ";
return abrev;
}

View file

@ -0,0 +1,23 @@
#!/bin/sh
# sed/changeword
# changes one model to another model for SCANRunSiteConfig.xml files
#
files=$(find /awips2/edex/data/utility/common_static | grep SCANRunSiteConfig.xml)
echo "Updating all SCANRunSiteConfig.xml files to use HRRR instead of RUC130."
old=RUC130
new=HRRR
for f in $files
do
echo "Processing file: " $f
if test -f "$f"
then
sed "s/$old/$new/g" $f > $f.new
mv $f $f.orig
mv $f.new $f
rm $f.orig
echo $f done
fi
done

View file

@ -20,8 +20,10 @@
package com.raytheon.edex.plugin.gfe.config;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@ -56,6 +58,7 @@ import com.raytheon.uf.common.dataplugin.gfe.weather.WxDefinition;
* 06/24/13 #2044 randerso Renamed satdirs to satdata to match serverConfig.py
* 08/14/2013 #1571 randerso Changed to use ProjectionType enum
* 03/05/2015 #4169 randerso Changed model name mappings to return null if no mapping
* 04/09/2015 #4383 dgilling Support FireWx ISC.
*
* </pre>
*
@ -164,6 +167,8 @@ public class IFPServerConfig {
private long _protocolVersion = 20080905;
private Collection<ISCRoutingConfig> iscRoutingConfig;
private String convertToString(final DatabaseID id) {
return id.getModelId();
}
@ -194,6 +199,7 @@ public class IFPServerConfig {
_desiredDbVersions = new HashMap<String, Integer>();
_gridPurgeAge = new HashMap<String, Integer>();
_gridDbConfig = new HashMap<String, GridDbConfig>();
iscRoutingConfig = Collections.emptyList();
}
protected IFPServerConfig(final SimpleServerConfig config) {
@ -554,6 +560,8 @@ public class IFPServerConfig {
DatabaseID.NO_MODEL_TIME);
setDesiredDbVersions(dbid, versions);
}
iscRoutingConfig = config.iscRoutingConfig;
}
/**
@ -844,4 +852,12 @@ public class IFPServerConfig {
+ _officialDatabases + "\n" + "Sites: " + _siteID + "\n"
+ "TimeZones: " + _timeZones + "\n";
}
public Collection<String> alternateISCEditAreaMasks() {
Collection<String> retVal = new HashSet<>();
for (ISCRoutingConfig entry : iscRoutingConfig) {
retVal.add(entry.getEditAreaPrefix());
}
return retVal;
}
}

View file

@ -0,0 +1,69 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.gfe.config;
import java.util.Collection;
/**
* Routing configuration data objection for supplemental ISC databases. Allows
* the list of defined weather elements to be additional mosaicked into the
* specified database name using the specified edit area type.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 09, 2015 #4383 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public final class ISCRoutingConfig {
private final Collection<String> parmNames;
private final String dbName;
private final String editAreaPrefix;
public ISCRoutingConfig(Collection<String> parmNames, String dbName,
String editAreaPrefix) {
this.parmNames = parmNames;
this.dbName = dbName;
this.editAreaPrefix = editAreaPrefix;
}
public Collection<String> getParmNames() {
return parmNames;
}
public String getDbName() {
return dbName;
}
public String getEditAreaPrefix() {
return editAreaPrefix;
}
}

View file

@ -20,6 +20,7 @@
package com.raytheon.edex.plugin.gfe.config;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -34,6 +35,7 @@ import com.raytheon.uf.common.dataplugin.gfe.config.ProjectionData;
* ------------ ---------- ----------- --------------------------
* 03/13/08 #1030 randerso Initial port
* 06/24/13 #2044 randerso Renamed satdirs to satdata to match serverConfig.py
* 04/09/15 #4383 dgilling Added addedISCRoutingConfig.
*
* </pre>
*
@ -110,6 +112,8 @@ public class SimpleServerConfig {
public List<String> officeTypes;
public Collection<ISCRoutingConfig> iscRoutingConfig;
public SimpleServerConfig() {
allowedNodes = new ArrayList<String>();
rpcPort = 0;

View file

@ -32,6 +32,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@ -61,6 +62,7 @@ import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceData.CoordinateT
import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceID;
import com.raytheon.uf.common.dataplugin.gfe.sample.SampleData;
import com.raytheon.uf.common.dataplugin.gfe.sample.SampleId;
import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
@ -113,6 +115,8 @@ import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
* Oct 20, 2014 #3685 randerso Changed structure of editAreaAttrs to keep zones from different maps separated
* Feb 19, 2015 #4125 rjpeter Fix jaxb performance issue
* Apr 01, 2015 #4353 dgilling Improve logging of Geometry validation errors.
* Apr 08, 2015 #4383 dgilling Change ISC_Send_Area to be union of
* areas ISC_XXX and FireWxAOR_XXX.
*
* </pre>
*
@ -422,6 +426,7 @@ public class MapManager {
i++;
}
writeISCMarker();
writeSpecialISCEditAreas();
long t1 = System.currentTimeMillis();
statusHandler.info("EditArea generation time: " + (t1 - t0) + " ms");
@ -485,6 +490,65 @@ public class MapManager {
}
}
private void writeSpecialISCEditAreas() {
statusHandler.debug("Creating: ISC_Tool_Area and ISC_Send_Area.");
ReferenceMgr refDataMgr = new ReferenceMgr(_config);
String thisSite = _config.getSiteID().get(0);
List<ReferenceData> areas = new ArrayList<>();
List<String> editAreaNames = new ArrayList<>();
ReferenceData iscSendArea = null;
ReferenceID iscAreaName = new ReferenceID("ISC_" + thisSite);
ServerResponse<List<ReferenceData>> sr = refDataMgr.getData(Arrays
.asList(iscAreaName));
if (sr.isOkay()) {
iscSendArea = new ReferenceData(sr.getPayload().get(0));
iscSendArea.setId(new ReferenceID("ISC_Send_Area"));
areas.add(iscSendArea);
editAreaNames.add(iscSendArea.getId().getName());
ReferenceData toolArea = createSwathArea("ISC_Tool_Area",
iscSendArea, 4);
if (toolArea != null) {
areas.add(toolArea);
editAreaNames.add(toolArea.getId().getName());
}
} else {
String errorMsg = String.format(
"Could not retrieve ISC edit area for site %s: %s",
thisSite, sr.message());
statusHandler.error(errorMsg);
return;
}
Collection<String> altISCEditAreas = _config
.alternateISCEditAreaMasks();
for (String altISCEditArea : altISCEditAreas) {
ReferenceID editAreaName = new ReferenceID(altISCEditArea
+ thisSite);
sr = refDataMgr.getData(Arrays.asList(editAreaName));
if (sr.isOkay()) {
ReferenceData refData = sr.getPayload().get(0);
iscSendArea.orEquals(refData);
} else {
String errorMsg = String
.format("Could not retrieve additional ISC edit area %s for site %s: %s. It will not be included in ISC_Send_Area defintion.",
editAreaName.getName(), thisSite, sr.message());
statusHandler.warn(errorMsg);
}
}
ReferenceData swath = createSwathArea("ISC_Swath", iscSendArea, 4);
if (swath != null) {
iscSendArea.orEquals(swath);
}
saveEditAreas(areas);
saveGroupList("ISC", editAreaNames);
}
/**
* Based on the supplied map configuration, creates edit areas, saves them,
* and updates group names. Handles special creation for ISC edit areas,
@ -522,36 +586,10 @@ public class MapManager {
List<String> knownSites = _config.allSites();
boolean anySites = false;
if (groupName.equals("ISC")) {
String thisSite = _config.getSiteID().get(0);
for (int i = 0; i < data.size(); i++) {
String n = data.get(i).getId().getName();
if ((n.length() == 7) && n.startsWith("ISC_")) {
String cwa = n.substring(4, 7);
if (cwa.equals(thisSite)) {
statusHandler
.debug("creating: ISC_Tool_Area and ISC_Send_Area"
+ " from "
+ data.get(i).getId().getName());
List<ReferenceData> areas = new ArrayList<ReferenceData>();
ReferenceData swath = createSwathArea(
"ISC_Tool_Area", data.get(i), 4);
if (swath != null) {
areas.add(swath);
list.add(swath.getId().getName());
}
ReferenceData extend = new ReferenceData(
data.get(i));
extend.setId(new ReferenceID("ISC_Send_Area"));
if (swath != null) {
extend.orEquals(swath);
}
areas.add(extend);
list.add(extend.getId().getName());
saveEditAreas(areas);
}
// Need some special sample sets for ISC
// Create ISC_Marker_Set if any CWA, use ISC_cwa areas

View file

@ -29,10 +29,13 @@ import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceData;
import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceID;
import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.LocalizationUtil;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.localization.region.RegionLookup;
import com.raytheon.uf.common.serialization.SingleTypeJAXBManager;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
@ -52,6 +55,9 @@ import com.raytheon.uf.common.util.FileUtil;
* Sep 30, 2013 2361 njensen Use JAXBManager for XML
* Sep 08, 2104 3592 randerso Changed to use new pm listStaticFiles()
* Feb 19, 2015 4125 rjpeter Fix jaxb performance issue
* Apr 10, 2015 4383 dgilling Fix getData so it searches correct localization
* directories for secondary sites.
*
* </pre>
*
* @author dgilling
@ -82,9 +88,8 @@ public class ReferenceMgr {
*/
public ServerResponse<List<ReferenceID>> getInventory() {
List<ReferenceID> refIDs = new ArrayList<ReferenceID>();
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationFile[] contents = pm.listStaticFiles(
LocalizationType.COMMON_STATIC, EDIT_AREAS_DIR,
LocalizationFile[] contents = pathMgr.listStaticFiles(
getSiteSearchContexts(), EDIT_AREAS_DIR,
new String[] { ".xml" }, false, true);
if (contents != null) {
for (LocalizationFile lf : contents) {
@ -121,7 +126,7 @@ public class ReferenceMgr {
for (ReferenceID id : ids) {
String path = FileUtil.join(EDIT_AREAS_DIR, id.getName() + ".xml");
LocalizationFile lf = pathMgr.getStaticLocalizationFile(
LocalizationType.COMMON_STATIC, path);
getSiteSearchContexts(), path);
// does it exist?
if (lf == null) {
@ -167,4 +172,38 @@ public class ReferenceMgr {
public String toString() {
return "ReferenceMgr [" + dbGridLocation.getSiteId() + "]";
}
private LocalizationContext[] getSiteSearchContexts() {
String siteId = dbGridLocation.getSiteId();
/*
* regionName could be returned as null, and if so, we will not add it
* to the final list of LocalizationContexts.
*/
String regionName = RegionLookup.getWfoRegion(siteId);
LocalizationContext[] searchContexts = pathMgr
.getLocalSearchHierarchy(LocalizationType.COMMON_STATIC);
List<LocalizationContext> fixedContexts = new ArrayList<>(
searchContexts.length);
for (LocalizationContext ctx : searchContexts) {
if (((ctx.getLocalizationLevel().equals(LocalizationLevel.SITE)) || (ctx
.getLocalizationLevel()
.equals(LocalizationLevel.CONFIGURED)))
&& (!ctx.getContextName().equals(siteId))) {
ctx.setContextName(siteId);
} else if (ctx.getLocalizationLevel().equals(
LocalizationLevel.REGION)) {
if (regionName == null) {
continue;
} else if (!ctx.getContextName().equals(regionName)) {
ctx.setContextName(regionName);
}
}
fixedContexts.add(ctx);
}
return fixedContexts.toArray(new LocalizationContext[fixedContexts
.size()]);
}
}

View file

@ -35,17 +35,16 @@ class TextProduct(MultipleElementTable.TextProduct):
Definition = copy.deepcopy(MultipleElementTable.TextProduct.Definition)
Definition["displayName"] = "MultipleElementTable"
Definition["database"] = "Official"
#Definition["outputFile"] = "/awips/GFESuite/products/TEXT/MultipleElementTable.txt"
#Definition["defaultEditAreas"] = [
#Definition["regionList"] = [
# ("area1","AREA 1"),
# ("area2","AREA 2"),
# ("area3","AREA 3"),
# ]
# ],
#Definition["regionList"] = [
# ("/33",["AREA 1","AREA 2"]),
# ("/19",["AREA 3"])
# ]
# ],
#Definition["elementList"] = ["Temp", "PoP"] # Default
#Definition["elementList"] = ["Temp", "Humidity"]

View file

@ -1,206 +0,0 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
########################################################################
# RDFcst
#
########################################################################
## EXAMPLE OUTPUT:
##
## 24 Hour Tabular Forecast for Boulder for 12 AM MST Mar 21 TO 12 PM MST Mar 21.
##
## Weather Element 12 AM 3 AM 6 AM 9 AM
##
## Temperature 30 28 29
## Dew Point 25 23 25
## Wind (mph) NW 4 NW 5 NW 6
## Sky Cover(%) MOSTLY MOSTLY MOSTLY
## CLOUDY CLOUDY CLOUDY
## Rainfall Amount(in.) 0.00 0.00 0.00 0.00
## Weather RAIN RAIN
## Snowfall(in.) 0 0 0 0
##
## This forecast was generated from a gridded database.
# Forecast Definition
RDFcst = {
## General Set-Up
"type": "table",
"displayName": "RDFcst", # for Product Generation Menu
"database": "Official",
# Output file for product results
"outputFile": "/home/ifp/release/products/TEXT/RDFcst.txt", # default output file
"runTimeOutputFile": "no", # If yes, ask user at run time
# Language
"language": "english", # default
"runTimeLanguage": "no", # If yes, ask user at run time
# Line Length for resulting Product
"lineLength": 79, # default
"runTimeLineLength": "no", # If yes, ask user at run time
# Text to preceed and follow the text product.
# Remember to add spacing lines backslash n.
# The variables: %TimePeriod, %EditArea, and %WeatherElement
# can be included to be filled in with constant variables.
# For phrase and combo, only %EditArea and %TimePeriod
# can be filled in.
"timePeriodMethod": "localTRLabel", ## localRangeLabel
"editAreaLoopBegText": "24 Hour Tabular Forecast for %EditArea for %TimePeriod. \n\n",
"editAreaLoopEndText": "\n",
"endingText": "\nThis forecast was generated from a gridded database.\n\n\n",
## Table Layout
# A table is a combination of three variables:
# edit areas, weather elements, and time periods
# One of these variables is held constant,
# one is assigned to rows and the other to columns.
"constantVariable": "EditArea", ## "TimePeriod",
"rowVariable": "WeatherElement", ## "EditArea",
"columnVariable": "TimePeriod", ## "WeatherElement",
"columnJustification":"Right",
## Edit Areas
# If the edit area is the constant variable, specify
# one area and whether to ask user at run time.
# runTimeEditArea can be a list of areas and/or edit area
# groups (groups will be expanded into areas) from which
# the user will be able to choose.
"defaultEditAreas": [
("area1", "Area1"),
("area2", "Area2"),
("area3", "Area3"),
("area4", "Area4")],
"runTimeEditAreas": "yes",
"areaType" : "Edit Area", # E.g. City, County, Basin, etc.
# Time Ranges
"defaultRanges": ["Today"],
"runTimeRanges" : "no", # if yes, ask user at run time
## Weather Elements
# elementList: List of Weather Element tuples:
# Weather Element Name
# Weather Element Label
# If you want the label to appear on multiple lines,
# use vertical bars as separators e.g. Maximum|Temperature
# Analysis method -- Method to produce statistics from the data
# ReportAs Method -- Method to format the analyzed value(s)
# DataType: Scalar or Vector or Weather
# Rounding increment e.g. 5 = round final value to
# nearest multiple of 5
# Conversion method
# e.g. "mphToKt" converts from mph to knots
#
# If the weather element is the constant variable, only one
# should be given.
# Name , Label , Analysis Method , ReportAs Method ,
# DataType , Rounding , Conversion
"elementList": [
("T","Temperature",
"avg",
"singleValue",
"Scalar", 1, None),
("Td","Dew Point",
"avg",
"singleValue",
"Scalar", 1, None),
("RH","Relative Humidity(%)",
"avg",
"singleValue",
"Scalar", 1, None),
("WindChill","Wind Chill(F)",
"avg",
"singleValue",
"Scalar", 1, None),
("Wind","Wind (mph)",
"vectorRange",
"avgValue",
"Vector", 1, "ktToMph"),
("Sky","Sky Cover(%)",
"avg",
"cloudCover",
"Scalar", 5, None),
("QPF","Rainfall Amount(in.)",
"avg",
"singleValue",
"Scalar", .01, None),
("Wx","Weather ",
"dominantWx",
"short_weather_phrase",
"Scalar", 1, None),
("SnowAmt","Snowfall(in.)",
"avg",
"singleValue",
"Scalar", 1, None),
("PoP", "Precip (%)",
"avg",
"singleValue",
"Scalar", 1, None),
],
## Time Period (If rows or columns vary with TimePeriod
# timePeriod: This is the interval in hours for sampling the data
# e.g. every 3 hours.
# (Can be floating point e.g. 1.5 hour TimePeriods)
"timePeriod": 3,
# timeSpan: This is the amount of data to sample at each
# interval.
# If you want the data analyzed (e.g averaged) over the
# entire period, the timeSpan should be set to "timePeriod".
# If you only want data for the beginning of each timePeriod,
# the timeSpan should be set to number of hours over which
# to analyze the data e.g. 1 hour
"timeSpan": 1,
"runTimePeriod": "no", # If yes, ask user at run time for period
# Method to label periods given a time range
# periodLabel -- GMT time hourZ/day e.g. 15Z/4
# localTimeLabel -- local time e.g. 6 AM
# localRangeLabel -- local time range e.g. 6AM-9AM
"periodLabelMethod": "localTimeLabel",
## User-supplied Methods
# loopMethod: Method to be called for each row.
# Such a method might keep ongoing statistics about table data.
# Arguments: (rowLabel, rowEntries, userDict, argDict)
# Returns: nothing
# "rowEntries" is a list of (colValue, value) tuples
# describing the entries in this row.
# "userDict" is a dictionary set up for user-defined
# callback methods so they can keep ongoing data as
# the table is being produced.
# It is not modified by the TextFormatter code.
"loopMethod": None,
# endMethod: Method to be called after table is complete.
# Arguments: (table, userDict, argDict)
# Returns: table (could be modified)
# The table can be modified to report summary statistics
# gathered in userDict.
#
"endMethod": None,
}

View file

@ -1,311 +0,0 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
#-------------------------------------------------------------------------
# Description: This product creates a Smart Element Table.
# The possible elements are Temperature (MaxT, MinT), Humidity (MinRH, MaxRH), and PoP
#-------------------------------------------------------------------------
# Copying:
# This software is in the public domain, furnished "as is", without technical
# support, and with no warranty, express or implied, as to its usefulness for
# any purpose.
#-------------------------------------------------------------------------
# Standard and Local file names and Locations:
# MultipleElementTableTable, MultipleElementTable_Local, MultipleElementTable_Aux_Local
#-------------------------------------------------------------------------
# User Configurable Variables:
#-------------------------------------------------------------------------
# Weather Elements Needed:
#-------------------------------------------------------------------------
# Edit Areas Needed:
#-------------------------------------------------------------------------
# Associated Utilities Files e.g. Combinations file:
#-------------------------------------------------------------------------
# Component Products:
#-------------------------------------------------------------------------
# Programmers and Support including product team leader's email:
#-------------------------------------------------------------------------
# Development tasks that are identified and in progress:
#-------------------------------------------------------------------------
# Additional Information:
#-------------------------------------------------------------------------
import TextRules
import SampleAnalysis
import string, time, types
class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
VariableList = [
("Forecast Product" , "Morning", "radio",
["Morning","Afternoon"]),
]
Definition = {
"type": "smart",
"displayName": "None",
"database": "Official",
"outputFile": "/awips/GFESuite/products/TEXT/SmartElementTable.txt",
"defaultEditAreas": [
("area1","AREA 1"),
("area2","AREA 2"),
("area3","AREA 3"),
],
# Product-specific variables
"regionList" : [
("/33",["AREA 1","AREA 2"]),
("/19",["AREA 3"])
],
# Possible elements are:
# "Temp" -- lists MaxT for daytime, MinT for nighttime
# "PoP"
# "Humidity" -- lists MinRH for daytime, MaxRH for nighttime
"elementList" : ["Temp", "PoP"],
# If set to 1, only one value for each element is listed
"includeTitle": 1,
"introLetters": ".<",
}
def __init__(self):
TextRules.TextRules.__init__(self)
SampleAnalysis.SampleAnalysis.__init__(self)
def generateForecast(self, argDict):
# Generate formatted product for a list of edit areas
# Get variables from varDict and Definition
self._getVariables(argDict)
# Get the areaList -- derived from defaultEditAreas and
# may be solicited at run-time from the user if desired
self._areaList = self.getAreaList(argDict)
# Determine time ranges for which the data will be sampled
self._determineTimeRanges(argDict)
# Sample the data
self._sampleData(argDict)
# Initialize the output string
fcst = ""
fcst = self._preProcessProduct(fcst, argDict)
# Generate the product for each edit area in the list
for editArea, areaLabel in self._areaList:
fcst = self._preProcessArea(fcst, editArea, areaLabel, argDict)
fcst = self._makeProduct(fcst, editArea, areaLabel, argDict)
fcst = self._postProcessArea(fcst, editArea, areaLabel, argDict)
fcst = self._postProcessProduct(fcst, argDict)
return fcst
def _getVariables(self, argDict):
# Determine whether Morning or Afternoon product type
varDict = argDict["varDict"]
self._productType = varDict["Forecast Product"]
# Make argDict accessible
self.__argDict = argDict
# Set up any other product-specific variables from the Definition
self._definition = argDict["forecastDef"]
for key in self._definition.keys():
exec "self._" + key + "= self._definition[key]"
self._currentRegion = None
# The analysisList tells which weather elements and statistics
# are desired for the product.
self._analysisList = self._getAnalysisList()
def _determineTimeRanges(self, argDict):
# Determine time ranges for product
# Sets up self._timeRangeList
if self._productType == "Morning":
timeRange = self.getTimeRange("Today", argDict)
numPeriods = 3
else:
timeRange = self.getTimeRange("Tonight", argDict)
numPeriods = 4
self._timeRangeList = self.getPeriods(timeRange, 12, 12, numPeriods)
return
def _sampleData(self, argDict):
# Sample the data
self._sampler = self.getSampler(argDict,
(self._analysisList, self._timeRangeList, self._areaList))
return
def _preProcessProduct(self, fcst, argDict):
# Set up format spacing and title line spacing
numElements = len(self._elementList)
if numElements > 2:
self._spaceStr = ""
else:
self._spaceStr = " "
if self._includeTitle == 0:
return fcst
self._titles = self._titleDict()
if numElements > 2:
if self._productType == "Morning":
self._headingLen = 15
else:
self._headingLen = 19
else:
if self._productType == "Morning":
self._headingLen = 21
else:
self._headingLen = 28
# Create title line
title = self._introLetters + " "
index = 0
for element in self._elementList:
title = title + string.center(
self._titles[element], self._headingLen)
if index < len(self._elementList)-1:
title = title + "/"
index += 1
return fcst + title + "\n"
def _preProcessArea(self, fcst, editArea, areaLabel, argDict):
# If we are in a new region, add region header
for region, areaList in self._regionList:
if areaLabel in areaList:
break
if region != self._currentRegion:
if self._currentRegion is not None:
# End the Region
fcst = fcst + "\n$$\n\n"
self._currentRegion = region
fcst = fcst + region
return fcst + "\n" + string.ljust(areaLabel, 10)
def _makeProduct(self, fcst, editArea, areaLabel, argDict):
# Get the Statistics
statList = self.getStatList(self._sampler, self._analysisList,
self._timeRangeList, editArea)
numElements = len(self._elementList)
index = 0
for element in self._elementList:
exec "fcst = fcst + self._get" + element + \
"Values(statList, argDict)"
if index < numElements-1:
fcst = fcst + " /"
index += 1
return fcst
def _postProcessArea(self, fcst, editArea, areaLabel, argDict):
return fcst
def _postProcessProduct(self, fcst, argDict):
fcst = fcst + "\n"
return fcst
########################################################################
# PRODUCT-SPECIFIC METHODS
########################################################################
def _getAnalysisList(self):
return [
("MinT", self.avg),
("MaxT", self.avg),
("MinRH", self.avg),
("MaxRH", self.avg),
("PoP", self.stdDevMaxAvg),
]
def _titleDict(self):
return {
"Temp": "TEMPERATURE",
"PoP": "PRECIPITATION",
"Humidity":"HUMIDITY",
}
def _getTempValues(self, statList, argDict):
# Return a string of Temperature values given statList
stats1 = statList[0]
if self._productType == "Morning":
stats2 = statList[1]
stats3 = statList[2]
t1 = self.getScalarVal(stats1["MaxT"])
t2 = self.getScalarVal(stats2["MinT"])
t3 = self.getScalarVal(stats3["MaxT"])
str = " " + t1+ self._spaceStr +t2+ self._spaceStr +t3
return str
else:
stats2 = statList[1]
stats3 = statList[2]
stats4 = statList[3]
t1 = self.getScalarVal(stats1["MinT"])
t2 = self.getScalarVal(stats2["MaxT"])
t3 = self.getScalarVal(stats3["MinT"])
t4 = self.getScalarVal(stats4["MaxT"])
str = " " +t1+ self._spaceStr +t2+ self._spaceStr +t3+ \
self._spaceStr+t4
return str
def _getHumidityValues(self, statList, argDict):
# Return a string of Humidity values given statList
stats1 = statList[0]
if self._productType == "Morning":
stats2 = statList[1]
stats3 = statList[2]
t1 = self.getScalarVal(stats1["MinRH"])
t2 = self.getScalarVal(stats2["MaxRH"])
t3 = self.getScalarVal(stats3["MinRH"])
return " " +t1+ self._spaceStr +t2+ self._spaceStr+t3
else:
stats2 = statList[1]
stats3 = statList[2]
stats4 = statList[3]
t1 = self.getScalarVal(stats1["MaxRH"])
t2 = self.getScalarVal(stats2["MinRH"])
t3 = self.getScalarVal(stats3["MaxRH"])
t4 = self.getScalarVal(stats4["MinRH"])
return " " +t1+ self._spaceStr +t2+ self._spaceStr +t3+ self._spaceStr +t4
def _getPoPValues(self, statList, argDict):
# Return a string of PoP values in the statList
pop = []
popStr = ""
index = 0
for stats in statList:
val = self._getPoPValue(stats)
if index < len(statList)-1:
popStr = popStr + val + self._spaceStr
else:
popStr = popStr + val
index += 1
popStr = popStr + " "
return popStr
def _getPoPValue(self, stats):
pop = self.getStats(stats,"PoP")
if pop is None:
val = " "
else:
max = self.round(pop, "Nearest", 10)
val = self.getScalarVal(max)
return val

View file

@ -1,59 +0,0 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
########################################################################
# SmartElementTable_Local
#
# Type: smart
# Local product:
# SmartElementTable_Local(type: smart)
# To customize this product for your site:
# Set up SmartElementTable_Local (see template below)
# to override variables, definitions, thresholds, and methods
##
##########################################################################
import SmartElementTable
import string, time, re, os, types, copy
class TextProduct(SmartElementTable.TextProduct):
Definition = copy.deepcopy(SmartElementTable.TextProduct.Definition)
Definition["displayName"] = "TEST_SmartElementTable"
#Definition["outputFile"] = "/awips/GFESuite/products/TEXT/SmartElementTable.txt"
#Definition["defaultEditAreas"] = [
# ("area1","AREA 1"),
# ("area2","AREA 2"),
# ("area3","AREA 3"),
# ]
#Definition["regionList"] = [
# ("/33",["AREA 1","AREA 2"]),
# ("/19",["AREA 3"])
# ]
#Definition["elementList"] = ["Temp", "PoP"] # Default
#Definition["elementList"] = ["Temp", "Humidity"]
#Definition["elementList"] = ["Temp", "Humidity", "PoP"]
#Definition["elementList"] = ["Temp", "PoP", "Humidity"]
#Definition["elementList"] = ["PoP", "Humidity", "Temp"]
#Definition["introLetters"] = ".<"
def __init__(self):
SmartElementTable.TextProduct.__init__(self)

View file

@ -33,6 +33,7 @@
# 07/09/2014 #3146 randerso Added check for duplicate smartInit
# rferrel Corrected log to alertviz.
# 11/18/2014 #4953 randerso Added check for empty unit string
# 04/09/2015 #4383 dgilling Added support for FireWx ISC.
#
########################################################################
import types
@ -521,3 +522,22 @@ def otherParse(serverhost, mhsid, port,
autoConfigureNotifyTextProd, \
iscRoutingTableAddress, reqISCsites, requestISC, sendiscOnSave, \
sendiscOnPublish, reqISCparms, transmitScript
def parseAdditionalISCRouting(iscRoutingData):
from com.raytheon.edex.plugin.gfe.config import ISCRoutingConfig
retVal = ArrayList()
if iscRoutingData:
try:
iter(iscRoutingData)
except TypeError:
raise TypeError("AdditionalISCRouting should be a list or tuple.")
for entry in iscRoutingData:
(pyParms, dbName, editAreaPrefix) = check(entry, (list, str, str), "AdditionalISCRouting entry not in correct format.")
javaParms = ArrayList()
for parm in pyParms:
javaParms.add(str(parm[0]))
retVal.add(ISCRoutingConfig(javaParms, dbName, editAreaPrefix))
return retVal

View file

@ -55,9 +55,11 @@
# 02/24/2015 #16692 byin Added RTMA. Removed gfsLR and GWW233
# 03/19/2015 #4300 randerso Remove GUMa as it is obsolete (per Shannon White)
# 03/30/2015 #17288 bhunder Added Guam-RTMA to D2D models
# 03/31/2015 #17288 bhunder Added Weather Params for RTMA
# 03/30/2015 #17206 yteng Changed some parameters that are not rate parameters
# 03/31/2015 #17288 bhunder Added Weather Params for RTMA
# 04/03/2015 #4367 dgilling Change WindGust's time constraints back to TC1
# 04/08/2015 #4383 dgilling Define FireWX ISC configuration parameters.
#
# for Fcst/Official.
#
########################################################################
@ -994,8 +996,8 @@ def localTC(start,repeat,duration,dst):
timezone = SITES[GFESUITE_SITEID][3]
import dateutil.tz, datetime
tz = dateutil.tz.gettz(timezone)
dt = datetime.datetime.utcnow()
delta = tz.utcoffset(dt) + tz.dst(dt)
local = datetime.datetime.now(tz)
delta = tz.utcoffset(local) - tz.dst(local)
offset = delta.days*86400 + delta.seconds
start = start - offset
if dst == 1:
@ -1817,6 +1819,13 @@ localISCExtraParms = []
myOfficeType = SITES[GFESUITE_SITEID][5]
AdditionalISCRouting = [
# Configure by adding entries to this list in the form of:
# ([WeatherElements], ModelName, EditAreaPrefix)
# Example:
# ([Hazards, LAL, CWR], "ISCFire", "FireWxAOR_"),
]
if not BASELINE and siteImport('localConfig'):
#ensure office type is set properly in localConfig SITES[]
if len(SITES[GFESUITE_SITEID]) == 5:
@ -2192,6 +2201,14 @@ ISCPARMS.append(([Topo], Persistent))
DATABASES.append((Restore, RESTOREPARMS))
DATABASES.append((ISC, ISCPARMS))
for entry in AdditionalISCRouting:
(parmList, dbName, editAreaPrefix) = entry
parmList = list(parmList)
addedIscDbDefinition = (dbName, ) + ISC[1:]
addedIscParms = [(parmList, TC1)]
DATABASES.append((addedIscDbDefinition, addedIscParms))
#---------------------------------------------------------------------------
#
# General server configuration section
@ -2272,5 +2289,6 @@ def doIt():
IFPConfigServer.sendiscOnPublish = sendiscOnPublish
IFPConfigServer.requestedISCparms = requestedISCparms
IFPConfigServer.transmitScript = transmitScript
IFPConfigServer.iscRoutingConfig = doConfig.parseAdditionalISCRouting(AdditionalISCRouting)
doIt()

View file

@ -390,17 +390,17 @@ def createTCVAreaDictionary(outputDir, mapDict, siteID):
# # "We ended the other list and are back at tab level 0 now",
# # ]
# 'infoSection': [
# "LOCAL EVACUATION AND SHELTERING: MIAMI-DADE COUNTY EMERGENCY MANAGEMENT",
# "Local evacuation and sheltering: Miami-Dade County Emergency Management",
# [
# "HTTP://WWW.MIAMIDADE.GOV/EMERGENCY/",
# "http://www.miamidade.gov/emergency/",
# ],
# "FAMILY EMERGENCY PLANS: FEDERAL EMERGENCY MANAGEMENT AGENCY",
# "Family emergency plans: Federal Emergency Management Agency",
# [
# "HTTP://READY.GOV/",
# "http://ready.gov/",
# ],
# "LOCAL WEATHER CONDITIONS AND FORECASTS: NWS MIAMI FLORIDA",
# "Local weather conditions and forecasts: NWS Miami Florida",
# [
# "HTTP://WWW.SRH.NOAA.GOV/MFL/",
# "http://www.srh.noaa.gov/mfl/",
# ],
# ],
# },

View file

@ -22,7 +22,7 @@
##
import iscMosaic,iscUtil
import os, stat, sys, re, string, traceback, types
import os, stat, sys, re, string, types
import time, xml, LogStream, IrtAccess
import IrtServer
from xml.etree import ElementTree
@ -45,6 +45,8 @@ from java.util import ArrayList
# 01/24/14 2504 randerso removed obsolete A1 comments
# 12/08/2014 4953 randerso Added support for sending/receiving TCV files
# Additional code cleanup
# 04/08/2015 4383 dgilling Support FireWx ISC.
# 04/23/2015 4383 randerso Fixed exception logging
#
##
@ -77,7 +79,7 @@ def purgeFiles(msgid, files):
try:
os.remove(file)
except:
logEvent("iscDataRec Failed to remove: ",file)
logException("iscDataRec Failed to remove file %s: ", str(file))
def execIscDataRec(MSGID,SUBJECT,FILES):
@ -108,7 +110,7 @@ def execIscDataRec(MSGID,SUBJECT,FILES):
destTree = ElementTree.ElementTree(ElementTree.XML(xmlFileBuf))
iscE = destTree.getroot()
except:
logProblem("Malformed XML received")
logException("Malformed XML received")
return
#no XML destination information. Default to dx4f,px3 98000000, 98000001
@ -198,29 +200,12 @@ def execIscDataRec(MSGID,SUBJECT,FILES):
elif SUBJECT == 'GET_ACTIVE_TABLE2':
IrtServer.getVTECActiveTable(dataFile, xmlFileBuf)
elif SUBJECT in ['ISCGRIDS', 'ISCGRIDS2']:
args = {"siteID": siteConfig.GFESUITE_SITEID,
"userID": 'SITE',
"databaseID": siteConfig.GFESUITE_SITEID+"_GRID__ISC_00000000_0000",
"parmsToProcess": [],
"blankOtherPeriods": True,
"startTime": None,
"endTime": None,
"altMask": None,
"replaceOnly": False,
"eraseFirst": False,
"announce": "ISC: ",
"renameWE": True,
"iscSends": False,
"inFiles": [dataFile],
"ignoreMask": False,
"adjustTranslate": True,
"deleteInput": True,
"parmsToIgnore": [],
"gridDelay": 0.0,
"logFileName": None}
mosaic = iscMosaic.IscMosaic(args)
mosaic.execute()
import localConfig
additionalISCRouting = []
if localConfig.AdditionalISCRouting:
additionalISCRouting = localConfig.AdditionalISCRouting
putISCGrids(dataFile, siteConfig.GFESUITE_SITEID, srcServer.get('site'), additionalISCRouting)
elif SUBJECT == 'ISCREQUEST':
IrtServer.serviceISCRequest(dataFile)
elif SUBJECT == 'PUT_TCV_FILES':
@ -236,11 +221,48 @@ def execIscDataRec(MSGID,SUBJECT,FILES):
logEvent('Sent to:',
irt.printServerInfo(destServer), "connectT=", delta1, "xmtT=", delta2)
except:
logProblem("iscDataRec failed!",traceback.format_exc())
logException("iscDataRec failed!")
finally:
# cleanup
purgeFiles(MSGID, FILES)
def putISCGrids(dataFile, destSite, srcSite, additionalISCRouting):
# iscMosaic now executes multiple times--once for the primary ISC database,
# and once more for each additional ISC database defined in the localConfig
args = {"siteID": destSite,
"userID": 'SITE',
"databaseID": destSite+"_GRID__ISC_00000000_0000",
"parmsToProcess": [],
"blankOtherPeriods": True,
"startTime": None,
"endTime": None,
"altMask": None,
"replaceOnly": False,
"eraseFirst": False,
"announce": "ISC: ",
"renameWE": True,
"iscSends": False,
"inFiles": [dataFile],
"ignoreMask": False,
"adjustTranslate": True,
"deleteInput": False,
"parmsToIgnore": [],
"gridDelay": 0.0,
"logFileName": None}
mosaic = iscMosaic.IscMosaic(args)
mosaic.execute()
for entry in additionalISCRouting:
(parms, dbName, editAreaPrefix) = entry
parmNameList = [parm[0] + "_SFC" for parm in parms]
args['parmsToProcess'] = parmNameList
args['databaseID'] = destSite + "_GRID__" + dbName + "_00000000_0000"
args['altMask'] = editAreaPrefix + srcSite
mosaic = iscMosaic.IscMosaic(args)
mosaic.execute()
#--------------------------------------------------------------------
# Main Routine
#--------------------------------------------------------------------
@ -283,8 +305,8 @@ def main(argv):
execIscDataRec(MSGID,SUBJECT,FILES)
except:
logProblem('Failure:', traceback.format_exc())
logException('Failure:')
except:
logProblem("FAIL: ", traceback.format_exc())
logException("FAIL: ")

View file

@ -23,6 +23,7 @@
# ------------ ---------- ----------- --------------------------
# 02/17/2015 4139 randerso Replaced call to iscTime.timeFromComponents
# with call to calendar.timegm
# 04/23/2015 4383 randerso Changed to log arguments to aid in troubleshooting
##
@ -521,9 +522,9 @@ class IscMosaic:
self.__processTimePeriod = (startTime, endTime)
initLogger(self.__logFile)
logger.info("iscMosaic Starting args: %s", str(args))
def execute(self):
logger.info("iscMosaic Starting")
# get the WxDefinition and DiscreteDefinition
config = IFPServerConfigManager.getServerConfig(self.__mysite)

View file

@ -355,9 +355,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# set this variable to zero for proper labeling.
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
return 1
def gust_wind_difference_nlValue(self, tree, node):
@ -1162,7 +1162,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# Product header
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -1171,11 +1171,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# The following lines insert a statement
# at the top of the forecast that describes the time periods
@ -1404,7 +1405,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
for myTimeRange, label in myTimeRanges:
# Add it on to the header
if periodNum == numPeriods:
header = header + "AND "
header = header + "and "
header = header + label
periodNum = periodNum + 1

View file

@ -303,8 +303,10 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# Add product heading to fcst string
return fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n"
fcst = fcst + s.upper()
return fcst
def _preProcessArea(self, fcst, editArea, areaLabel, argDict):
return fcst + areaLabel + " "

View file

@ -802,7 +802,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -811,11 +811,13 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + self._Text1()
try:
text2 = self._Text2(argDict)
@ -831,7 +833,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
print "Generating Forecast for", areaLabel
areaHeader = self.makeAreaHeader(
argDict, areaLabel, self._issueTime, self._expireTime,
self._areaDictionary, self._defaultEditAreas)
self._areaDictionary, self._defaultEditAreas, upperCase=True)
fcst = fcst + areaHeader
# get the hazards text
@ -1125,14 +1127,14 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.
# Periods longer than that will always be split into day and night labels
# (e.g. SUNDAY THROUGH MONDAY NIGHT)
# (e.g. Sunday through Monday night)
compName = node.getComponentName()
if compName == "CWFExtended":
return 0

View file

@ -417,7 +417,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def combinedSeas_threshold(self, tree, node):
# See wave_phrase
# If waves and swells are above this threshold,
# combined seas will be reported AND no Swell phrase will be reported.
# combined seas will be reported and no Swell phrase will be reported.
# Units: feet
return 7
@ -1105,7 +1105,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -1113,11 +1113,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + self._Text1()
try:
text2 = self._Text2(argDict)
@ -1131,7 +1132,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
print "Generating Forecast for", areaLabel
areaHeader = self.makeAreaHeader(
argDict, areaLabel, self._issueTime, self._expireTime,
self._areaDictionary, self._defaultEditAreas)
self._areaDictionary, self._defaultEditAreas, upperCase=True)
fcst = fcst + areaHeader
# get the hazards text
@ -1270,7 +1271,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
## # expirationHour -- hour when the product expires (in local time)
## # This is relitive to midnight local time of the
## # current day.
## # period1 Label -- the label for the first period. e.g. ".Today...", ".REST OF Today..."
## # period1 Label -- the label for the first period. e.g. ".Today...", ".Rest of Today..."
## # period1 lateNight phrase -- phrase to use if the hours of 3am to 6am must be qualified
## # e.g. "Partly cloudy in the early morning."
## # period1 lateDay phrase -- phrase to use if the hours of 3pm to 6pm must be qualified
@ -1314,9 +1315,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.

View file

@ -90,8 +90,8 @@ class TextProduct(CivilEmerg.TextProduct):
label, variable = key
exec "self._" + variable + "= varDict[key]"
fcst = fcst + "An earthquake has been felt " + self._felt + " BY " +\
self._extent + " " + "IN THE |*enter area*| AREA. " + \
fcst = fcst + "An earthquake has been felt " + self._felt + " by " +\
self._extent + " " + "in the |*enter area*| area. " + \
self._damage + " damage has been reported. "
if self._damage != "No":

View file

@ -851,7 +851,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# Product header
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -859,11 +859,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# Put in a place holder for the headlines to be substituted in
# "postProcessProduct"

View file

@ -627,7 +627,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# Add product heading to fcst string
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -635,11 +635,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weahter Service " + self._wfoCityState + \
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# Put in a place holder for the headlines to be substituted in
# "postProcessProduct"

View file

@ -267,8 +267,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# This is the header for the overall product
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n"
fcst = fcst + s.upper()
return fcst
def _preProcessArea(self, fcst, editArea, areaLabel, argDict):

View file

@ -431,46 +431,43 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
return 1
def marine_abbreviateText(self, fcst):
fcst = " " + fcst
fcst = re.sub(r'\n', r' ',fcst)
fcst = re.sub(r'(?i)(\W)NORTH(?!WARD|ERN|WESTWARD|EASTWARD|WESTERN|EASTERN)(\W)', r'\1N\2', fcst)
fcst = re.sub(r'(?i)(\W)SOUTH(?!WARD|ERN|WESTWARD|EASTWARD|WESTERN|EASTERN)(\W)', r'\1S\2', fcst)
fcst = re.sub(r'(?i)(\W)EAST(?!WARD|ERN)(\W)', r'\1E\2', fcst)
fcst = re.sub(r'(?i)(\W)WEST(?!WARD|ERN)(\W)', r'\1W\2', fcst)
fcst = re.sub(r'(?i)(\W)KNOTS?(\W)', r'\1KT\2', fcst)
fcst = re.sub(r'(?i)(\W)MILLIBARS?(\W)', r'\1MB\2', fcst)
fcst = re.sub(r'(?i)(\W)FATHOMS?(\W)', r'\1FM\2', fcst)
fcst = re.sub(r'(?i)(\W)NAUTICAL MILES?(\W)', r'\1NM\2', fcst)
fcst = re.sub(r'(?i)(\W)FOOT|FEET(\W)', r'\1FT\2', fcst)
fcst = re.sub(r'(?i)(\W)POSITION(\W)', r'\1PSN\2', fcst)
fcst = re.sub(r'(?i)(\W)VISIBILITY(\W)', r'\1VSBY\2', fcst)
fcst = re.sub(r'(?i)(\W)THUNDERSTORM(\W)', r'\1TSTM\2', fcst)
fcst = re.sub(r'(?i)(\W)AVERAGE(\W)', r'\1AVG\2', fcst)
fcst = re.sub(r'(?i)(\W)ATLANTIC(\W)', r'\1ATLC\2', fcst)
fcst = re.sub(r'(?i)(\W)LONGITUDE(\W)', r'\1LONG\2', fcst)
fcst = re.sub(r'(?i)(\W)PACIFIC(\W)', r'\1PAC\2', fcst)
fcst = re.sub(r'(?i)(\W)DEGREE(\W)', r'\1DEG\2', fcst)
fcst = re.sub(r'(?i)(\W)PRESSURE(\W)', r'\1PRES\2', fcst)
fcst = re.sub(r'(?i)(\W)SUNDAY(\W)', r'\1SUN\2', fcst)
fcst = re.sub(r'(?i)(\W)MONDAY(\W)', r'\1MON\2', fcst)
fcst = re.sub(r'(?i)(\W)TUESDAY(\W)', r'\1TUE\2', fcst)
fcst = re.sub(r'(?i)(\W)WEDNESDAY(\W)', r'\1WED\2', fcst)
fcst = re.sub(r'(?i)(\W)THURSDAY(\W)', r'\1THU\2', fcst)
fcst = re.sub(r'(?i)(\W)FRIDAY(\W)', r'\1FRI\2', fcst)
fcst = re.sub(r'(?i)(\W)SATURDAY(\W)', r'\1SAT\2', fcst)
fcst = re.sub(r'(?i)(\W)W HALF(\W)', r'\1WEST HALF\2', fcst)
fcst = re.sub(r'(?i)(\W)E HALF(\W)', r'\1EAST HALF\2', fcst)
fcst = re.sub(r'(?i)(\W)N HALF(\W)', r'\1NORTH HALF\2', fcst)
fcst = re.sub(r'(?i)(\W)S HALF(\W)', r'\1SOUTH HALF\2', fcst)
fcst = re.sub(r'(?i)(\W)W THIRD(\W)', r'\1WEST THIRD\2', fcst)
fcst = re.sub(r'(?i)(\W)E THIRD(\W)', r'\1EAST THIRD\2', fcst)
fcst = re.sub(r'(?i)(\W)N THIRD(\W)', r'\1NORTH THIRD\2', fcst)
fcst = re.sub(r'(?i)(\W)S THIRD(\W)', r'\1SOUTH THIRD\2', fcst)
fcst = re.sub(r'(?i)(\W)W TWO(\W)', r'\1WEST TWO\2', fcst)
fcst = re.sub(r'(?i)(\W)E TWO(\W)', r'\1EAST TWO\2', fcst)
fcst = re.sub(r'(?i)(\W)N TWO(\W)', r'\1NORTH TWO\2', fcst)
fcst = re.sub(r'(?i)(\W)S TWO(\W)', r'\1SOUTH TWO\2', fcst)
fcst = re.sub(r'^ ', r'',fcst)
fcst = re.sub(r'(?i)(\W|^)NORTH(?!WARD|ERN|WESTWARD|EASTWARD|WESTERN|EASTERN)(?=\W|$)', r'\1N', fcst)
fcst = re.sub(r'(?i)(\W|^)SOUTH(?!WARD|ERN|WESTWARD|EASTWARD|WESTERN|EASTERN)(?=\W|$)', r'\1S', fcst)
fcst = re.sub(r'(?i)(\W|^)EAST(?!WARD|ERN)(?=\W|$)', r'\1E', fcst)
fcst = re.sub(r'(?i)(\W|^)WEST(?!WARD|ERN)(?=\W|$)', r'\1W', fcst)
fcst = re.sub(r'(?i)(\W|^)KNOTS?(?=\W|$)', r'\1kt', fcst)
fcst = re.sub(r'(?i)(\W|^)MILLIBARS?(?=\W|$)', r'\1mb', fcst)
fcst = re.sub(r'(?i)(\W|^)FATHOMS?(?=\W|$)', r'\1fm', fcst)
fcst = re.sub(r'(?i)(\W|^)NAUTICAL MILES?(?=\W|$)', r'\1nm', fcst)
fcst = re.sub(r'(?i)(\W|^)(?:FOOT|FEET)(?=\W|$)', r'\1ft', fcst)
fcst = re.sub(r'(?i)(\W|^)POSITION(?=\W|$)', r'\1PSN', fcst)
fcst = re.sub(r'(?i)(\W|^)VISIBILITY(?=\W|$)', r'\1VSBY', fcst)
fcst = re.sub(r'(?i)(\W|^)THUNDERSTORM(?=\W|$)', r'\1TSTM', fcst)
fcst = re.sub(r'(?i)(\W|^)AVERAGE(?=\W|$)', r'\1AVG', fcst)
fcst = re.sub(r'(?i)(\W|^)ATLANTIC(?=\W|$)', r'\1ATLC', fcst)
fcst = re.sub(r'(?i)(\W|^)LONGITUDE(?=\W|$)', r'\1LONG', fcst)
fcst = re.sub(r'(?i)(\W|^)PACIFIC(?=\W|$)', r'\1PAC', fcst)
fcst = re.sub(r'(?i)(\W|^)DEGREE(?=\W|$)', r'\1deg', fcst)
fcst = re.sub(r'(?i)(\W|^)PRESSURE(?=\W|$)', r'\1PRES', fcst)
fcst = re.sub(r'(?i)(\W|^)SUNDAY(?=\W|$)', r'\1Sun', fcst)
fcst = re.sub(r'(?i)(\W|^)MONDAY(?=\W|$)', r'\1Mon', fcst)
fcst = re.sub(r'(?i)(\W|^)TUESDAY(?=\W|$)', r'\1Tue', fcst)
fcst = re.sub(r'(?i)(\W|^)WEDNESDAY(?=\W|$)', r'\1Wed', fcst)
fcst = re.sub(r'(?i)(\W|^)THURSDAY(?=\W|$)', r'\1Thu', fcst)
fcst = re.sub(r'(?i)(\W|^)FRIDAY(?=\W|$)', r'\1Fri', fcst)
fcst = re.sub(r'(?i)(\W|^)SATURDAY(?=\W|$)', r'\1Sat', fcst)
fcst = re.sub(r'(?i)(\W|^)W HALF(?=\W|$)', r'\1West half', fcst)
fcst = re.sub(r'(?i)(\W|^)E HALF(?=\W|$)', r'\1east half', fcst)
fcst = re.sub(r'(?i)(\W|^)N HALF(?=\W|$)', r'\1north half', fcst)
fcst = re.sub(r'(?i)(\W|^)S HALF(?=\W|$)', r'\1soutH half', fcst)
fcst = re.sub(r'(?i)(\W|^)W THIRD(?=\W|$)', r'\1west third', fcst)
fcst = re.sub(r'(?i)(\W|^)E THIRD(?=\W|$)', r'\1east third', fcst)
fcst = re.sub(r'(?i)(\W|^)N THIRD(?=\W|$)', r'\1north third', fcst)
fcst = re.sub(r'(?i)(\W|^)S THIRD(?=\W|$)', r'\1south third', fcst)
fcst = re.sub(r'(?i)(\W|^)W TWO(?=\W|$)', r'\1west two', fcst)
fcst = re.sub(r'(?i)(\W|^)E TWO(?=\W|$)', r'\1east two', fcst)
fcst = re.sub(r'(?i)(\W|^)N TWO(?=\W|$)', r'\1north two', fcst)
fcst = re.sub(r'(?i)(\W|^)S TWO(?=\W|$)', r'\1south two', fcst)
return fcst
def rounding_method_dict(self, tree, node):
@ -608,7 +605,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# Get the edit areas
try:
if self._groupings == "West 1/3:East 2/3":
if self._groupings == "West 1/3:east 2/3":
self._areaList = [("west_one_third", "WEST THIRD"),
("east_two_thirds", "EAST TWO THIRDS")]
elif self._groupings == "West 2/3:East 1/3":
@ -782,7 +779,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -790,13 +787,15 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + '\n' + \
self._lakezone + "-" + self._expireTimeDDHHMM + "-\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n" + \
self._headerphrase + "\n\n" + ".SYNOPSIS..." + "\n\n"
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + self._headerphrase + "\n\n" + ".SYNOPSIS..." + "\n\n"
# Set up hazards
self.getHazards(argDict, self._areaList)
@ -855,12 +854,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# Adjust some phrases to local requirements
# ========================================
fcst = string.replace(fcst,"WIDESPREAD RAIN", "OCCASIONAL RAIN")
fcst = string.replace(fcst,"WIDESPREAD SHOWERS", "SHOWERS")
fcst = string.replace(fcst,"WIDESPREAD THUNDERSTORMS", "THUNDERSTORMS")
fcst = string.replace(fcst,"widespread rain", "occasional rain")
fcst = string.replace(fcst,"widespread showers", "showers")
fcst = string.replace(fcst,"widespread thunderstorms", "thunderstorms")
fcst = string.replace(fcst, "RAIN SHOWERS", "SHOWERS")
fcst = string.replace(fcst, "THUNDERSTORMS AND SHOWERS", "SHOWERS AND THUNDERSTORMS")
fcst = string.replace(fcst, "rain showers", "showers")
fcst = string.replace(fcst, "thunderstorms and showers", "showers and thunderstorms")
#phrase = string.replace(phrase, "widespread", "")
# This is the footer for an edit area combination
@ -870,9 +869,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
fcst = fcst + "$$\n\n"
if string.find(fcst, "STORM FORCE") > 0 or\
string.find(fcst, "STORM WARNING") > 0 or\
string.find(fcst, "HURRICANE") > 0:
if string.find(fcst, "storm force") > 0 or\
string.find(fcst, "storm warning") > 0 or\
string.find(fcst, "hurricane") > 0:
fcst = fcst + "&&STORM\n\n"
if self._processmafor == 1:
@ -965,9 +964,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.

View file

@ -273,7 +273,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
def _preProcessProduct(self, fcst, argDict):
# Product header
if self._areaName != "":
self._areaName = " FOR " + self._areaName
self._areaName = " for " + self._areaName
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict,
self._productName + self._areaName)
@ -283,11 +283,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
else:
eas = ''
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
eas + productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + "Default overview section\n"
return fcst
@ -503,9 +504,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
continue #no defined headline, skip phrase
endTimePhrase = self.hazardTimePhrases(eachHazard, argDict)
hazNameA = self.hazardName(eachHazard['hdln'], argDict, True)
hazNameACap = self.sentence(hazNameA, addPeriod=False)
hazName = self.hazardName(eachHazard['hdln'], argDict, False)
# if hazName == "Winter Weather Advisory" or hazName == "Winter Storm Warning":
if hazName in ["Winter Weather Advisory", "Winter Storm Warning", "Beach Hazards Statement"]:
forPhrase = " for |* Enter hazard type *|"
else:
@ -527,18 +528,18 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
phraseCount = 2
if hdln != lastHdln:
if eachHazard['phen'] in ['HU', 'TR', 'TY']:
hazardBodyPhrase = hazardBodyPhrase + hazNameA + \
hazardBodyPhrase = hazardBodyPhrase + hazNameACap + \
" has also been issued."
else:
hazardBodyPhrase = hazardBodyPhrase + hazNameA + \
hazardBodyPhrase = hazardBodyPhrase + hazNameACap + \
" has also been issued. This " + hazName + forPhrase + \
" is in effect" + endTimePhrase + ". "
else:
if eachHazard['phen'] in ['HU', 'TR', 'TY']:
hazardBodyPhrase = hazardBodyPhrase + hazNameA + \
hazardBodyPhrase = hazardBodyPhrase + hazNameACap + \
" has also been issued."
else:
hazardBodyPhrase = hazardBodyPhrase + hazNameA + forPhrase + \
hazardBodyPhrase = hazardBodyPhrase + hazNameACap + forPhrase + \
" has also been issued" + endTimePhrase + ". "
else:
if eachHazard['phen'] in ['HU', 'TR', 'TY']:
@ -564,7 +565,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
hazardBodyPhrase = hazardBodyPhrase + \
" has cancelled the " + hazName + ". "
else:
hazardBodyPhrase = hazardBodyPhrase + "THE " + hazName + \
hazardBodyPhrase = hazardBodyPhrase + "The " + hazName + \
" has been cancelled. "
#
@ -579,13 +580,13 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
continue # No attribution for this case if it is a bullet product
hazName = self.hazardName(eachHazard['hdln'], argDict, False)
if eachHazard['endTime'] <= argDict['creationTime']:
hazardBodyPhrase = hazardBodyPhrase + "THE " + hazName + \
hazardBodyPhrase = hazardBodyPhrase + "The " + hazName + \
" is no longer in effect. "
else:
expTimeCurrent = argDict['creationTime']
timeWords = self.getTimingPhrase(eachHazard, expTimeCurrent)
hazardBodyPhrase = hazardBodyPhrase + "THE " + hazName + \
hazardBodyPhrase = hazardBodyPhrase + "The " + hazName + \
" will expire " + timeWords + ". "
#
@ -600,7 +601,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
endTimePhrase = self.hazardTimePhrases(eachHazard, argDict)
hazName = self.hazardName(eachHazard['hdln'], argDict, False)
hazardBodyPhrase = hazardBodyPhrase + "THE " + hazName + \
hazardBodyPhrase = hazardBodyPhrase + "The " + hazName + \
" is now in effect" + endTimePhrase + ". "
#
@ -611,7 +612,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
if len(eachHazard['hdln']) == 0:
continue #no defined headline, skip phrase
hazName = self.hazardName(eachHazard['hdln'], argDict, False)
hazardBodyPhrase = hazardBodyPhrase + "THE " + hazName + \
hazardBodyPhrase = hazardBodyPhrase + "The " + hazName + \
" is no longer in effect. "
#
@ -670,6 +671,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
startPara = 1
else:
startPara = 2
segmentText, foundCTAs = self.cleanCapturedText(prevText,
startPara, addFramingCodes = False,
skipCTAs = skipCTAs)

View file

@ -251,7 +251,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# Product header
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()

View file

@ -2120,10 +2120,10 @@ class TextProduct(HLSTCV_Common.TextProduct):
return direction
def _dirInEnglish(self, direction):
dirList = ["North", "North-Northeast", "Northeast", "East-Northeast",
"East", "East-Southeast", "Southeast", "South-Southeast",
"South", "South-Southwest", "Southwest", "West-Southwest",
"West", "West-Northwest", "Northwest", "North-NorthWest"]
dirList = ["north", "north-northeast", "northeast", "east-northeast",
"east", "east-southeast", "southeast", "south-southeast",
"south", "south-southwest", "southwest", "west-southwest",
"west", "west-northwest", "northwest", "north-northwest"]
dirIndex = int((direction + 11.25) / 22.5)
if dirIndex > 15:
dirIndex = dirIndex - 16

View file

@ -24,6 +24,7 @@
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# Oct 20, 2014 #3685 randerso Changed to support mixed case
# Apr 28, 2015 #4027 randerso Additional changes for mixed case
#
##
@ -90,14 +91,14 @@ class TextProduct(GenericHazards.TextProduct):
"name": "Forsyth County Environmental Affairs Department Winston-Salem NC",
"declaration": "The Forsyth County Environmental Affairs Department has issued an Air Quality Action Day...",
"zones": ["FLZ039"],
"text": "A Code @ALERTCODE Air Quality Alert for Ozone has been issued. Ground level ozone concentrations within the region may approach or exceed unhealthy standards. @ALERTCTA For additional information...please visit the Forsyth County Environmental Affairs Department Web site at http://www.co.forsyth.nc.us/envaffairs.",
"text": "A Code @ALERTCODE Air Quality Alert for Ozone has been issued. Ground level ozone concentrations within the region may approach or exceed unhealthy standards. @ALERTCTA For additional information...please visit the Forsyth County Environmental Affairs Department web site at http://www.co.forsyth.nc.us/envaffairs.",
},
"NC": {
"name": "North Carolina Department of Environmental and Natural Resources Raleigh NC",
"declaration": "The North Carolina Department of Environmental and Natural Resources has issued an Air Quality Action Day...",
"zones" : ["FLZ042", "FLZ043","FLZ048"],
"text": "A Code @ALERTCODE Air Quality Alert for Ozone has been issued. Ground level ozone concentrations within the region may approach or exceed unhealthy standards. @ALERTCTA For additional information...please visit the North Carolina Division of Air Quality Web site at http://daq.state.nc.us/airaware/forecast/.",
"text": "A Code @ALERTCODE Air Quality Alert for Ozone has been issued. Ground level ozone concentrations within the region may approach or exceed unhealthy standards. @ALERTCTA For additional information...please visit the North Carolina Division of Air Quality web site at http://daq.state.nc.us/airaware/forecast/.",
},
}
@ -150,19 +151,19 @@ class TextProduct(GenericHazards.TextProduct):
# Product header
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " +\
s = self._wmoID + " " + self._fullStationID + " " +\
self._ddhhmmTime + "\n" + self._pil + "\n\n" + productName + "\n"
# Placeholder for Agency Names to be filled in in _postProcessProduct
#fcst = fcst + "@AGENCYNAMES" + "\n"
s = "Relayed by National Weather Service " + self._wfoCityState + "\n" +\
#s = s + "@AGENCYNAMES" + "\n"
s = s + "Relayed by National Weather Service " + self._wfoCityState + "\n" +\
issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()

View file

@ -203,7 +203,7 @@ class TextProduct(GenericHazards.TextProduct):
for each in fullKeyList:
if each in ['LS.W', 'LS.A', 'LS.Y', 'LS.S']:
productName = "Lakeshore Hazard Message"
fcst = fcst.replace(self._productName, productName, 1)
fcst = fcst.replace(self._productName.upper(), productName.upper(), 1)
break
# Added to place line feeds in the CAP tags to keep separate from CTAs

View file

@ -133,7 +133,7 @@ class TextProduct(GenericHazards.TextProduct):
#
if self._areaName != "":
self._areaName = " FOR " + self._areaName
self._areaName = " for " + self._areaName
if useEAS == 1:
easPhrase = "URGENT - IMMEDIATE BROADCAST REQUESTED\n"
else:
@ -142,12 +142,14 @@ class TextProduct(GenericHazards.TextProduct):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, self._productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" + easPhrase +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n" + \
self._easPhrase + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + "Default overview section\n"
return fcst
@ -293,9 +295,9 @@ class TextProduct(GenericHazards.TextProduct):
#period.
areaGroupLen = len(areaGroups)
if areaGroupLen == 1:
areaPhrase = "A portion of "
areaPhrase = "a portion of "
else:
areaPhrase = "Portions of "
areaPhrase = "portions of "
#parts of the states
areaGroupCount = 0
@ -304,7 +306,7 @@ class TextProduct(GenericHazards.TextProduct):
if areaGroupCount == 1:
conn = ""
elif areaGroupCount == areaGroupLen:
conn = " AND "
conn = " and "
else:
conn = "..."
@ -324,39 +326,39 @@ class TextProduct(GenericHazards.TextProduct):
countyCnt = 0
for state, partOfState, names in areaGroups:
for name,nameType in names:
if nameType == "Zone":
if nameType == "zone":
zoneCnt = zoneCnt + 1
elif nameType == "County":
elif nameType == "county":
countyCnt = countyCnt + 1
elif nameType == "Independent city":
elif nameType == "independent city":
icCnt = icCnt + 1
elif nameType == "Parish":
elif nameType == "parish":
parishCnt = parishCnt + 1
incPhrases = []
if zoneCnt == 1:
incPhrases.append("Area")
incPhrases.append("area")
elif zoneCnt > 1:
incPhrases.append("Areas")
incPhrases.append("areas")
if countyCnt == 1:
incPhrases.append("County")
incPhrases.append("county")
elif countyCnt > 1:
incPhrases.append("Counties")
incPhrases.append("counties")
if icCnt == 1:
incPhrases.append("Independent city")
incPhrases.append("independent city")
elif icCnt > 1:
incPhrases.append("Independent cities")
incPhrases.append("independent cities")
if parishCnt == 1:
incPhrases.append("Parish")
incPhrases.append("parish")
elif parishCnt > 1:
incPhrases.append("Parishes")
incPhrase = " AND ".join(incPhrases)
incPhrases.append("parishes")
incPhrase = " and ".join(incPhrases)
if generalOnly:
return areaPhrase
areaPhrase = areaPhrase + "...Including the following " + \
areaPhrase = areaPhrase + "...including the following " + \
incPhrase + "..."
#list of the specific areas
@ -375,7 +377,10 @@ class TextProduct(GenericHazards.TextProduct):
phrase = "...".join(snames[0:-1])
# complex phrasing (state, partOfState, and names)
else:
phrase = "IN "
if i == 0:
phrase = "in "
else:
phrase = "In "
if partOfState != '' and partOfState != ' ':
phrase = phrase + partOfState + ' '
phrase = phrase + state + "..." + "...".join(snames[0:-1])
@ -383,7 +388,7 @@ class TextProduct(GenericHazards.TextProduct):
if len(snames) == 1:
phrase = phrase + snames[-1]
else:
phrase = phrase + " AND " + snames[-1]
phrase = phrase + " and " + snames[-1]
areaPhrase = areaPhrase + phrase
if i != len(areaGroups) - 1:
areaPhrase = areaPhrase + '. ' #another one coming, add period
@ -413,7 +418,7 @@ class TextProduct(GenericHazards.TextProduct):
if hazard['act'] == 'NEW' and len(hazard['hdln']):
attribution = nwsPhrase + "issued a"
headPhrase = "* " + hazName + " FOR " + areaPhrase + "."
headPhrase = "* " + hazName + " for " + areaPhrase + "."
elif hazard['act'] == 'CON' and len(hazard['hdln']):
attribution = "The " + hazName + " continues for"

View file

@ -1040,7 +1040,7 @@ class TextProduct(GenericHazards.TextProduct):
# Product header
if self._areaName != "":
self._areaName = " FOR " + self._areaName
self._areaName = " for " + self._areaName
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, actualProductName + self._areaName)
@ -1049,11 +1049,12 @@ class TextProduct(GenericHazards.TextProduct):
else:
eas = ''
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
eas + productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# Main Headline
mh = self._MainHeadline
@ -2833,10 +2834,10 @@ class TextProduct(GenericHazards.TextProduct):
def _dirInEnglish(self, direction):
dirList = ["North", "North-Northeast", "Northeast", "East-Northeast",
"East", "East-Southeast", "Southeast", "South-Southeast",
"South", "South-Southwest", "Southwest", "West-Southwest",
"West", "West-Northwest", "Northwest", "North-NorthWest"]
dirList = ["north", "north-northeast", "northeast", "east-northeast",
"east", "east-southeast", "southeast", "south-southeast",
"south", "south-southwest", "southwest", "west-southwest",
"west", "west-northwest", "northwest", "north-northwest"]
dirIndex = int((direction + 11.25) / 22.5)
if dirIndex > 15:
dirIndex = dirIndex - 16
@ -2873,7 +2874,7 @@ class TextProduct(GenericHazards.TextProduct):
if act in self._ignoreActions():
continue
if hdlns.index(hazardHdln) > 0:
t+= " AND "
t+= " and "
t+= "A " + hdln
reported += 1
if reported > 0:
@ -2936,7 +2937,7 @@ class TextProduct(GenericHazards.TextProduct):
if areaCount == 1:
conn = ""
elif areaCount == areaLen:
conn = " AND "
conn = " and "
else:
conn = "..."
if generalArea[1] != "":
@ -3384,9 +3385,9 @@ class TextProduct(GenericHazards.TextProduct):
# Skip HU.S headines
if (phen =='HU' and sig =='S'):
continue
if hdln[0] in ["A","I"]:a='AN '
elif hdln.find("FOR") == 0: a = ' '
else: a ='A '
if hdln[0] in ["A","I"]:a='an '
elif hdln.find("for") == 0: a = ' '
else: a ='a '
#print "\n Headline", hdln, phen
if areaWordMethod is not None:
@ -3443,7 +3444,7 @@ class TextProduct(GenericHazards.TextProduct):
# t+="but will continue to be monitored until it no longer threatens the area. "
#
# else:
t+="AT "+ self._stormTime + "...the center of "
t+="At "+ self._stormTime + "...the center of "
# Fix the grammar if dealing with "remnants"
if re.search("(?i)remnants", self._stormTypeName) is not None:
@ -3504,7 +3505,7 @@ class TextProduct(GenericHazards.TextProduct):
if act in self._ignoreActions():
continue
if hdlns.index(hazardHdln) > 0:
t+= " AND "
t+= " and "
t+= "A " + hdln
reported += 1
if reported > 0:
@ -4052,7 +4053,7 @@ remain in port until this storm passes.
if act in self._ignoreActions():
continue
if hdlns.index(hazardHdln) > 0:
t+= " AND "
t+= " and "
t+= "A " + hdln
reported += 1
if reported > 0:
@ -4710,7 +4711,7 @@ remain in port until this storm passes.
"marine":self._frame("Small craft should remain in port or safe harbor until winds and seas subside. For any small craft who are in distress...or if you see someone else in distress...radio your situation according to maritime protocol. If appropriate...deploy your emergency distress beacon.")+"\n",
},
"NoImpact": {
"general": self._frame("THIS EVENT IS NO LONGER EXPECTED TO HAVE AN IMPACT ACROSS THE AREA AT THIS TIME. USE THE OPPORTUNITY TO REVISE PREPAREDNESS PLANS AND REMAIN PREPARED FOR FUTURE EVENTS.\n\nAdd other wrap-up wording here.")+"\n",
"general": self._frame("This event is no longer expected to have an impact across the area at this time. Use the opportunity to revise preparedness plans and remain prepared for future events.\n\nAdd other wrap-up wording here.")+"\n",
},
"LongTerm": {
"land": self._frame("Continue to listen to NOAA weather radio and other local news media for the latest information on storm impacts.\n\nIf you are using a portable generator...observe all safety precautions to avoid carbon monoxide poisoning...electrocution...or fires. Portable generators should be operated outdoors...in a dry and well ventilated place. Do not store fuel inside your home or garage.\n\nChain saws can be very helpful when removing fallen trees and large branches. Yet...operating a chain saw is dangerous work. Be sure to review operating procedures for safe cutting. To reduce the chance of mishap or injury...work with another person who has experience.\n\nDo not go sight seeing into areas which have been hardest hit as you may hinder ongoing rescue and recovery operations.\n\nStay out of flooded areas as the water may be contaminated or the road might have been washed away. Test drinking water before using...particularly from wells. Stay away from downed power lines too.")+"\n\n",
@ -4723,13 +4724,13 @@ remain in port until this storm passes.
return {
"InProgress": self._frame(
"""
although the system is losing its tropical characteristics...the
Although the system is losing its tropical characteristics...the
potential impacts are similar to those previously indicated
regardless of its nature. Continue with readiness actions as
recommended."""),
"Completed": self._frame(
"""
although the system has become non-tropical...the potential
Although the system has become non-tropical...the potential
impacts are similar to those previously indicated. Continue with
readiness actions as recommended."""),
}

View file

@ -144,7 +144,7 @@ class TextProduct(GenericReport.TextProduct):
if areaCount == 1:
conn = ""
elif areaCount == areaLen:
conn = " AND "
conn = " and "
else:
conn = "..."
if eachGeneralArea[1] != "":

View file

@ -480,7 +480,7 @@ class TextProduct(GenericHazards.TextProduct):
if self._elevationSource == "Grids":
### initialize the phrase
le = " FOR "
le = " for "
### Set the phrase from the forecaster selections
if len(self._rfwType) > 0:
### add the event type
@ -489,7 +489,7 @@ class TextProduct(GenericHazards.TextProduct):
le = le + phraseDict.get(t)[0]
### add zone numbers or generic location description to headline
if self._numInHeadline == 0:
le = le + "For |* location description *|"
le = le + "for |* location description *|"
else:
le = le + self._headlineNumbers(hazard['id'])
else:
@ -577,9 +577,9 @@ class TextProduct(GenericHazards.TextProduct):
numList.sort()
### initialize the zone number list
if len(numList) > 1:
numStr = "For fire weather zones "
numStr = "for fire weather zones "
else:
numStr = "For fire weather zone "
numStr = "for fire weather zone "
i = 0
for i in range (len(numList)):
@ -588,7 +588,7 @@ class TextProduct(GenericHazards.TextProduct):
elif (len(numList) - i) > 2: ### more than three zones, and/or last zone in list
numStr = numStr + numList[i] + "..."
elif (len(numList) - i) > 1: ### next to last zone in list
numStr = numStr + numList[i] + " AND "
numStr = numStr + numList[i] + " and "
return numStr
@ -657,7 +657,7 @@ class TextProduct(GenericHazards.TextProduct):
### include state name
if self._includeStateName == 1:
nameString = nameString + "IN " + stateList[0] + "..."
nameString = nameString + "In " + stateList[0] + "..."
### sort based on zone number
ugcList = sorted(ugcList, key=lambda ugc: ugc[2])
@ -680,14 +680,14 @@ class TextProduct(GenericHazards.TextProduct):
elif (len(ugcList) - i) > 2: ### more than three zones, and/or last zone in list
nameString = nameString + ugcList[i][2] + " " + "..."
elif (len(ugcList) - i) == 2: ### next to last zone in list
nameString = nameString + ugcList[i][2] + " " + " AND "
nameString = nameString + ugcList[i][2] + " " + " and "
else: ### more than one state
for state in stateList:
### include state name
if self._includeStateName == 1:
nameString = nameString + "IN " + state + "..."
nameString = nameString + "In " + state + "..."
newList = [] ### split up ugcList for each state.
for st, name, num in ugcList:
@ -715,7 +715,7 @@ class TextProduct(GenericHazards.TextProduct):
elif (len(newList) - i) > 2: ### more than three zones, and/or last zone in list
nameString = nameString+ newList[i][0] + " " + "..."
elif (len(newList) - i) == 2: ### next to last zone in list
nameString = nameString + newList[i][0] + " " + " AND "
nameString = nameString + newList[i][0] + " " + " and "
### get rid of any spaces in the ellipses
nameString = nameString.replace("... ","...")
@ -810,7 +810,7 @@ class TextProduct(GenericHazards.TextProduct):
else:
hazardTypeForWeather = ""
forPhrase = " FOR " + hazardTypeForWeather
forPhrase = " for " + hazardTypeForWeather
return forPhrase

View file

@ -641,21 +641,21 @@ class TextProduct(HLSTCV_Common.TextProduct):
phen, sig = phenSig.split('.')
headline = VTECTable.VTECTable[phenSig]["hdln"]
definition = "A " + headline + " MEANS "
definition = "A " + headline + " means "
if phen == "HU":
definition += "HURRICANE WIND CONDITIONS"
definition += "Hurricane wind conditions"
elif phen == "TR":
definition += "TROPICAL STORM WIND CONDITIONS"
definition += "Tropical storm wind conditions"
elif phen == "SS":
definition += "LIFE THREATENING INUNDATION LEVELS"
definition += "Life threatening inundation levels"
else:
return ""
if sig == "W": # Warning
definition += " ARE EXPECTED SOMEWHERE WITHIN THIS AREA AND WITHIN THE NEXT 36 HOURS"
definition += " are expected somewhere within this area and within the next 36 hours"
elif sig == "A": # Watch
definition += " ARE POSSIBLE SOMEWHERE WITHIN THIS AREA AND WITHIN THE NEXT 48 HOURS"
definition += " are possible somewhere within this area and within the next 48 hours"
return definition
@ -1940,7 +1940,7 @@ class FloodingRainSection(SectionCommon):
self._setProductPartValue(segmentDict, 'forecastSubsection', subsectionDict)
def _latestForecastSummary(self, segmentDict, productSegmentGroup, productSegment):
summary = "" # was "No flood watch is in effect"
summary = "" # was "No Flood Watch is in effect"
segment, vtecRecords = productSegment
headlines, _ = self._textProduct._getAdditionalHazards()

View file

@ -112,7 +112,7 @@ class TextProduct(GenericHazards.TextProduct):
#
if self._areaName != "":
self._areaName = " FOR " + self._areaName
self._areaName = " for " + self._areaName
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict,
self._productName + watchPhrase)
@ -375,16 +375,16 @@ class TextProduct(GenericHazards.TextProduct):
county2 = "In {area} this allows to expire {number} {placeTypes}"
indepCity1 = "In {area} this allows to expire {number} " +\
"independent city"
indepCity2 = "IN {area} THIS ALLOWS TO EXPIRE {number} " +\
indepCity2 = "In {area} this allows to expire {number} " +\
"independent cities"
marine = "This allows to expire the following adjacent coastal waters"
elif phraseType == "REPLACE":
county1 = "IN {area} THE NEW WATCH INCLUDES {number} {placeType}"
county2 = "IN {area} THE NEW WATCH INCLUDES {number} {placeTypes}"
indepCity1 = "IN {area} THE NEW WATCH INCLUDES {number} " + \
county1 = "In {area} the new watch includes {number} {placeType}"
county2 = "In {area} the new watch includes {number} {placeTypes}"
indepCity1 = "In {area} the new watch includes {number} " + \
"independent city"
indepCity2 = "IN {area} THE NEW WATCH INCLUDES {number} " + \
indepCity2 = "In {area} the new watch includes {number} " + \
"independent cities"
marine = "The new watch includes the following adjacent coastal waters"
@ -559,7 +559,7 @@ class TextProduct(GenericHazards.TextProduct):
def _makeTextFromCountyTuple(self, countyTuple, lineLength=66, colWidth=22,
mainFormatSingular="In {area} this watch includes {number} {placeType}",
mainFormatPlural="In {area} this watch includes {number} {placeTypes}",
subFormat="IN {area}", mode="byState"):
subFormat="In {area}", mode="byState"):
#countyTuple: (state, partOfStateAndState, name)
#The type of text depends upon the mode: "byState" or "byPart"

View file

@ -259,8 +259,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
(self._getAnalysisList(), self._timeRangeList, self._areaList))
def _preProcessProduct(self, fcst, argDict):
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n"
fcst = fcst + s.upper()
return fcst
def _preProcessArea(self, fcst, editArea, areaLabel, argDict):

View file

@ -69,7 +69,7 @@
# in the AWIPS text database.
# This value is also used for the default GUI entry for
# storage.
# awipsWANPil Defines the awips product identifier
# awipsWANPil Defines the AWIPS product identifier
# (e.g., KBOUCCFDEN) that is used to transmit the
# product to the AWIPS WAN.
# This value is also used for the default GUI
@ -78,7 +78,7 @@
# grid points in a zone that must contain the hazard
# in order for it to be considered. Tuple (percent, points)
#
# periodCombining If 1, compnents an attempt will be made to combine components
# periodCombining If 1, components an attempt will be made to combine components
# or time periods into one. Otherwise no period combining will
# will be done.
# useAbbreviations
@ -329,7 +329,6 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def postProcessPhrases(self, tree, node):
words = node.get("words")
if words is not None:
words = string.lower(words)
words = string.replace(words, "thunderstorms and rain showers",
"showers and thunderstorms")
words = string.replace(words, "snow showers and rain showers", "rain and snow showers")
@ -574,7 +573,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -582,19 +581,21 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n" + \
self._lakeStmt(argDict) + "\n\n"
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + self._lakeStmt(argDict) + "\n\n"
fcst = fcst + self._Text1()
return fcst
def _preProcessArea(self, fcst, editArea, areaLabel, argDict):
areaHeader = self.makeAreaHeader(
argDict, areaLabel, self._issueTime, self._expireTime,
self._areaDictionary, self._defaultEditAreas)
self._areaDictionary, self._defaultEditAreas, upperCase=True)
fcst = fcst + areaHeader
# get the hazards text
@ -694,9 +695,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.

View file

@ -514,9 +514,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.
@ -920,18 +920,20 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
issuedByString = self.getIssuedByString()
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + self._Text1()
try:
text2 = self._Text2(argDict["host"])

View file

@ -419,7 +419,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
zoneTZ = localTZ
tzid = localTZid
LogStream.logProblem("WARNING: Entry " + area +
" missing from AreaDictionary. Using default time zone.")
" missing from AreaDictionary. Using default time zone.", LogStream.exc())
if (zoneTZ, tzid) not in tzs:
tzs.append((zoneTZ, tzid))
@ -674,12 +674,13 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
productName = self.checkTestMode(argDict,
productDescription)
fcst = fcst + self._pil + "\n\n"
fcst = fcst + productName + "\n"
fcst = fcst + "National Weather Service "
fcst = fcst + self._wfoCityState +"\n"
fcst = fcst + issuedByString
fcst = fcst + self._mndTimeLabel + "\n\n"
s = self._pil + "\n\n" + \
productName + "\n" + \
"National Weather Service " + \
self._wfoCityState +"\n" + \
issuedByString + \
self._mndTimeLabel + "\n\n"
fcst = fcst + s.upper()
return fcst

View file

@ -41,8 +41,8 @@
# names in one of two formats, depending upon whether
# you are supporting regional headers. Choose one and
# use it throughout the product.
# (editAreaName, "REGIONLABEL\nCITYLABEL")
# (editAreaName, "CITYLABEL")
# (editAreaName, "Regionlabel\nCitylabel")
# (editAreaName, "Citylabel")
#
# productName defines name of product e.g. "Tabular State Forecast"
#
@ -158,9 +158,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
"outputFile": "{prddir}/TEXT/SFT_<MultiPil>.txt",
"debug": 0,
"defaultEditAreas": [("area1", "REGION1\nCITY1"),
("area2", "REGION1\nCITY2"),
("area3", "REGION2\nCITY3"),
"defaultEditAreas": [("area1", "Region1\nCity1"),
("area2", "Region1\nCity2"),
("area3", "Region2\nCity3"),
],
# product identifiers
@ -354,15 +354,18 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# Add product heading to fcst string
issuedByString = self.getIssuedByString()
productName = self._productName + " FOR " + self._stateName
productName = self._productName + " for " + self._stateName
productName = self.checkTestMode(argDict, productName)
return fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n" +\
self._zoneCode + "-" + self._ddhhmmTimeExpire + "-\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n" + \
self._rowDescription() + "\n\n" + self._tableHeader() + "\n\n"
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
return fcst + self._rowDescription() + "\n\n" + self._tableHeader() + "\n\n"
def _preProcessArea(self, fcst, editArea, areaLabel, argDict):
# determine the region and area names, separated by a new line
@ -582,7 +585,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _popTimeLabel(self):
# Returns the valid time for the daily POP field
return " NIGHTTIME 6PM-6AM/DAYTIME 6AM-6PM"
return " nighttime 6PM-6AM/daytime 6AM-6PM"
def _qpfTimeLabel(self):
# Returns the valid time for the daily qpf field
@ -595,30 +598,30 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
ident = " "
# s is the built-up string containing the description
s = "ROWS INCLUDE...\n"
s = "Rows include...\n"
# Weather
s = s + ident + "DAILY PREDOMINANT DAYTIME WEATHER 6AM-6PM"
s = s + ident + "Daily predominant daytime weather 6AM-6PM"
# Temps
s = s + "\n" + ident + \
"FORECAST TEMPERATURES...EARLY MORNING LOW/DAYTIME HIGH"
"Forecast temperatures...early morning low/daytime high"
# PoP
if self._alwaysIncludePoP:
s = s + "\n" + ident + ident + ident + \
"PROBABILITY OF PRECIPITATION" + self._popTimeLabel()
"Probability of precipitation" + self._popTimeLabel()
# other stuff
s = s + "\n" + \
ident + ident + ident + " - INDICATES TEMPERATURES BELOW ZERO\n" + \
ident + ident + ident + "MM INDICATES MISSING DATA"
ident + ident + ident + " - indicates temperatures below zero\n" + \
ident + ident + ident + "MM indicates missing data"
#QPF
if self._alwaysIncludeQPF:
s = s + "\n" + ident + \
"QUANTITATIVE PRECIPITATION - INCHES -" + \
"Quantitative precipitation - inches -" + \
self._qpfTimeLabel()

View file

@ -59,7 +59,7 @@
# You can copy the information from the AreaDictionary as a starting point.
# Then add the following information for each zone:
#
# "landSeaArea": An edit area you need to create which contians grid
# "landSeaArea": An edit area you need to create which contains grid
# points along the coast, including both land and sea.
# "marineArea": Typically, the coastal waters area.
# "surfAreas": The surfAreas entry is an optional list of edit areas and labels
@ -67,18 +67,18 @@
# For example, If you have:
#
# surfAreas: [
# ("WestCoast", "Surf along west facing reefs.............."),
# ("NorthCoast", "Surf along north facing reefs............."),
# ("EastCoast", "Surf along east facing reefs.............."),
# ("SouthCoast", "Surf along south facing reefs............."),
# ("WestCoast", "SURF ALONG WEST FACING REEFS.............."),
# ("NorthCoast", "SURF ALONG NORTH FACING REEFS............."),
# ("EastCoast", "SURF ALONG EAST FACING REEFS.............."),
# ("SouthCoast", "SURF ALONG SOUTH FACING REEFS............."),
# ]
#
# You would get a surfHeight report for each surfArea listed:
#
# Surf along west facing reefs................10 TO 12 feet.
# Surf along north facing reefs...............4 TO 6 feet.
# Surf along east facing reefs................2 TO 3 feet.
# Surf along south facing reefs...............4 TO 6 feet.
# SURF ALONG WEST FACING REEFS................10 TO 12 feet.
# SURF ALONG NORTH FACING REEFS...............4 TO 6 feet.
# SURF ALONG EAST FACING REEFS................2 TO 3 feet.
# SURF ALONG SOUTH FACING REEFS...............4 TO 6 feet.
#
# If the list is empty, you will simply get surfHeight reported
# for the current value of the WaveHeight Grid sampled from the
@ -281,7 +281,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
"ripGrid": "", # Use grid for rip_phrase
"waterSpoutGrid": "", # Use grid for waterSpout_phrase
"includeOutlook": 0, # If 1, OUTLOOK section included
"outLookText": "\n.OUTLOOK...",# Text for OUTLOOK section
"outLookText": "\n.Outlook...",# Text for OUTLOOK section
"tideFiles": { # For each tide table, list the file where it can
# be found
"Venice Inlet": "/data/local/localapps/tides/VeniceInlet.txt",
@ -313,7 +313,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
"areaDictionary": "SurfAreaDictionary",
"language": "english",
"synopsisUGC": "", # UGC code for synopsis
"synopsisHeading": ".SYNOPSIS...",# Heading for synopsis
"synopsisHeading": ".Synopsis...",# Heading for synopsis
# If individualExtended == 1, an extended forecast will be
# generated for each individual area
# If extendedLabel == 1, a label will be included for each
@ -355,34 +355,34 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# If a method, it will be called with arguments:
# tree, node, key, element
return {
"WaveHeight" : "surf................",
"WaveHeight" : "SURF................",
"Swell": "swell",
"Swell2": "swell",
"LabelSwell": "swell...............",
"LabelSwell2": "secondary swell.....",
"Period": "period..............",
"Period2":"secondary period....",
"chop" : "water condition.....",
"rip" : "rip current risk....",
"HeatIndex": "heat index..........",
"20-foot winds......." : "beach winds.........",
"MaxT_FireWx":"max temperature.....",
"Sky/weather.........": "sky/weather.........",
"sst" : "water temperature...",
"uvi" : "UVI index...........",
"LAL" : "lightning threat....",
"WaterSpout" : "waterspout threat...",
"PoP" : "chance of...........",
"LabelSwell": "SWELL...............",
"LabelSwell2": "SECONDARY SWELL.....",
"Period": "PERIOD..............",
"Period2":"SECONDARY PERIOD....",
"chop" : "WATER CONDITION.....",
"rip" : "RIP CURRENT RISK....",
"HeatIndex": "HEAT INDEX..........",
"20-FOOT WINDS......." : "BEACH WINDS.........",
"MaxT_FireWx":"MAX TEMPERATURE.....",
"SKY/WEATHER.........": "SKY/WEATHER.........",
"sst" : "WATER TEMPERATURE...",
"uvi" : "UVI INDEX...........",
"LAL" : "LIGHTNING THREAT....",
"WaterSpout" : "WATERSPOUT THREAT...",
"PoP" : "CHANCE OF...........",
"MinT":"lows",
"MaxT":"highs",
"Wind": "winds",
# Used for Headlines
"Expected" : "expected",
"In effect" : "in effect",
"EXPECTED" : "expected",
"IN EFFECT" : "in effect",
# Used for single values
"around": "around ",
" valleys/lwr slopes...": " inland...............",
" ridges/upr slopes....": " coastal..............",
" VALLEYS/LWR SLOPES...": " INLAND...............",
" RIDGES/UPR SLOPES....": " COASTAL..............",
}
############################################################################
@ -857,7 +857,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict,):
# Product header
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -865,11 +865,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# Try to get Synopsis from previous SRF
srfPil = self._statePil + self._srfPil
@ -937,8 +938,8 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# "landSeaArea": "Extra0",
# "marineArea": "Extra1",
# "surfAreas": [
# ('NorthCoast', 'Surf along north facing reefs.............'),
# ('SouthCoast', 'Surf along south facing reefs.............')
# ('NorthCoast', 'SURF ALONG NORTH FACING REEFS.............'),
# ('SouthCoast', 'SURF ALONG SOUTH FACING REEFS.............')
# ],
# "tideTables": ["Cedar Key", "Venice Inlet"],
# },
@ -1228,7 +1229,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
return self.setWords(node, "")
self.setWords(node, "")
node.set("descriptor", "")
node.set("indentLabel", "20-foot winds.......")
node.set("indentLabel", "20-FOOT WINDS.......")
return self.DONE()
def fireRidgeValleyWind_setUp(self, tree, node):
@ -1538,7 +1539,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
tokens = line.split()
# Look for the city
for token in tokens:
if token == uviCity:
if token.upper() == uviCity.upper():
index = tokens.index(token)
state = tokens[index + 1]
if state == uviState:
@ -1597,7 +1598,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# Add error message to fcst
fcst = fcst + tideTable
continue
fcst = fcst + "\nAT " + label + "...\n\n"
fcst = fcst + "\nAt " + label + "...\n\n"
for line in tideTable:
if line.find(currentDate) == 0:
# Get the tide info
@ -1704,7 +1705,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
if words is None:
return
if words == "":
words = "Missing"
words = "MISSING"
node.set("descriptor", "")
node.set("indentLabel", "Label"+elementName)
node.set("compound", 1)

View file

@ -118,7 +118,7 @@ Definition["autoWrite"] = 0 #set to 1 to write product to file
Definition["lacList"] = ["VAC910c", "NCC940c"]
Definition["defaultEditAreas"] = [
("area1","Southwest mountains including yourTown"),
("area1","Southwest Mountains including YourTown"),
("area2","Eastern Virginia"),
("area3","Northern North Carolina"),
]

View file

@ -29,7 +29,6 @@ import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.persist.IPersistable;
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteMessageData;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.IDataStore;
@ -67,6 +66,8 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery;
* Mar 07, 2014 2791 bsteffen Move Data Source/Destination to numeric
* plugin.
* Nov 04, 2014 2714 bclement removed GINI specific DAOs
* Apr 15, 2014 4388 bsteffen Preserve fill value across interpolation levels.
*
* </pre>
*
* @author bphillip
@ -113,8 +114,12 @@ public class SatelliteDao extends PluginDao {
storageRecord.setCorrelationObject(satRecord);
final Map<String, Object> attributes = storageRecord
.getDataAttributes();
final Float fillValue = getAttribute(attributes,
if (storageRecord.getFillValue() == null) {
Number fillValue = getAttribute(attributes,
SatelliteRecord.SAT_FILL_VALUE, 0.0f);
storageRecord.setFillValue(fillValue);
}
final Number fillValue = storageRecord.getFillValue();
// Store the base record.
dataStore.addDataRecord(storageRecord);
@ -142,13 +147,14 @@ public class SatelliteDao extends PluginDao {
// data.
dr.setDataAttributes(attributes);
dr.setProperties(props);
dr.setFillValue(fillValue);
return dr;
}
@Override
public double getFillValue() {
// always the same fill value
return fillValue;
return fillValue.doubleValue();
}
@Override
@ -381,10 +387,10 @@ public class SatelliteDao extends PluginDao {
*/
private IDataRecord createDataRecord(SatelliteRecord satRec, Object data,
int downscaleLevel, Rectangle size) {
SatelliteMessageData msgData = null;
msgData = new SatelliteMessageData(data, size.width, size.height);
IDataRecord rec = msgData.getStorageRecord(satRec,
String.valueOf(downscaleLevel));
long[] sizes = new long[] { size.width, size.height };
IDataRecord rec = DataStoreFactory.createStorageRecord(
String.valueOf(downscaleLevel),
satRec.getDataURI(), data, 2, sizes);
rec.setCorrelationObject(satRec);
rec.setGroup(DataStoreFactory.createGroupName(satRec.getDataURI(),
SatelliteRecord.SAT_DATASET_NAME, true));
@ -403,11 +409,11 @@ public class SatelliteDao extends PluginDao {
* A default value.
* @return
*/
public static Float getAttribute(Map<String, Object> attrs,
public static Number getAttribute(Map<String, Object> attrs,
String attrName, Float defValue) {
Float retValue = defValue;
Number retValue = defValue;
if ((attrs != null) && (attrName != null)) {
retValue = (Float) attrs.get(attrName);
retValue = (Number) attrs.get(attrName);
}
return retValue;
}

View file

@ -21,6 +21,7 @@ package com.raytheon.uf.common.activetable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
@ -56,6 +57,7 @@ import com.vividsolutions.jts.geom.Geometry;
* Jul 16, 2013 2181 bsteffen Convert geometry types to use hibernate-
* spatial
* 10/16/2014 3454 bphillip Upgrading to Hibernate 4
* 04/28/2015 4027 randerso Expunged Calendar from ActiveTableRecord
* </pre>
*
* @author njensen
@ -126,19 +128,19 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
/** vtec start time */
@DynamicSerializeElement
protected Calendar startTime;
protected Date startTime;
@Column
@DynamicSerializeElement
protected Calendar endTime;
protected Date endTime;
@Column
@DynamicSerializeElement
protected Calendar issueTime;
protected Date issueTime;
@Column
@DynamicSerializeElement
protected Calendar purgeTime;
protected Date purgeTime;
@Column(length = 8)
@DynamicSerializeElement
@ -209,15 +211,15 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
@Column
@DynamicSerializeElement
protected Calendar floodBegin;
protected Date floodBegin;
@Column
@DynamicSerializeElement
protected Calendar floodCrest;
protected Date floodCrest;
@Column
@DynamicSerializeElement
protected Calendar floodEnd;
protected Date floodEnd;
@Override
public abstract Object clone();
@ -657,7 +659,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
/**
* @return the startTime
*/
public Calendar getStartTime() {
public Date getStartTime() {
return startTime;
}
@ -665,14 +667,14 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* @param startTime
* the startTime to set
*/
public void setStartTime(Calendar startTime) {
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
/**
* @return the endTime
*/
public Calendar getEndTime() {
public Date getEndTime() {
return endTime;
}
@ -680,14 +682,14 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* @param endTime
* the endTime to set
*/
public void setEndTime(Calendar endTime) {
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
/**
* @return the issueTime
*/
public Calendar getIssueTime() {
public Date getIssueTime() {
return issueTime;
}
@ -695,14 +697,14 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* @param issueTime
* the issueTime to set
*/
public void setIssueTime(Calendar issueTime) {
public void setIssueTime(Date issueTime) {
this.issueTime = issueTime;
}
/**
* @return the purgeTime
*/
public Calendar getPurgeTime() {
public Date getPurgeTime() {
return purgeTime;
}
@ -710,7 +712,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* @param purgeTime
* the purgeTime to set
*/
public void setPurgeTime(Calendar purgeTime) {
public void setPurgeTime(Date purgeTime) {
this.purgeTime = purgeTime;
}
@ -957,7 +959,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
/**
* @return the floodBegin
*/
public Calendar getFloodBegin() {
public Date getFloodBegin() {
return floodBegin;
}
@ -965,14 +967,14 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* @param floodBegin
* the floodBegin to set
*/
public void setFloodBegin(Calendar floodBegin) {
public void setFloodBegin(Date floodBegin) {
this.floodBegin = floodBegin;
}
/**
* @return the floodCrest
*/
public Calendar getFloodCrest() {
public Date getFloodCrest() {
return floodCrest;
}
@ -980,14 +982,14 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* @param floodCrest
* the floodCrest to set
*/
public void setFloodCrest(Calendar floodCrest) {
public void setFloodCrest(Date floodCrest) {
this.floodCrest = floodCrest;
}
/**
* @return the floodEnd
*/
public Calendar getFloodEnd() {
public Date getFloodEnd() {
return floodEnd;
}
@ -995,7 +997,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* @param floodEnd
* the floodEnd to set
*/
public void setFloodEnd(Calendar floodEnd) {
public void setFloodEnd(Date floodEnd) {
this.floodEnd = floodEnd;
}
@ -1050,17 +1052,17 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
}
atr.setAct(wr.getAct());
atr.setCountyheader(wr.getCountyheader());
atr.setEndTime(wr.getEndTime());
atr.setEndTime(calendarToDate(wr.getEndTime()));
atr.setEtn(wr.getEtn());
atr.setFloodBegin(wr.getFloodBegin());
atr.setFloodCrest(wr.getFloodCrest());
atr.setFloodEnd(wr.getFloodEnd());
atr.setFloodBegin(calendarToDate(wr.getFloodBegin()));
atr.setFloodCrest(calendarToDate(wr.getFloodCrest()));
atr.setFloodEnd(calendarToDate(wr.getFloodEnd()));
atr.setFloodRecordStatus(wr.getFloodRecordStatus());
atr.setFloodSeverity(wr.getFloodSeverity());
atr.setForecaster(wr.getForecaster());
atr.setGeometry(wr.getGeometry());
atr.setImmediateCause(wr.getImmediateCause());
atr.setIssueTime(wr.getIssueTime());
atr.setIssueTime(calendarToDate(wr.getIssueTime()));
atr.setLoc(wr.getLoc());
atr.setLocationID(wr.getLocationID());
atr.setMotdir(wr.getMotdir());
@ -1071,13 +1073,13 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
atr.setPhensig(wr.getPhensig());
atr.setPil(wr.getPil());
atr.setProductClass(wr.getProductClass());
atr.setPurgeTime(wr.getPurgeTime());
atr.setPurgeTime(calendarToDate(wr.getPurgeTime()));
atr.setRawmessage(wr.getRawmessage());
atr.setRegion(wr.getRegion());
atr.setSeg(wr.getSeg());
atr.setSegText(wr.getSegText());
atr.setSig(wr.getSig());
atr.setStartTime(wr.getStartTime());
atr.setStartTime(calendarToDate(wr.getStartTime()));
atr.setUfn(wr.isUfn());
atr.setVtecstr(wr.getVtecstr());
atr.setWmoid(wr.getWmoid());
@ -1093,4 +1095,11 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
return list;
}
private static Date calendarToDate(Calendar calendar) {
Date date = null;
if (calendar != null) {
date = calendar.getTime();
}
return date;
}
}

View file

@ -20,7 +20,7 @@
package com.raytheon.uf.common.activetable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -38,6 +38,7 @@ import com.vividsolutions.jts.geom.Geometry;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 4, 2013 dgilling Initial creation
* Apr 28, 2015 #4027 randerso Expunged Calendar from ActiveTableRecord
*
* </pre>
*
@ -84,15 +85,12 @@ public class ActiveTableUtil {
template.put("phensig", atr.getPhensig());
template.put("act", atr.getAct());
template.put("seg", atr.getSeg());
template.put("startTime",
atr.getStartTime().getTimeInMillis() / 1000);
template.put("endTime", atr.getEndTime().getTimeInMillis() / 1000);
template.put("startTime", atr.getStartTime().getTime() / 1000);
template.put("endTime", atr.getEndTime().getTime() / 1000);
template.put("ufn", atr.isUfn());
template.put("officeid", atr.getOfficeid());
template.put("purgeTime",
atr.getPurgeTime().getTimeInMillis() / 1000);
template.put("issueTime",
atr.getIssueTime().getTimeInMillis() / 1000);
template.put("purgeTime", atr.getPurgeTime().getTime() / 1000);
template.put("issueTime", atr.getIssueTime().getTime() / 1000);
template.put("state", "Decoded");
template.put("xxxid", atr.getXxxid());
@ -104,9 +102,9 @@ public class ActiveTableUtil {
template.put("rawMessage", atr.getRawmessage());
template.put("countyheader", atr.getCountyheader());
Calendar floodBegin = atr.getFloodBegin();
Date floodBegin = atr.getFloodBegin();
if (floodBegin != null) {
long floodBeginMillis = floodBegin.getTimeInMillis();
long floodBeginMillis = floodBegin.getTime();
if (floodBeginMillis != 0) {
template.put("floodBegin", floodBeginMillis / 1000);
}
@ -114,31 +112,31 @@ public class ActiveTableUtil {
template.put("wmoid", atr.getWmoid());
// Warngen fields
Calendar floodCrest = atr.getFloodCrest();
Date floodCrest = atr.getFloodCrest();
if (floodCrest != null) {
long floodCrestMillis = floodCrest.getTimeInMillis();
long floodCrestMillis = floodCrest.getTime();
if (floodCrestMillis != 0) {
template.put("floodCrest", floodCrestMillis / 1000);
}
}
Calendar floodEnd = atr.getFloodEnd();
Date floodEnd = atr.getFloodEnd();
if (floodEnd != null) {
long floodEndMillis = floodEnd.getTimeInMillis();
long floodEndMillis = floodEnd.getTime();
if (floodEndMillis != 0) {
template.put("floodBegin", floodEndMillis / 1000);
}
}
String floodStatus = atr.getFloodRecordStatus();
if (floodStatus != null && !"".equals(floodStatus.trim())) {
if ((floodStatus != null) && !"".equals(floodStatus.trim())) {
template.put("floodrecordstatus", floodStatus);
}
String floodSeverity = atr.getFloodSeverity();
if (floodSeverity != null && !"".equals(floodSeverity.trim())) {
if ((floodSeverity != null) && !"".equals(floodSeverity.trim())) {
template.put("floodseverity", floodSeverity);
}
Geometry geometry = atr.getGeometry();
if (geometry != null && !geometry.isEmpty()) {
if ((geometry != null) && !geometry.isEmpty()) {
StringBuilder sb = new StringBuilder();
String sep = "";
long lat;
@ -154,17 +152,17 @@ public class ActiveTableUtil {
}
String immediateCause = atr.getImmediateCause();
if (immediateCause != null && !"".equals(immediateCause.trim())) {
if ((immediateCause != null) && !"".equals(immediateCause.trim())) {
template.put("immediateCause", immediateCause);
}
String loc = atr.getLoc();
if (loc != null && !"".equals(loc.trim())) {
if ((loc != null) && !"".equals(loc.trim())) {
template.put("loc", loc);
}
String locationId = atr.getLocationID();
if (locationId != null && !"".equals(locationId.trim())) {
if ((locationId != null) && !"".equals(locationId.trim())) {
template.put("locationId", locationId);
}

Some files were not shown because too many files have changed in this diff Show more