landlab

SpatialPrecipitationDistribution: Generate random sequence of spatially-resolved precipitation events

class SpatialPrecipitationDistribution(grid, number_of_years=1, orographic_scenario=None, max_numstorms=5000)[source]

Bases: landlab.core.model_component.Component

Generate spatially resolved precipitation events.

A component to generate a sequence of spatially resolved storms over a grid, following a lightly modified version (see below) of the stochastic methods of Singer & Michaelides, Env Res Lett 12, 104011, 2017, & Singer et al., Geosci. Model Dev., accepted, 10.5194/gmd-2018-86.

The method is heavily stochastic, and at the present time is intimately calibrated against the conditions at Walnut Gulch, described in those papers. In particular, assumptions around intensity-duration calibration and orographic rainfall are “burned in” for now, and are not accessible to the user. The various probability distributions supplied to the various run methods default to WG values, but are easily modified. This calibration reflects a US desert southwest “monsoonal” climate, and the component distinguishes (optionally) between two seasons, “monsoonal” and “winter”. The intensity-duration relationship is shared between the seasons, and so may prove useful in a variety of storm-dominated contexts.

The default is to disable the orographic rainfall functionality of the component. However, if orographic_scenario == ‘Singer’, the component requires a ‘topographic__elevation’ field to already exist on the grid at the time of instantiation.

The component has two ways of simulating a “year”. This choice is controlled by the ‘limit’ parameter of the yield methods. If limit== ‘total_rainfall’, the component will continue to run until the total rainfall for the season and/or year exceeds a stochastically generated value. This method is directly comparable to the Singer & Michaelides method, but will almost always result in years which are not one calendar year long, unless the input distributions are very carefully recalibrated for each use case. If limit==’total_time’, the component will terminate a season and/or year once the elapsed time exceeds one year. In this case, the total rainfall will not correspond to the stochastically generated total. You can access the actual total for the last season using the property (median_)total_rainfall_last_season.

Note that this component cannot simulate the occurrence of more than one storm at the same time. Storms that should be synchronous will instead occur sequentially, with no interstorm time. This limitation means that if enough storms occur in a year that numstorms*mean_storm_duration exceeds one year, the number of simulated storms will saturate. This limitation may be relaxed in the future.

The component offers the option to modify the maximum number of storms simulated per year. If you find simulations encountering this limit too often, you may need to raise this limit. Conversely, it could be lowered to reduce memory usage over small grids. However, in increasing the value, beware - the component maintains two limit*nnodes arrays, which will chew through memory if the limit gets too high. The default will happily simulate grids up to around 50 km * 50 km using the default probability distributions.

Key methods are:

yield_storms
Generate a timeseries of storm:interstorm duration pairs, alongside a field that describes the spatial distribution of rain during that storm.
yield_years
Generate a timeseries of ints giving number of storms per year, alongside a field that describes the spatial distribution of total rainfall across that year.
yield_seasons
Generate a timeseries of ints giving number of storms per season, alongside a field that describes the spatial distribution of total rainfall across that season.
calc_annual_rainfall
Produce a timeseries of tuples giving total rainfall each season, without resolving the storms spatially (i.e., fast!).

A large number of properties are available to access storm properties during generation:

  • current_year
  • current_season
  • storm_depth_last_storm
  • storm_recession_value_last_storm
  • storm_duration_last_storm
  • storm_area_last_storm
  • storm_intensity_last_storm
  • total_rainfall_this_season
  • total_rainfall_this_year
  • total_rainfall_last_season
  • total_rainfall_last_year
  • median_total_rainfall_this_season
  • median_total_rainfall_this_year
  • median_total_rainfall_last_season
  • median_total_rainfall_last_year
  • number_of_nodes_under_storm
  • nodes_under_storm
  • target_median_total_rainfall_this_season

Note that becuase these are medians not means, median_total_rainfall_last_season + median_total_rainfall_this_season != median_total_rainfall_this_year.

