This automatic configuration is based on the afos2awips.txt pil/wmoid table. If there are errors in this table, then the products will not be correctly configured. To correct the templates after making changes to afos2awips.txt, you can rerun the template expansion scripts. Refer to the configureTextProduct User Guide for more details.
Some sites will have multiple entries in their afos2awips.txt table for a particular product, e.g., ZFP. The configuration script takes this into account and will automatically generate formatters for each entry found.
Product | Standard File (Text Products Window) |
Site Definition File Site Overrides File (Text Utilities Window) OR Local file (Text Products Window) |
Regional
Overrides File (Text Utilities Window) |
Edit Areas |
Additional Set-up Info |
CCF | CCF | CCF_<site>_Definition CCF_<site>_Overrides |
CCF_<region>_Overrides | "defaultEditAreas" |
Edit Areas Needed: Typically point edit areas are required for each entry to you wish to generate the product for. |
SFT | SFT | SFT_<site>_Definition SFT_<site>_Overrides |
SFT_<region>_Overrides | "defaultEditAreas" | Edit Areas Needed: Typically point edit areas are required for each entry to you wish to generate the product for. |
AFM | PFM | AFM_<site>_Definition AFM_<site>_Overrides |
AFM_<region>_Overrides | Combinations |
See Standard product file for details. |
PFM | PFM | PFM_<site>_Definition PFM_<site>_Overrides |
PFM_<region>_Overrides | "defaultEditAreas" | Edit Areas Needed: Typically point edit areas are required for each entry to you wish to generate the product for. |
MVF | MVF | MVF_<site>_Definition MVF_<site>_Overrides |
MVF_<region>_Overrides | "defaultEditAreas" | Edit Areas Needed: Typically point edit areas are required for each entry to you wish to generate the product for. |
FWF Tabular | FWFTable | FWFTable_<site>_Definition FWFTable_<site>_Overrides |
FWFTable_<region>_Overrides | Combinations |
|
FWM | FWM | FWM_<site>_Definition FWM_<site>_Overrides |
FWM_<region>_Overrides | "defaultEditAreas" | |
AFD |
AFD | AFD_<site>_Definition AFD_<site>_Overrides |
AFD_<region>_Overrides | Combinations |
Product | Standard File (Text Products Window) |
Site Definition File Site Overrides File (Text Utilities Window) OR Local file (Text Products Window) |
Regional
Overrides File (Text Utilities Window) |
Edit
Areas |
Additional Set-up Info |
ZFP | AreaFcst | ZFP_<site>_Definition ZFP_<site>_Overrides |
ZFP_<region>_Overrides | Combinations |
|
SAF | AreaFcst | SAF_<site>_Definition SAF_<site>_Overrides |
SAF_<region>_Overrides | "defaultEditAreas" | Also inherits from ZFP Site Definitions and Overrides so that
those settings and customizations will carry over to the SAF. Also inherits from SAF_Overrides |
CWF | CWF | CWF_<site>_Definition CWF_<site>_Overrides |
CWF_<region>_Overrides | Combinations |
|
CWF_Pacific | CWF_Pacific | CWF_Pacific_<site>_Definition CWF_Pacific_<site>_Overrides |
CWF_Pacific_<region>_Overrides | Combinations | |
GLF | GLF | GLF_<site>_Definition GLF_<site>_Overrides |
GLF_<region>_Overrides | "defaultEditAreas" | Many special edit areas needed.
See Standard GLF product file for more details. |
NSH | NSH | NSH_<site>_Definition NSH_<site>_Overrides |
NSH_<region>_Overrides | Combinations | |
OFF |
OFF |
OFF_<site>_Definition OFF_<site>_Overrides |
OFF_<region>_Overrides |
Combinations |
|
FWF | FWF | FWF_<site>_Definition FWF_<site>_Overrides |
FWF_<region>_Overrides | Combination |
|
FWS |
FWF |
FWS_<site>_Definition FWS_<site>_Overrides |
FWS_<region>_Overrides | Lat/Lon point |
Also inherits from FWS_Overrides. |
Product |
Standard
File |
Local
File |
Edit
Areas |
Additional
Info |
ADR |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_ADR_Local | Combinations | Does not use any gridded
data. Zone combiner is used to define area of product. |
AVA |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_AVA_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
AVW |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_AVW_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
BLU |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_BLU_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
CAE |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_CAE_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
CDW |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_CDW_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
CEM |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_CEM_Local | Combinations | Does not use any gridded
data. Zone combiner is used to define area of product. |
CFW |
Hazard_CFW (Inherits from GenericHazard) |
Hazard_CFW_Local |
Automatically determined |
Uses the Hazards grid. |
EQR |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_EQR_Local | Combinations |
Does not use any gridded data. Zone combiner is used to define area of product. |
EQW |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_EQW_Local |
Combinations |
Does not use any gridded data. Zone combiner is used to define area of product. |
EVI |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_EVI_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
FFA |
Hazard_FFA (Inherits from GenericHazard) |
Hazard_FFA_Local |
Automatically determined |
A dialog is displayed when this
formatter is started to allow the forecaster to select the flood reason
for the required H-VTEC line.
Can be configured for either ZONES or FIPS UGCs. |
FRW |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_FRW_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
HLS |
Hazard_HLS (Inherits from GenericReport) |
Hazard_HLS_Local |
Combinations |
Does not use any gridded data. Zone combiner is used to define area of product. |
HMW |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_HMW_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
HWO | Hazard_HWO (Inherits from GenericReport) |
Hazard_HWO_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
LAE |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_LAE_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
LEW |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_LEW_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
MWS |
Hazard_MWS (Inherits from GenericHazard) |
Hazard_MWS_Local |
Automatically determined | Uses the Hazards grid. |
NPW |
Hazard_NPW (Inherits from GenericHazard) |
Hazard_NPW_Local |
Automatically determined | Uses the Hazards grid. |
NUW |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_NUW_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
RFW |
Hazard_RFW (Inherits from GenericHazard) |
Hazard_RFW_Local |
Automatically determined | Uses the Hazards grid. |
RHW |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_RHW_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
SPW |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_SPW_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
TOE |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_TOE_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
VOW |
CivilEmerg (Inherits from GenericReport) |
CivilEmerg_VOW_Local | Combinations | Does not use any gridded data. Zone combiner is used to define area of product. |
WCN |
Hazard_WCN (Inherits from GenericHazard) |
Hazard_WCN_Local |
Automatically determined | Uses the Hazards grid. |
WSW |
Hazard_WSW (Inherits from GenericHazard) |
Hazard_WSW_Local |
Automatically determined | Uses the Hazards grid. |
Product |
Standard File |
Local File |
EditAreas |
Additional
Info |
ESF |
GenericReport |
ESF_Local |
Combinations |
Can be configured to use either
FIPS or ZONE codes. |
NOW |
GenericReport | NOW_Local |
Combinations | |
PNS |
GenericReport | PNS_Local |
Combinations | |
RFD |
GenericReport | RFD_Local |
Combinations | |
SPS |
GenericReport | SPS_Local |
Combinations |
The "wind_withGusts_phrase" produces phrases such as:
WINDS NORTHEAST 10 TO 20 KNOTS WITH GUSTS TO AROUND 70 KNOTS VEERING SOUTHEAST 5 TO 15 KNOTS WITH GUSTS AROUND 25 KNOTS IN THE EARLY MORNING.
When we find this phrase in the Wind and
WindGust Text Rules section, we see that it can be customized in
various ways. If we want to change the descriptor from "WINDS" to
"WIND", we need to override the phrase_descriptor_dict
for "Wind". First, we look to see if it is
already overridden in the Standard File, AreaFcst, which we
open in the Text Products folder of the Define Text Products dialog. We
can issue a "find" command to see if it is there. It is not, so next we
look in the ConfigVariables utility from the Text Utilities folder
and issue a "find" command. NOTE:
The ConfigVariables Utility is "Read-Only", so
you cannot change the method in that file. You MUST copy it into your
Overrides file, and in that location, you can change the value which
will override or supercede the value found in the library module.
We notice that the phrase_descriptor_dict is very lengthy. We do not have to repeat the entire method. Instead, we can use the dictionary as a starting point and simply change any entries that are relevant to us as follows:
def phrase_descriptor_dict(self, tree, node):Notice that our descriptor entry can be in lower case. All formatters work in lower case to construct the phrase. It is converted to upper case near the end of processing.
dict = TextRules.TextRules.phrase_descriptor_dict(self, tree, node)
dict["Wind"] = "wind"
return dict
If we want to report knots as "KTS" instead of "KNOTS", we will override the units_descriptor_dict for "kt" as follows in the "Overriding Thresholds and Variables" section of our Overrides file:
def units_descriptor_dict(self, tree, node):The wind_withGusts_phrase reports gusts if they are 10 knots greater than the maximum wind speed. Suppose we would like to suppress reporting gusts unless they are at least 15 knots greater than the maximum wind speed. The table for the "public_windRange_withGusts_phrase" lists a method called gust_wind_difference_threshold. We can locate it in the VectorRelatedPhrases module and copy and paste it into our Overrides file:
dict = TextRules.TextRules.units_descriptor_dict(self, tree, node)
unitsDict = dict["units"]
unitsDict["kt"] = "kts"
return dict
def
gust_wind_difference_threshold(self, tree, node):
# Difference between gust and max wind below which gusts are not
mentioned
# Units are in mph or knots depending on the current product
return 15
Narrative Definition and Configurable Issuance -- issuance_list
Narrative products are composed of a "narrative" which contains a series of "component" phrase products. This is used to construct a "narrative" type of product of the form:
{
"type": "narrative",
"narrativeDef": [(<componentName>, <number of
hours>), ...],
"methodList": [self.assembleChildWords"],
# optional:
"priorPeriod": <number of hours>, # Number of hours
for sampling prior to forecast. Used for
# first period trends
}
For example:
{
"type": "narrative",
"narrativeDef": [("Period_1", 12), ("Period_2_3", 12),
("Period_2_3, 12)],
"methodList": [self.assembleChildWords"],
# optional:
"priorPeriod": 24, # Number of hours for sampling prior to
forecast. Used for
# first period trends
}
Note that you may define a "Phantom" period during which no phrases will be generated. It will act as a placeholder advancing your time periods:
"narrativeDef": {
("Period", "period1"),
("Period", 12), ("Period", 12),
("LaterPeriod", 12), ("LaterPeriod", 12), ("LaterPeriod", 12),
("Phantom", 6), ("Extended", 24), ("Extended", 24), ("Extended", 24)
}
You can customize the issuance times and the series of components by overriding the _issuance_list method, which returns information about the issuance times you want for your product. The issuance_list, is found in the Standard file for narrative-type products.
For each issuance time we must give the following information:
def _10_503_issuance_list(self,
argDict):
narrativeDefAM = [
("Period_1",
"period1"),
("Period_2_3", 12), ("Period_2_3", 12),
("Period_4_5", 12), ("Period_4_5", 12),
("Period_6_14", 12), ("Period_6_14", 12), ("Period_6_14", 12),
("Period_6_14", 12),
("Period_6_14", 12), ("Period_6_14", 12), ("Period_6_14", 12),
("Period_6_14", 12),
]
narrativeDefPM = [
("Period_1", "period1"),
("Period_2_3", 12), ("Period_2_3", 12),
("Period_4_5", 12), ("Period_4_5", 12),
("Period_6_14", 12), ("Period_6_14", 12), ("Period_6_14", 12),
("Period_6_14", 12),
("Period_6_14", 12), ("Period_6_14", 12), ("Period_6_14", 12),
("Period_6_14", 12),
("Period_6_14", 12),
]
return [
("Morning", self.DAY(), self.NIGHT(), self.NIGHT(),
".TODAY...", "early in the morning", "late in the afternoon",
1, narrativeDefAM),
("Morning with Pre-1st Period", self.DAY()-2, self.NIGHT(),
self.NIGHT(),
".TODAY...", "early in the morning", "late in the afternoon",
1, narrativeDefAM),
("Morning Update", "issuanceHour", self.NIGHT(), self.NIGHT(),
".REST OF TODAY...", "early in the morning", "late in the afternoon",
1, narrativeDefAM),
("Afternoon Update", "issuanceHour", self.NIGHT(), self.NIGHT(),
".REST OF TODAY...", "early in the morning","late in the afternoon",
1, narrativeDefAM),
# End times are tomorrow:
("Afternoon", self.NIGHT(), 24 + self.DAY(), 24 + self.DAY(),
".TONIGHT...", "late in the night", "early in the evening",
1, narrativeDefPM),
("Afternoon with Pre-1st Period", self.NIGHT()-2, 24 + self.DAY(), 24 +
self.DAY(),
".TONIGHT...", "late in the night", "early in the evening",
1, narrativeDefPM),
("Evening Update", "issuanceHour", 24 + self.DAY(), 24 + self.DAY(),
".REST OF TONIGHT...", "early in the morning","early in the evening",
1, narrativeDefPM),
#
For the early morning update, this produces:
#
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",
0, narrativeDefPM),
#
Alternative
#
For the early morning update, this produces:
#
EARLY THIS MORNING:
#
TODAY
#
TONIGHT
#("Evening Update", "issuanceHour", 24 + self.DAY(), 24 + self.DAY(),
#
".REST OF TONIGHT...", "late in the night", "early in the evening",
# 1,
narrativeDefPM),
#("Early Morning Update", "issuanceHour", self.DAY(), self.DAY(),
#
".EARLY THIS MORNING...", "early in the morning", "late in the
afternoon",
# 1,
narrativeDefPM),
]
NOTE: Any variables that begin with a "self._" should be
encased in a "try" block. This is because the "_issuance_list" is
accessed and examined once BEFORE the product is actually run in order
to set up the input dialog. During this first examination, the
variables are not yet initialized. As an example, here is the
issuance_list from the FWF:
def
_issuance_list(self, argDict):
narrativeDefAM = [
("FirePeriod", "period1"),
("FirePeriod", 12), ("FirePeriod", 12),
]
narrativeDefPM = [
("FirePeriod", "period1"),
("FirePeriod", 12), ("FirePeriod", 12), ("FirePeriod", 12)
]
extended = [
("FireExtendedShortTerm", 24), ("FireExtendedShortTerm", 24),
("FireExtendedShortTerm", 24),
("FireExtended", 24), ("FireExtended", 24),
]
try:
if self._individualExtended == 1:
if self._extendedLabel == 1:
narrativeDefAM.append(("ExtendedLabel",0))
narrativeDefPM.append(("ExtendedLabel",0))
narrativeDefAM = narrativeDefAM + extended
narrativeDefPM = narrativeDefPM + extended
except:
pass
return [
("Morning", self.DAY(), self.NIGHT(), self.NIGHT(),
".TODAY...", "early in the morning", "late in the afternoon",
1, narrativeDefAM),
("Morning Update", "issuanceHour", self.NIGHT(), self.NIGHT(),
".REST OF TODAY...", "early in the morning", "late in the afternoon",
1, narrativeDefAM),
("Afternoon Update", "issuanceHour", self.NIGHT(), self.NIGHT(),
".REST OF TODAY...", "early in the morning","late in the afternoon",
1, narrativeDefAM),
# End times are tomorrow:
("Afternoon", self.NIGHT(), 24 + self.DAY(), 24 + self.DAY(),
".TONIGHT...", "late in the night", "early in the evening",
1, narrativeDefPM),
("Evening Update", "issuanceHour", 24 + self.DAY(), 24 + self.DAY(),
".REST OF TONIGHT...", "late in the night","early in the evening",
1, narrativeDefPM),
# For the early morning update, this produces:
# 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",
0, narrativeDefPM),
# Alternative
# For the early morning update, this produces:
# EARLY THIS MORNING:
# TODAY
# TONIGHT
#("Evening Update", "issuanceHour", 24 + self.DAY(), 24 + self.DAY(),
# ".REST OF TONIGHT...", "late in the night", "early in the evening",
# 1, narrativeDefPM),
#("Early Morning Update", "issuanceHour", self.DAY(), self.DAY(),
# ".EARLY THIS MORNING...", "early in the morning", "late in the
afternoon",
# 1, narrativeDefPM),
]
Post-Processing Narrative Phrases
Although, it is not encouraged, there will be times that you will want to post-process phrases to clean up undesirable wording.
A "postProcessPhrase" hook is available for most phrases. This allows you to do string replacement and/or abbreviations. Here is the default method from the PhraseBuilder module. You may copy it into your Overrides file and add replacements:
def postProcessPhrase(self,
tree, node):
words
= node.get("words")
if
words is not None:
words = words.replace("rain showers and thunderstorms", "showers and
thunderstorms")
return self.setWords(node, words)