discretized_misfit: calculate a misfit discretized to patches of the topography¶
-
discretized_misfit
(model_grid, data_grid, name, misfit_field, field_1, field_2, field_1_percentile_edges, field_2_percentile_edges)[source]¶ Calculate a discretized misfit on a Landlab grid field.
The following Binder notebook shows example usage of this umami calculation.
The
discretized_misfit
calculation first classifies each grid cell in the landscape into categories based onfield_1
,field_2
and the percentile edges for each (using the data grid). This results in a set of categories, which may or may not be congiguous in space. This category field is then stored as a property of theResidual
calledResidual.category
.For each category, the sum of squared residuals is calculated based on the
misfit_field
.Since this calculation returns one value for each category, rather than one value in total, a
name
must be provided. This is a string that will be formatted with the values for{field_1_level}
and{field_2_level}
. The output is an ordered dictionary withname
as the keys, and the sum of squares misfit as the values.For example, if
field_1
was thedrainage_area
andfield_2
wastopographic__elevation
, and the parametername
wasda_{field_1_level}_z_{field_2_level}
, then the following four categories would be identified:Name
Contents
da_0_z_0
Cells with the lower half of drainage area, and then within those cells, the lowest half of elevation
da_0_z_1
Cells with the lower half of drainage area, and then within those cells, the higher half of elevation
da_1_z_0
Cells with the higher half of drainage area, and then within those cells, the lowest half of elevation
da_1_z_1
Cells with the higher half of drainage area, and then within those cells, the higher half of elevation
Within each of these four categories, the sum of squared residuals on the
misfit_field
is calculated and returned.- Parameters
model_grid (Landlab model grid) –
data_grid (Landlab model grid) –
name (str) –
misfit_field (str) – An at-node Landlab grid field that is present on the model grid.
field_1 (str) – An at-node Landlab grid field that is present on the model grid.
field_2 (str) – An at-node Landlab grid field that is present on the model grid.
field_1_percentile_edges (list) – A list of percentile edges applied to
field_1
. For example,[0, 60, 100]
specifies splittingfield_1
into two parts, separated at the 60th percentile.field_2_percentile_edges (list) – A list of percentile edges applied to
field_2
. For example,[0, 60, 100]
specifies splittingfield_2
into two parts, separated at the 60th percentile.
- Returns
- Return type
OrderedDict
Examples
First an example that only uses the
discretized_misfit
function.>>> import numpy as np >>> from landlab import RasterModelGrid >>> from landlab.components import FlowAccumulator >>> from umami.calculations import discretized_misfit >>> np.random.seed(42) >>> model = RasterModelGrid((50, 50)) >>> z_model = model.add_zeros("node", "topographic__elevation") >>> z_model += model.x_of_node + model.y_of_node >>> data = RasterModelGrid((50, 50)) >>> z_data = data.add_zeros("node", "topographic__elevation") >>> z_data += data.x_of_node + data.y_of_node >>> z_data[data.core_nodes] += np.random.random(data.core_nodes.shape) >>> data_fa = FlowAccumulator(data) >>> data_fa.run_one_step() >>> model_fa = FlowAccumulator(model) >>> model_fa.run_one_step() >>> cat, out = discretized_misfit( ... model, ... data, ... "da_{field_1_level}_z_{field_2_level}", ... "topographic__elevation", ... "drainage_area", ... "topographic__elevation", ... [0, 50, 100], ... [0, 30, 60, 100]) >>> for key, value in out.items(): ... print(key, np.round(value, decimals=3)) da_0_z_0 0.713 da_0_z_1 0.711 da_0_z_2 0.712 da_1_z_0 0.414 da_1_z_1 0.441 da_1_z_2 0.432 >>> cat[:5] array([0, 0, 0, 0, 0])
Next, the same calculations are shown as part of an umami
Residual
.>>> from io import StringIO >>> from umami import Residual >>> file_like=StringIO(''' ... dm: ... _func: discretized_misfit ... name: da_{field_1_level}_z_{field_2_level} ... misfit_field: topographic__elevation ... field_1: drainage_area ... field_2: topographic__elevation ... field_1_percentile_edges: ... - 0 ... - 50 ... - 100 ... field_2_percentile_edges: ... - 0 ... - 30 ... - 60 ... - 100 ... ''') >>> residual = Residual(model, data) >>> residual.add_from_file(file_like) >>> residual.names ['da_0_z_0', 'da_0_z_1', 'da_0_z_2', 'da_1_z_0', 'da_1_z_1', 'da_1_z_2'] >>> residual.calculate() >>> for key, value in zip(residual.names, residual.values): ... print(key, np.round(value, decimals=3)) da_0_z_0 0.713 da_0_z_1 0.711 da_0_z_2 0.712 da_1_z_0 0.414 da_1_z_1 0.441 da_1_z_2 0.432 >>> residual.category[:5] array([0, 0, 0, 0, 0])