Significant differences between this component and the Singer code are:

  • The component does not model evapotranspiration. Use a separate
    Landlab component for this.
  • The component runs only over a LL grid; there is no such thing as a
    validation or simulation run.
  • It produces “fuzz” around intensity values using a continuous
    distribution; Singer does this with integer steps.
  • Step changes mid-run cannot be explicitly modelled. Instead, run the
    component for a fixed duration, make the change to the distribution input parameter, then run it again.
  • Storms can be centred at any spatial coordinate, not just over nodes.
  • Edge buffering is now dynamic; i.e., big storms have a bigger edge
    buffer than smaller storms. Storms can be centered off the grid edges.
  • Storms are never discarded - once a storm is drawn, it must hit the
    catchment, and positions are repeatedly selected until this can happen. Singer’s method would discard such a storm and draw a new one.
  • Durations are not rescaled to ensure both total duration and total
    precip are both satisfied at the same time, as in Singer’s method. Instead, the component either matches a year’s duration, or exactly a year’s worth of rain. This choice is dictated by the limit parameter in the yield methods.

Examples

>>> import numpy as np
>>> from landlab import RasterModelGrid, VoronoiDelaunayGrid
>>> mg = RasterModelGrid((10, 10), xy_spacing=1000.)
>>> rain = SpatialPrecipitationDistribution(mg)

Calling yield_storms will produce storm-interstorm duration (hr) pairs until the model runtime has elapsed.

>>> np.random.seed(1)
>>> total_t_each_step = [
...     (storm+interstorm) for (storm, interstorm) in rain.yield_storms()]
>>> len(total_t_each_step)
41
>>> np.isclose(sum(total_t_each_step)/24., 365.)
True

The actual rainfall intensities during that interval are accessible in the ‘rainfall__flux’ field (mm/hr). The storm centre does not have to be over the grid, but in this case, it was for the last simulated storm:

>>> mg.at_node['rainfall__flux'].argmax()
80

We can also run the component for only one season (i.e., only using one of the pdf sets describing the storm properties):

>>> for field in ('rainfall__flux', 'rainfall__total_depth_per_year'):
...     _ = mg.at_node.pop(field)  # clear out the existing fields
>>> rain = SpatialPrecipitationDistribution(mg, number_of_years=2)
>>> np.random.seed(5)
>>> total_t_each_step = [
...     (storm+interstorm) for (storm, interstorm) in rain.yield_storms(
...         style='monsoonal', monsoon_fraction_of_year=0.35)]
>>> np.isclose(sum(total_t_each_step)/24./365./2., 0.35)
True

Note this behaviour can be stopped by upping monsoon_fraction_of_year:

>>> np.random.seed(5)
>>> total_t_each_step = [
...     (storm+interstorm) for (storm, interstorm) in rain.yield_storms(
...         style='monsoonal', monsoon_fraction_of_year=1.)]
>>> np.isclose(round(sum(total_t_each_step)/24./365./2., 2), 1.)
True

yield_years yields the number of storms in the last whole year. Use ‘rainfall__total_depth_per_year’ to access the rainfall map for the last fully elapsed year, or equivalently, the total_rainfall_last_year property. Note the component seamlessly handles non-raster grid types:

>>> vdg = VoronoiDelaunayGrid(np.random.rand(100)*1000.,
...                           np.random.rand(100)*1000.)
>>> np.random.seed(3)
>>> rain = SpatialPrecipitationDistribution(vdg, number_of_years=3)
>>> storms_each_year = []
>>> for total_storms in rain.yield_years(style='monsoonal',
...                                      total_rf_trend=0.05,
...                                      storminess_trend=-0.02):
...     storms_each_year.append(total_storms)
...     assert(np.all(np.equal(
...         vdg.at_node['rainfall__total_depth_per_year'],
...         rain.total_rainfall_last_year)))
>>> sum(storms_each_year)
11

yield_seasons yields rainfall statistics for individual seasons. Access these using the various provided component properties. Note that we can get the component to yield a total rainfall that is calibrated to the supplied total_rf_gaussians if we set limit to ‘total__rainfall’ rather than ‘total_time’ (at the cost of exactly matching the season length):

