## Exercise1 for Apr 02 02 13:00:00 GMT - Apr 03
02 01:00:00 GMT.
##
## Edit Area QPF
Precip (%) Wind (mph)
##
## Area
1
0
6
NW 0
## Area
2
0
11
NE 5
## Area
3
0
4
W 10
Definition = {
## General Set-Up
"type": "table",
"displayName": "TextEx1", # for Product
Generation Menu
"outputFile": "./Exercise1.txt", # default
output file
## Table Layout
"constantVariable": "TimePeriod",
"rowVariable": "EditArea",
"columnVariable": "WeatherElement",
"beginningText": "Exercise1 for %TimePeriod.
\n\n",
"endingText": " ",
## Edit Areas
"defaultEditAreas": [
("area1", "Area 1"),
("area2", "Area 2"),
("area3", "Area 3"),
],
"runTimeEditAreas" : "no", # if yes, ask user
at run time
"areaType" : "Edit Area", # E.g. City, County,
Basin, etc.
## Time Ranges
"defaultRanges": ["Today"],
"runTimeRanges" : "no", # if yes, ask user at
run time
## Weather Elements
# Name , Label , Analysis Method , ReportAs
Method ,
# DataType , Rounding , Conversion
"elementList": [
("QPF", "QPF", "avg", "singleValue",
"Scalar", .01, None),
("PoP", "Precip (%)", "avg", "singleValue",
"Scalar", 1, None),
("Wind","Wind (mph)", "vectorRange", "avgValue",
"Vector", 5, None),
],
}
## Experimental Surface Temperature Guidance
Product
##
## Edit Area 13Z/2
16Z/2 19Z/2 22Z/2
##
## Area
1
28
28
28 25
## Area
2
30
31
31 27
## Area
3
32
33
34 27
Definition = {
## General Set-up
"type": "table",
"displayName": "TextEx2", # for Product
Generation Menu
"outputFile": "./SurfaceTemp.txt", # default
output file
## Table Layout
"constantVariable": "WeatherElement",
"rowVariable": "EditArea",
"columnVariable": "TimePeriod",
"beginningText": "Experimental Surface
Temperature Guidance Product \n\n",
"endingText": "",
## Edit Areas
"defaultEditAreas" : [
("area1", "Area 1"),
("area2", "Area 2"),
("area3", "Area 3"),
],
"runTimeEditAreas" : "yes", # if yes, ask user
at run time
"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": [
("T","Temp", "avg", "singleValue",
"Scalar", 1, None),
],
## Time Period
"timePeriod": 3,
"runTimePeriod": "yes", # If yes, ask user at
run time for period
}
Answer to Smart Tabular
Exercise 2
########################################################################
# 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
import TimeRange
class TextProduct(SmartElementTable.TextProduct):
Definition =
copy.deepcopy(SmartElementTable.TextProduct.Definition)
Definition["displayName"] = "SmartElementTable"
#Definition["outputFile"] =
"{prddir}/TEXT/SmartElementTable.txt"
#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",
"Wind"]
#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)
def _getAnalysisList(self):
return [
("MinT",
self.avg),
("MaxT",
self.avg),
("MinRH",
self.avg),
("MaxRH",
self.avg),
("PoP",
self.stdDevMaxAvg),
("Wind",
self.vectorAvg),
]
def _titleDict(self):
return {
"Temp": "TEMPERATURE",
"PoP": "PRECIPITATION",
"Humidity":"HUMIDITY",
"Wind": "WIND",
}
def _getWindValues(self, statList, argDict):
# Return a string of PoP values in
the statList
wind = []
windStr = " "
index = 0
for stats in statList:
val =
self._getWindValue(stats)
if index
< len(statList)-1:
windStr = windStr + val + " "
else:
windStr = windStr + val
index += 1
windStr = windStr + " "
return windStr
def _getWindValue(self, stats):
wind = self.getStats(stats,"Wind")
if wind is None:
val =
" "
else:
mag, dir =
wind
mag =
self.round(mag, "Nearest", 5)
val =
self.getVectorVal((mag,dir))
return val
#
---------------------------------------------------------------------
# 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.
#
# FWFTable_BOU_Overrides.TextUtility
#
# This file is used for WFO specific overrides of the FWFTable
# formatter.
#
#
# Methods:
# Overrides:
#
# Additions:
#
# ---------------------------------------------------------------------
import string, time, re, os, types, copy
import TimeRange
import TextRules
#**********************************************************************
# MAKE NO CHANGES HERE
# The minimum contents of this file are the following class definition
# and the __init__ method with only "pass" line in it.
class FWFTable_BOU_Overrides:
def __init__(self):
pass
# End MAKE NO CHANGES HERE
#**********************************************************************
# Make sure to indent methods inside the class
statement.
#----- WFO BOU FWFTable Overrides -----
# It is helpful to put a debug statement at the
beginning of each
# method to help with trouble-shooting.
#def _method(self):
#self.debug_print("Debug:
_method in FWFTable_CR_Overrides")
# Example of Overriding a dictionary from TextRules
#def phrase_descriptor_dict(self, tree, node):
#dict =
TextRules.TextRules.phrase_descriptor_dict(self, tree, node)
#dict["PoP"] = "chance of"
#return dict
def _rowList(self):
# The rowList is controls
what parameters go into the table.
# The list is a set of
(label:method) pairs.
# You may change the label
if you like.
# The order of the list
determines the order of the rows in the table
# so you may re-arrange the
order if you like.
return [
#
Directive requirements
#
MODIFICATION: Changing order of Precip and Cloud cover
#("CLOUD COVER", self._cloudCover_row),
#("PRECIP TYPE", self._precipType_row),
("PRECIP TYPE", self._precipType_row),
("CLOUD COVER", self._cloudCover_row),
("CHANCE PRECIP (%)", self._chancePrecip_row),
("TEMP (24H TREND)", self._tempWithTrend_row),
("RH
% (24H TREND)",self._rhWithTrend_row),
#
Use these if you do not want trends
#("TEMP", self._temp_row),
#("RH %", self._rh_row),
("20FTWND-VAL/AM(MPH)", self._windValleyMph_row),
("20FTWND-RDG/PM(MPH)", self._windRidgeMph_row),
#
Directive optional products
##
("PRECIP AMOUNT", self._precipAmount_row),
##
("PRECIP DURATION", self._precipDuration_row),
##
("PRECIP BEGIN", self._precipBegin_row),
##
("PRECIP END", self._precipEnd_row),
##
("MIXING HGT(M-AGL/MSL)", self._mixHgtM_row),
##
("MIXING HGT(FT-AGL/MSL)", self._mixHgtFt_row),
##
("TRANSPORT WND (KTS)", self._transWindKts_row),
##
("TRANSPORT WND (M/S)", self._transWindMS_row),
##
("TRANSPORT WND (MPH)", self._transWindMph_row),
##
("VENT RATE (KT-FT)", self._ventRateKtFt_row),
##
("VENT RATE (M/S-M)", self._ventRate_row),
##
("DISPERSION", self._dispersion_row),
##
("DSI", self._dsi_row),
##
("SUNSHINE HOURS", self._sunHours_row),
## #
If you need Ceiling, uncomment the Ceiling line in _getAnalysisList
##
("CEILING", self._ceiling_row),
##
("CWR", self._cwr_row),
##
("LAL", self._lal_row),
##
("HAINES INDEX", self._haines_row),
##
("RH RECOVERY", self._rhRecovery_row),
## #
If you need 500m Mix Hgt Temp, uncomment the MixHgt500
## #
line in _getAnalysisList
##
("MIX HGT 500", self._mixHgt500_row),
##
("STABILITY CLASS", self._stability_row),
]
def _getVariables(self, argDict):
# Make argDict accessible
self.__argDict = argDict
# Get variables from
VariableList
self._definition =
argDict["forecastDef"]
for key in
self._definition.keys():
exec
"self._" + key + "= self._definition[key]"
varDict = argDict["varDict"]
self._issuanceType =
varDict["Issuance Type"]
self._productType =
varDict["Forecast Product"]
# Determine issue time
self._issueTime =
self.IFP().AbsTime.current()
# Determine expiration time
self._expirationTimeOffset =
12
self._expireTime =
self._issueTime + self._expirationTimeOffset*3600
#self._expireTime =
time.strftime("%d%H%M",time.gmtime(expireTime))
# Set up product-specific
variables
self._colWidth = 13
if self._columnJustification
== "l":
self._rowLabelWidth = 22
else:
self._rowLabelWidth = 24
self._fixedValueWidth = 13
self._analysisList =
self._getAnalysisList()
# Calculate current times
self._ddhhmmTime =
self.getCurrentTime(
argDict, "%d%H%M", shiftToLocal=0, stripLeading=0)
# MODIFICATION: Changing
format of current time
#self._timeLabel =
self.getCurrentTime(
# argDict,
"%l%M %p %Z %a %b %e %Y", stripLeading=1)
self._timeLabel =
self.getCurrentTime(
argDict, "%b %e %Y %l%M %p %Z %a", stripLeading=1)
return None
def _sky(self, statDict, timeRange, argList):
# Return a sky value
sky =
self.getStats(statDict, "Sky")
print "USING OVERRIDDEN SKY
THRESHOLDS"
# MODIFICATION -- Changing
sky thresholds
## if sky is None:
##
value = ""
## elif sky < 10:
##
value = "CLEAR"
## elif sky < 30:
##
value = "MCLEAR"
## elif sky <= 60:
##
value = "PCLDY"
## elif sky <= 80:
##
value = "MCLDY"
## else:
##
value = "CLOUDY"
if sky is None:
value = ""
elif sky < 15:
value = "CLEAR"
elif sky < 40:
value = "MCLEAR"
elif sky <= 70:
value = "PCLDY"
elif sky <= 85:
value = "MCLDY"
else:
value = "CLOUDY"
return value