In 20.2.1, there is a robust capability for easily managing interdependencies between Immediate Cause, Source, and Event Type. The methods that present the interdependency lookups (icEventTypeSourceDefaults, icEventTypeSourceRespected) are methods of the class GeneralUtilities.py, because it is a convenient place to make those methods accessible to both the interdependency logic and the metadata classes.
The base instance of icEventTypeSourceDefaults() has a set of interdependencies implemented, but that set of interdependencies has not necessarily been vetted as the very best set of default interdependencies.
To help understand the parameters of managing these interdependencies, here are lists of all the values of these we know about.
Immediate cause values we know about:
immediateCauseDict = {"ER":"excessive rain",
"SM":"snowmelt",
"RS":"rain and snowmelt",
"DM":"a dam or levee failure",
"DR":"a dam floodgate release",
"GO":"a glacier-dammed lake outburst",
"IJ":"an ice jam",
"IC":"rain and/or snow melt and/or ice jam",
"FS":"upstream flooding plus storm surge",
"FT":"upstream flooding plus tidal effects",
"ET":"elevated upstream flow plus tidal effects",
"WT":"wind and/or tidal effects",
"OT":"other effects",
"MC":"multiple causes",
"UU":"Unknown" }
Source values we know about:
return {"identifier":"dopplerSource",
"displayString": "Doppler radar indicated",
return {"identifier":"dopplerGaugesSource",
"displayString": "Doppler radar and automated gauges",
return {"identifier":"trainedSpottersSource",
"displayString": "Trained spotters reported",
return {"identifier":"publicSource",
"displayString": "Public reported",
return {"identifier":"localLawEnforcementSource",
"displayString": "Local law enforcement reported",
return {"identifier":"emergencyManagementSource",
"displayString": "Emergency management reported",
return {"identifier":"emergencyManagementSource",
"displayString": "Emergency management reported",
return {"identifier":"satelliteSource",
"displayString": "Satellite estimates",
return {"identifier":"satelliteGaugesSource",
"displayString": "Satellite estimates and gauge reports",
return {"identifier":"gaugesSource",
"displayString": "Gauge reports",
return {"identifier":"countySource",
"displayString": "County dispatch"
return {"identifier":"corpsOfEngineersSource",
"displayString": "Corps of Engineers"
return {"identifier":"damOperatorSource",
"displayString": "Dam operator"
return {"identifier":"bureauOfReclamationSource",
"displayString": "Bureau of Reclamation"
return {"identifier":"civilAirPatrolSource",
"displayString": "Civil Air Patrol"
return {"identifier":"cascadesVolcanoSource",
"displayString": "Cascades Volcano Observatory"
Event type values we know about:
return {"identifier":"thunderEvent", "displayString":"Thunderstorm(s)"}
return {"identifier":"rainEvent", "displayString": "Heavy rainfall (no thunder)"}
return {"identifier":"noEventType", "displayString": "None"}
return {"identifier":"minorFlooding", "displayString": "Minor flooding occurring"}
return {"identifier":"flooding", "displayString": "Flooding occurring"}
return { "identifier":"genericFlooding", "displayString": "Generic (provide reasoning)"}
return {"identifier":"flashFlooding", "displayString": "Flash flooding occurring"}
"Groundwater", "Glacial-Dammed Lake Outburst"
For FF.W.NonConvective, the user sees a selector for Hydrologic Cause instead of Immediate Cause. Hydrologic Cause maps to Immediate Cause as follows. The Immediate Cause values implicitly selected via Hydrologic Cause participate in these interdependencies.
'genericImminent': {'immediateCause': 'DM', …
'genericFailed': {'immediateCause': 'DM',...
'siteImminent': {'immediateCause': 'DM',...
'siteFailed': {'immediateCause': 'DM', ...
'levee': {'immediateCause': 'DM', ...
'floodgate': {'immediateCause': 'DR', ...
'glacier': {'immediateCause': 'GO',...
'icejam': {'immediateCause': 'IJ', ...
'ijbreak': {'immediateCause': 'IJ',...
'rain': {'immediateCause': 'RS', ...
'snowMelt': {'immediateCause': 'RS',...
'volcano': {'immediateCause': 'SM', ...
'volcanoLahar': {'immediateCause': 'SM',...
'default': {'immediateCause': 'ER', ...
The text in blue shows the current base version of icEventTypeSourceDefaults(). One can gain some understanding of how this works by reading the comments here. To help with understanding how this works, we explain the meaning of these two lines:
if userChoice in [ "DM", "DR" ] :
return [ "damOperatorSource", "flooding", "noEventType", "genericFlooding"]
These lines apply if one has just now chosen an immediate cause of DM or DR, or a hydrologic cause that maps to one of those immediate causes. There is one source value in the list, "damOperatorSource". In a particular situation, any given value of source may or may not be valid. If that source value is valid, that source will automatically be selected, assuming that the previous choice made just before DM or DR was not to choose a different source. The list returned then contains 3 different event types. Analogous logic will be applied to the first event type in the list that is valid in this particular situation.
# For managing interoperability between source, immediate cause and
# event type. This can be easily shared between interdependency logic
# and metadata classes.
def icEventTypeSourceDefaults(userChoice, hazardType, \
immediateCauseVal=None, eventTypeVal=None, \
sourceVal=None, hydrologicCauseVal=None):
'''
input userChoice is an identifier for either source, immediate
cause, hydrologic cause, or event type choice.
return is list of any number of identifiers representing a choice
for other selectors that will be automatically imposed as a result
of the user making the 'userChoice'. First identifier for a selector that
is actually usable is the one used. The userChoice will always be
the same as one of the input Val's.
Normal behavior is for this defaulting mechanism to NOT change the very last
thing that was selected; a * on the end of a returned default value can override
that.
'''
updates = []
if userChoice in [ "DM", "DR" ] :
return [ "damOperatorSource", "flooding", "noEventType", "genericFlooding"]
if userChoice in [ "IC", "IJ" ] :
return [ "noEventType", "genericFlooding", "emergencyManagementSource" ]
if userChoice=="damOperatorSource" :
return [ "DM", "flooding", "noEventType", "genericFlooding" ]
if userChoice in ["thunderEvent", "rainEvent" ] :
if immediateCauseVal in [ "IJ", "DM", "DR", "GO" ] :
return [ "ER*" ]
if not immediateCauseVal in [ "ER", "RS" ] :
return [ "ER" ]
return []
if userChoice=="dopplerSource" :
if immediateCauseVal in [ "ER", "RS" ] :
return ["default", "thunderEvent", "rainEvent" ]
return ["ER", "default", "thunderEvent", "rainEvent" ]
if userChoice=="GO" :
return [ "GroundWater", "emergencyManagementSource" ]
return updates
For non-convective FFWs, as mentioned, we have the concept of Hydrologic Cause.
Each Hydrologic Cause value maps to one and only one immediate cause value, but some immediate causes are associated with multiple Hydrologic Causes. For example, the IJ immediate cause is associated with 2 hydrologic causes; one for the impounding phase of an ice jam and one for the break phase of an ice jam.
In order to support more seamless evolution of hazards among FF.W, FA.W, and FA.Y, it eventually may be worth exploring migrating the Hydrologic Cause concept to FA.W and FA.Y. To close the circle on this, an implied Hydrologic Cause value would get associated with any convective or burn scar FFW, even if users never directly interoperated with that concept for those hazard types.
If we pursue generalizing the Hydrologic Cause concept for all areal flood hazards, that would not happen anytime in the next couple of major releases; for now it is just something to think about.