>>> for field in ('rainfall__flux', 'rainfall__total_depth_per_year'):
...     _ = mg.at_node.pop(field)  # clear out the existing fields
>>> rain = SpatialPrecipitationDistribution(mg, number_of_years=2)
>>> np.random.seed(5)
>>> season_list = []
>>> theoretical_median_rf_season = []
>>> median_rf_season = []
>>> median_rf_last_year = []
>>> mean_rf_season = []
>>> mean_rf_last_year = []
>>> for storm_number in rain.yield_seasons(limit='total_rainfall'):
...     season_list.append(rain.current_season)
...     theoretical_median_rf_season.append(
...         rain.target_median_total_rainfall_this_season)
...     median_rf_season.append(rain.median_total_rainfall_this_season)
...     median_rf_last_year.append(rain.median_total_rainfall_last_year)
...     mean_rf_season.append(rain.total_rainfall_this_season.mean())
...     mean_rf_last_year.append(rain.total_rainfall_last_year.mean())
>>> season_list == ['M', 'W', 'M', 'W']
True
>>> [meas > sim for (meas, sim) in zip(
...     median_rf_season, theoretical_median_rf_season)]  # must exceed
[True, True, True, True]
>>> np.isclose(median_rf_last_year[0], 0.)
True
>>> for season in (0, 2):  # this property must be the same in both seasons
...     np.isclose(median_rf_last_year[season],
...                median_rf_last_year[season + 1])
True
True

Note that because we work here with medians, the seasonal medians don’t sum to the year median, but the means do:

>>> np.isclose(median_rf_last_year[2],
...            median_rf_season[0] + median_rf_season[1])
False
>>> np.isclose(mean_rf_last_year[2],
...            mean_rf_season[0] + mean_rf_season[1])
True

References

Required Software Citation(s) Specific to this Component

Singer, M., Michaelides, K., Hobley, D. (2018). STORM 1.0: a simple, flexible, and parsimonious stochastic rainfall generator for simulating climate and climate change. Geoscientific Model Development 11(9), 3713-3726. https://dx.doi.org/10.5194/gmd-11-3713-2018

Additional References

None Listed

Create the SpatialPrecipitationDistribution generator component.

Parameters:
  • grid (ModelGrid) – A Landlab model grid of any type.
  • number_of_years (int) – The number of years over which to generate storms.
  • orographic_scenario ({None, 'Singer', func}) – Whether to use no orographic rule, or to adopt S&M’s 2017 calibration for Walnut Gulch. Alternatively, provide a function here that turns the provided elevation of the storm center into a length-11 curve weighting to select which orographic scenario to apply.
__init__(grid, number_of_years=1, orographic_scenario=None, max_numstorms=5000)[source]

Create the SpatialPrecipitationDistribution generator component.

Parameters:
  • grid (ModelGrid) – A Landlab model grid of any type.
  • number_of_years (int) – The number of years over which to generate storms.
  • orographic_scenario ({None, 'Singer', func}) – Whether to use no orographic rule, or to adopt S&M’s 2017 calibration for Walnut Gulch. Alternatively, provide a function here that turns the provided elevation of the storm center into a length-11 curve weighting to select which orographic scenario to apply.
calc_annual_rainfall(style='whole_year', monsoon_total_rf_gaussian={'mu': 207.0, 'sigma': 64.0}, winter_total_rf_gaussian={'mu': 1.65, 'sigma': 52.0})[source]

Return a tuple of rainfall totals (mm) for the year, with entries subdividing the yearly total into seasons as appropriate.

Parameters:
  • style (('whole_year', 'monsoonal', 'winter')) – Whether to simulate 2 seasons, or a single season.
  • monsoon_total_rf_gaussian (dict of sigma and mu for the summer) – distribution (if used). Defaults to Walnut Gulch.
  • winter_total_rf_gaussian (dict of sigma and mu for the summer) – distribution (if used). Defaults to Walnut Gulch.
Returns:

tuple – If style==’monsoonal’ or ‘winter’, a len(1) tuple of the total rf. If style==’whole_year’, a len(2) tuple of (monsoon, winter) totals.

Return type:

(first_season_total, [second_season_total])

Examples

>>> mg = RasterModelGrid((10, 10), xy_spacing=500.)
>>> z = mg.add_zeros("topographic__elevation", at="node")
>>> rain = SpatialPrecipitationDistribution(mg)
>>> mytotals = []
>>> for yr in range(5):
...     mytotals.append(rain.calc_annual_rainfall(style='whole_year'))
>>> [len(x) == 2 for x in mytotals]
[True, True, True, True, True]
>>> mytotals = []
>>> for yr in range(3):
...     mytotals.append(rain.calc_annual_rainfall(style='monsoonal'))
>>> [len(x) == 1 for x in mytotals]
[True, True, True]
coordinates_of_last_storm_center

Get the coordinates of the center of the last storm as (x, y).

current_season

Get the current season.

‘M’ is monsoon, ‘W’ is winter.

current_year

Get the current year as an int.

median_total_rainfall_last_season

Get the median total rainfall recorded over the open nodes of the grid during the last (completed) simulated season (mm).

median_total_rainfall_last_year

Get the median total rainfall recorded over the open nodes of the grid during the last (completed) simulated year (mm).

median_total_rainfall_this_season

Get the accumulated median total rainfall over the open nodes of the grid so far this season (mm).

median_total_rainfall_this_year

Get the accumulated median total rainfall over the open nodes of the grid so far this year (mm).

nodes_under_storm

Get the IDs of the nodes under the last storm.

number_of_nodes_under_storm

Get the number of nodes under the last storm.

storm_area_last_storm

Get the area (in m**2) of the last storm.

storm_depth_last_storm

Get the maximum storm depth during the last storm (mm).

storm_duration_last_storm

Get the duration (in hrs) of the last storm.

storm_intensity_last_storm

Get the intensity (mm/hr) of the last storm, averaged under the storm.

footprint. Note that duration * intensity != storm max depth.

storm_recession_value_last_storm

Get the recession parameter (radial die-off) for the last storm.

target_median_total_rainfall_this_season

Get the stochastically generated “target” average total rainfall amount over the catchment for the current season.

If limit == ‘total_rainfall’, this will be very close to median_total_rainfall_last_season. If ‘total_time’, it will diverge from this value.

total_rainfall_last_season

Get the total recorded rainfall over the last (completed) simulated season, spatially resolved (mm).

total_rainfall_last_year

Get the total recorded rainfall over the last (completed) simulated year, spatially resolved (mm).

Equivalent to the field ‘rainfall__total_depth_per_year’.

total_rainfall_this_season

Get the accumulated, spatially resolved total rainfall over the grid for the season so far (mm).

total_rainfall_this_year

Get the accumulated, spatially resolved total rainfall over the grid for the year so far (mm).

yield_seasons(limit='total_time', style='whole_year', total_rf_trend=0.0, storminess_trend=0.0, monsoon_fraction_of_year=0.42, monsoon_total_rf_gaussian={'mu': 207.0, 'sigma': 64.0}, monsoon_storm_duration_GEV={'mu': 34.1409, 'shape': -0.570252, 'sigma': 35.7389, 'trunc_interval': (1.0, 1040.0)}, monsoon_storm_area_GEV={'mu': 122419000.0, 'shape': 0.0, 'sigma': 28387600.0, 'trunc_interval': (5000000.0, 300000000.0)}, monsoon_storm_interarrival_GEV={'mu': 10.6108, 'shape': -0.807971, 'sigma': 9.4957, 'trunc_interval': (0.0, 720.0)}, monsoon_storm_radial_weakening_gaussian={'mu': 0.25, 'sigma': 0.08, 'trunc_interval': (0.15, 0.67)}, winter_total_rf_gaussian={'mu': 1.65, 'sigma': 52.0}, winter_storm_duration_fisk={'c': 1.0821, 'scale': 68.4703, 'trunc_interval': (1.0, 5000.0)}, winter_storm_area_GEV={'mu': 122419000.0, 'shape': 0.0, 'sigma': 28387600.0, 'trunc_interval': (5000000.0, 300000000.0)}, winter_storm_interarrival_GEV={'mu': 47.4944, 'shape': 1.1131, 'sigma': 53.2671, 'trunc_interval': (0.0, 720.0)}, winter_storm_radial_weakening_gaussian={'mu': 0.25, 'sigma': 0.08, 'trunc_interval': (0.15, 0.67)})[source]

Yield a timeseries giving the number if storms occurring each season in a rainfall simulation. Only meaningfully different from yield_years if style==’whole_year’.

All default distributions specified as parameters reflect values for Walnut Gulch, see Singer & Michaelides, 2017 & Singer et al, submitted.

Parameters:
  • limit (('total_time', 'total_rainfall')) – Controls whether a season is defined based on its total rainfall (and can be any length), or by its duration (and can have any amount of rainfall). If ‘total_time’, monsoon_fraction_of_year sets the fraction of a year occupied by the monsoon.
  • style (('whole_year', 'monsoonal', 'winter')) – Controls whether the component seeks to simulate a western US- style “monsoonal” climate, a western US-style winter climate, or a full year combining both. These distributions are by default based on Singer et al.’s calibrations. Note if ‘monsoonal’, the total duration of a “year” will appear to be only monsoon_fraction_of_year, and the opposite for winter.
  • total_rf_trend (float) – Controls if a drift is applied to the total rainfall distribution through time. If 0., no trend. If positive, rainfall totals increase gradually through time. If negative, they fall through time. S&M recommend +/- 0.07 for a realistic climate chage driven drift at Walnut Gulch.
  • storminess_trend (float) – Controls if a drift is applied to the expected intensity of individual storms through time. If 0., no trend. If positive, storms get more intense through time, if negative, less so. S&M recommend +/- 0.01 for a realistic climate change driven drift at Walnut Gulch.
  • monsoon_fraction_of_year (float) – If limit == ‘total_time’, sets the fraction of one year occupied by the monsoon season. If not, ignored. Singer’s monsoon runs from May to September, inclusive, and the default reflects this.
  • is a normal distribution controlling the (monsoon_total_rf_gaussian) – total rainfall expected in each year. S&M use ‘mu’ in {143., 271.} for step changes up/down in rainfall totals. In mm.
  • is a generalised extreme value distribution (winter_storm_area_GEV) – controlling the duration of each storm. In MIN.
  • is a generalised extreme value distribution – controlling the plan view area of each storm. S&M use ‘shape’: 0., which collapses the distribution to a plain extreme value distribution.
  • is a generalised extreme value (winter_storm_interarrival_GEV) – distribution controlling the interarrival time between each storm. In HRS. Note that this calibration is specifically to Walnut Gulch, which has an area of 275 km**2. The generator directly scales this resulting distribution to the area ratio of Walnut Gulch to the open cells of the grid. This crudely accounts for the fact that bigger catchments will have more storms, but note that the heavy tail on this distribution means the default distribution shape will not be trustworthy for catchments with big differences in size from Walnut Gulch.
  • is a normal distribution (winter_storm_radial_weakening_gaussian) – controlling the rate of intensity decline with distance from storm center. For more detail see Rodriguez-Iturbe et al., 1986; Morin et al., 2005.
  • is a normal distribution controlling the total (winter_total_rf_gaussian) – rainfall expected in each year. S&M use ‘mu’ in {143., 271.} for step changes up/down in rainfall totals.
  • is a Fisk (i.e., log-logistic) distribution (winter_storm_duration_fisk) – controlling the duration of each storm. Note this differs from the summer scaling. In MIN.
  • is a generalised extreme value distribution – controlling the plan view area of each storm. S&M use ‘shape’: 0., which collapses the distribution to a plain extreme value distribution.
  • is a generalised extreme value – distribution controlling the interarrival time between each storm. In HRS. The same considerations apply here as for the monsoonal interstorm equivalent.
  • is a normal distribution – controlling the rate of intensity decline with distance from storm center. For more detail see Rodriguez-Iturbe et al., 1986; Morin et al., 2005.
Yields:
  • number_of_storms_per_season (float) – Float that gives the number of storms simulated in the season that elapsed since the last yield. The rainfall__total_depth_per_year field gives the total accumulated rainfall depth during the year preceding the yield, so far. rainfall__flux gives the rainfall intensity of the last storm in that year.
  • NB (Use the component property total_rainfall_last_season to access) – the actual amount of rainfall in the season that has the number of storms that the method generates.
yield_storms(limit='total_time', style='whole_year', total_rf_trend=0.0, storminess_trend=0.0, monsoon_fraction_of_year=0.42, monsoon_total_rf_gaussian={'mu': 207.0, 'sigma': 64.0}, monsoon_storm_duration_GEV={'mu': 34.1409, 'shape': -0.570252, 'sigma': 35.7389, 'trunc_interval': (0.0, 1040.0)}, monsoon_storm_area_GEV={'mu': 122419000.0, 'shape': 0.0, 'sigma': 28387600.0, 'trunc_interval': (5000000.0, 300000000.0)}, monsoon_storm_interarrival_GEV={'mu': 10.6108, 'shape': -0.807971, 'sigma': 9.4957, 'trunc_interval': (0.0, 720.0)}, monsoon_storm_radial_weakening_gaussian={'mu': 0.25, 'sigma': 0.08}, winter_total_rf_gaussian={'mu': 1.65, 'sigma': 52.0}, winter_storm_duration_fisk={'c': 1.0821, 'scale': 68.4703, 'trunc_interval': (0.0, 5000.0)}, winter_storm_area_GEV={'mu': 122419000.0, 'shape': 0.0, 'sigma': 28387600.0, 'trunc_interval': (5000000.0, 300000000.0)}, winter_storm_interarrival_GEV={'mu': 47.4944, 'shape': 1.1131, 'sigma': 53.2671, 'trunc_interval': (0.0, 720.0)}, winter_storm_radial_weakening_gaussian={'mu': 0.25, 'sigma': 0.08, 'trunc_interval': (0.15, 0.67)})[source]

Yield a timeseries giving the number of storms occurring each year in a rainfall simulation.

All default distributions specified as parameters reflect values for Walnut Gulch, see Singer & Michaelides, 2017 & Singer et al, submitted.

Parameters:
  • limit (str) – Controls whether a season is defined based on its total rainfall (and can be any length), or by its duration (and can have any amount of rainfall). One of ‘total_time’ or ‘total_rainfall’. If ‘total_time’, monsoon_fraction_of_year sets the fraction of a year occupied by the monsoon.
  • style (str) – Controls whether the component seeks to simulate a western US- style “monsoonal” climate, a western US-style winter climate, or a full year combining both. One of ‘whole_year’, ‘monsoonal’, or ‘winter’ These distributions are by default based on Singer et al.’s calibrations. Note if ‘monsoonal’, the total duration of a “year” will appear to be only monsoon_fraction_of_year, and the opposite for winter.
  • total_rf_trend (float) – Controls if a drift is applied to the total rainfall distribution through time. If 0., no trend. If positive, rainfall totals increase gradually through time. If negative, they fall through time. S&M recommend +/- 0.07 for a realistic climate change driven drift at Walnut Gulch.
  • storminess_trend (float) – Controls if a drift is applied to the expected intensity of individual storms through time. If 0., no trend. If positive, storms get more intense through time, if negative, less so. S&M recommend +/- 0.01 for a realistic climate change driven drift at Walnut Gulch.
  • monsoon_fraction_of_year (float) – If limit == ‘total_time’, sets the fraction of one year occupied by the monsoon season. If not, ignored. Singer’s monsoon runs from May to September, inclusive, and the default reflects this.
  • monsoon_total_rf_gaussian (dict) – Parameters defining the normal distribution controlling the total rainfall expected in each year. S&M use ‘mu’ in {143., 271.} for step changes up/down in rainfall totals.
  • monsoon_storm_duration_GEV (dict) – Parameters defining a generalised extreme value distribution controlling the duration of each storm. In minutes.
  • monsoon_storm_area_GEV (dict) – Parameters defining a generalised extreme value distribution controlling the plan view area of each storm. S&M use ‘shape’: 0., which collapses the distribution to a plain extreme value distribution.
  • monsoon_storm_interarrival_GEV (dict) – Parameters defining a generalised extreme value distribution controlling the interarrival time between each storm. In HRS. Note that this calibration is specifically to Walnut Gulch, which has an area of 275 km**2. The generator directly scales this resulting distribution to the area ratio of Walnut Gulch to the open cells of the grid. This crudely accounts for the fact that bigger catchments will have more storms, but note that the heavy tail on this distribution means the default distribution shape will not be trustworthy for catchments with big differences in size from Walnut Gulch.
  • monsoon_storm_radial_weakening_gaussian (dict) – Parameters defining a normal distribution controlling the rate of intensity decline with distance from storm center. For more detail see Rodriguez-Iturbe et al., 1986; Morin et al., 2005.
  • winter_total_rf_gaussian (dict) – Parameters defining a normal distribution controlling the total rainfall expected in each year. S&M use ‘mu’ in {143., 271.} for step changes up/down in rainfall totals.
  • winter_storm_duration_fisk (dict) – Parameters defining a Fisk (i.e., log-logistic) distribution controlling the duration of each storm. Note this differs from the summer scaling. In Minutes.
  • is a generalised extreme value distribution (winter_storm_area_GEV) – controlling the plan view area of each storm. S&M use ‘shape’: 0., which collapses the distribution to a plain extreme value distribution.
  • winter_storm_interarrival_GEV (dict) – Parameters defining a generalised extreme value distribution controlling the interarrival time between each storm. In HRS. The same considerations apply here as for the monsoonal interstorm equivalent.
  • winter_storm_radial_weakening_gaussian (dict) – Parameters defining a normal distribution controlling the rate of intensity decline with distance from storm center. For more detail see Rodriguez-Iturbe et al., 1986; Morin et al., 2005.
Yields:

(storm_t, interval_t) ((float, float)) – Tuple pair of duration of a single storm, then the interstorm interval that follows it. In hrs. The rainfall__flux field describes the rainfall rate during the interval storm_t as the tuple is yielded. In HRS. Note that the rainfall__total_depth_per_year field gives the total accumulated rainfall depth during the last completed model year, not the year to the point of yield. For the latter, use the property total_rainfall_this_year.

yield_years(limit='total_time', style='whole_year', total_rf_trend=0.0, storminess_trend=0.0, monsoon_fraction_of_year=0.42, monsoon_total_rf_gaussian={'mu': 207.0, 'sigma': 64.0}, monsoon_storm_duration_GEV={'mu': 34.1409, 'shape': -0.570252, 'sigma': 35.7389, 'trunc_interval': (1.0, 1040.0)}, monsoon_storm_area_GEV={'mu': 122419000.0, 'shape': 0.0, 'sigma': 28387600.0, 'trunc_interval': (5000000.0, 300000000.0)}, monsoon_storm_interarrival_GEV={'mu': 10.6108, 'shape': -0.807971, 'sigma': 9.4957, 'trunc_interval': (0.0, 720.0)}, monsoon_storm_radial_weakening_gaussian={'mu': 0.25, 'sigma': 0.08, 'trunc_interval': (0.15, 0.67)}, winter_total_rf_gaussian={'mu': 1.65, 'sigma': 52.0}, winter_storm_duration_fisk={'c': 1.0821, 'scale': 68.4703, 'trunc_interval': (1.0, 5000.0)}, winter_storm_area_GEV={'mu': 122419000.0, 'shape': 0.0, 'sigma': 28387600.0, 'trunc_interval': (5000000.0, 300000000.0)}, winter_storm_interarrival_GEV={'mu': 47.4944, 'shape': 1.1131, 'sigma': 53.2671, 'trunc_interval': (0.0, 720.0)}, winter_storm_radial_weakening_gaussian={'mu': 0.25, 'sigma': 0.08, 'trunc_interval': (0.15, 0.67)})[source]

Yield a timeseries giving the number if storms occurring each year in a rainfall simulation.

All default distributions specified as parameters reflect values for Walnut Gulch, see Singer & Michaelides, 2017 & Singer et al, submitted.

Parameters:
  • limit (('total_time', 'total_rainfall')) – Controls whether a season is defined based on its total rainfall (and can be any length), or by its duration (and can have any amount of rainfall). If ‘total_time’, monsoon_fraction_of_year sets the fraction of a year occupied by the monsoon.
  • style (('whole_year', 'monsoonal', 'winter')) – Controls whether the component seeks to simulate a western US- style “monsoonal” climate, a western US-style winter climate, or a full year combining both. These distributions are by default based on Singer et al.’s calibrations. Note if ‘monsoonal’, the total duration of a “year” will appear to be only monsoon_fraction_of_year, and the opposite for winter.
  • total_rf_trend (float) – Controls if a drift is applied to the total rainfall distribution through time. If 0., no trend. If positive, rainfall totals increase gradually through time. If negative, they fall through time. S&M recommend +/- 0.07 for a realistic climate chage driven drift at Walnut Gulch.
  • storminess_trend (float) – Controls if a drift is applied to the expected intensity of individual storms through time. If 0., no trend. If positive, storms get more intense through time, if negative, less so. S&M recommend +/- 0.01 for a realistic climate change driven drift at Walnut Gulch.
  • monsoon_fraction_of_year (float) – If limit == ‘total_time’, sets the fraction of one year occupied by the monsoon season. If not, ignored. Singer’s monsoon runs from May to September, inclusive, and the default reflects this.
  • is a normal distribution controlling the (monsoon_total_rf_gaussian) – total rainfall expected in each year. S&M use ‘mu’ in {143., 271.} for step changes up/down in rainfall totals. In mm.
  • is a generalised extreme value distribution (winter_storm_area_GEV) – controlling the duration of each storm. In MIN.
  • is a generalised extreme value distribution – controlling the plan view area of each storm. S&M use ‘shape’: 0., which collapses the distribution to a plain extreme value distribution.
  • is a generalised extreme value (winter_storm_interarrival_GEV) – distribution controlling the interarrival time between each storm. In HRS. Note that this calibration is specifically to Walnut Gulch, which has an area of 275 km**2. The generator directly scales this resulting distribution to the area ratio of Walnut Gulch to the open cells of the grid. This crudely accounts for the fact that bigger catchments will have more storms, but note that the heavy tail on this distribution means the default distribution shape will not be trustworthy for catchments with big differences in size from Walnut Gulch.
  • is a normal distribution (winter_storm_radial_weakening_gaussian) – controlling the rate of intensity decline with distance from storm center. For more detail see Rodriguez-Iturbe et al., 1986; Morin et al., 2005.
  • is a normal distribution controlling the total (winter_total_rf_gaussian) – rainfall expected in each year. S&M use ‘mu’ in {143., 271.} for step changes up/down in rainfall totals.
  • is a Fisk (i.e., log-logistic) distribution (winter_storm_duration_fisk) – controlling the duration of each storm. Note this differs from the summer scaling. In MIN.
  • is a generalised extreme value distribution – controlling the plan view area of each storm. S&M use ‘shape’: 0., which collapses the distribution to a plain extreme value distribution.
  • is a generalised extreme value – distribution controlling the interarrival time between each storm. In HRS. The same considerations apply here as for the monsoonal interstorm equivalent.
  • is a normal distribution – controlling the rate of intensity decline with distance from storm center. For more detail see Rodriguez-Iturbe et al., 1986; Morin et al., 2005.
Yields:

number_of_storms_per_year (float) – Float that gives the number of storms simulated in the year that elapsed since the last yield. The rainfall__total_depth_per_year field gives the total accumulated rainfall depth during the year preceding the yield. rainfall__flux gives the rainfall intensity of the last storm in that year.