landlab.components.chi_index.channel_chi¶
Created March 2016.
@author: dejh
- class ChiFinder[source]¶
Bases:
Component
Calculate Chi Indices.
This component calculates chi indices, sensu Perron & Royden, 2013, for a Landlab landscape.
Examples
>>> import numpy as np >>> from landlab import RasterModelGrid >>> from landlab.components import FlowAccumulator, FastscapeEroder >>> from landlab.components import ChiFinder
>>> mg = RasterModelGrid((3, 4)) >>> for nodes in ( ... mg.nodes_at_right_edge, ... mg.nodes_at_bottom_edge, ... mg.nodes_at_top_edge, ... ): ... mg.status_at_node[nodes] = mg.BC_NODE_IS_CLOSED >>> _ = mg.add_field("topographic__elevation", mg.node_x, at="node") >>> fr = FlowAccumulator(mg, flow_director="D8") >>> cf = ChiFinder(mg, min_drainage_area=1.0, reference_concavity=1.0) >>> fr.run_one_step() >>> cf.calculate_chi() >>> mg.at_node["channel__chi_index"].reshape(mg.shape)[1, :] array([0.5, 1. , 2. , 0. ])
>>> mg2 = RasterModelGrid((5, 5), xy_spacing=100.0) >>> for nodes in ( ... mg2.nodes_at_right_edge, ... mg2.nodes_at_bottom_edge, ... mg2.nodes_at_top_edge, ... ): ... mg2.status_at_node[nodes] = mg2.BC_NODE_IS_CLOSED >>> _ = mg2.add_zeros("topographic__elevation", at="node") >>> mg2.at_node["topographic__elevation"][mg2.core_nodes] = ( ... mg2.node_x[mg2.core_nodes] / 1000.0 ... ) >>> np.random.seed(0) >>> mg2.at_node["topographic__elevation"][mg2.core_nodes] += np.random.rand( ... mg2.number_of_core_nodes ... ) >>> fr2 = FlowAccumulator(mg2, flow_director="D8") >>> sp2 = FastscapeEroder(mg2, K_sp=0.01) >>> cf2 = ChiFinder(mg2, min_drainage_area=0.0, reference_concavity=0.5) >>> for i in range(10): ... mg2.at_node["topographic__elevation"][mg2.core_nodes] += 10.0 ... fr2.run_one_step() ... sp2.run_one_step(1000.0) ... >>> fr2.run_one_step() >>> cf2.calculate_chi() >>> mg2.at_node["channel__chi_index"].reshape(mg2.shape) array([[0. , 0. , 0. , 0. , 0. ], [0.77219416, 1.54438833, 2.63643578, 2.61419437, 0. ], [1.09204746, 2.18409492, 1.52214691, 2.61419437, 0. ], [0.44582651, 0.89165302, 1.66384718, 2.75589464, 0. ], [0. , 0. , 0. , 0. , 0. ]])
>>> cf3 = ChiFinder( ... mg2, ... min_drainage_area=20000.0, ... use_true_dx=True, ... reference_concavity=0.5, ... reference_area=mg2.at_node["drainage_area"].max(), ... clobber=True, ... ) >>> cf3.calculate_chi() >>> cf3.chi_indices.reshape(mg2.shape) array([[ 0. , 0. , 0. , 0. , 0. ], [ 0. , 173.20508076, 0. , 0. , 0. ], [ 0. , 0. , 270.71067812, 0. , 0. ], [ 0. , 100. , 236.60254038, 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ]]) >>> cf3.hillslope_mask.reshape(mg2.shape) array([[ True, True, True, True, True], [False, False, True, True, True], [ True, True, False, True, True], [False, False, False, True, True], [ True, True, True, True, True]])
References
Required Software Citation(s) Specific to this Component
None Listed
Additional References
Perron, J., Royden, L. (2012). An integral approach to bedrock river profile analysis Earth Surface Processes and Landforms 38(6), 570-576. https://dx.doi.org/10.1002/esp.3302
- Parameters:
grid (RasterModelGrid) – A landlab RasterModelGrid.
reference_concavity (float) – The reference concavity to use in the calculation.
min_drainage_area (float (m**2)) – The drainage area down to which to calculate chi.
reference_area (float or None (m**2)) – If None, will default to the mean core cell area on the grid. Else, provide a value to use. Essentially becomes a prefactor on the value of chi.
use_true_dx (bool (default False)) – If True, integration to give chi is performed using each value of node spacing along the channel (which can lead to a quantization effect, and is not preferred by Taylor & Royden). If False, the mean value of node spacing along the all channels is assumed everywhere.
clobber (bool (default False)) – Raise an exception if adding an already existing field.
- __init__(grid, reference_concavity=0.5, min_drainage_area=1000000.0, reference_area=1.0, use_true_dx=False, clobber=False)[source]¶
- Parameters:
grid (RasterModelGrid) – A landlab RasterModelGrid.
reference_concavity (float) – The reference concavity to use in the calculation.
min_drainage_area (float (m**2)) – The drainage area down to which to calculate chi.
reference_area (float or None (m**2)) – If None, will default to the mean core cell area on the grid. Else, provide a value to use. Essentially becomes a prefactor on the value of chi.
use_true_dx (bool (default False)) – If True, integration to give chi is performed using each value of node spacing along the channel (which can lead to a quantization effect, and is not preferred by Taylor & Royden). If False, the mean value of node spacing along the all channels is assumed everywhere.
clobber (bool (default False)) – Raise an exception if adding an already existing field.
- static __new__(cls, *args, **kwds)¶
- best_fit_chi_elevation_gradient_and_intercept(ch_nodes=None)[source]¶
Returns least squares best fit for a straight line through a chi plot.
- Parameters:
ch_nodes (array of ints or None) – Nodes at which to consider chi and elevation values. If None, will use all nodes in grid with area greater than the component min_drainage_area.
- Returns:
coeffs – A len-2 array containing the m then z0, where z = z0 + m * chi.
- Return type:
array(gradient, intercept)
Examples
>>> import numpy as np >>> from landlab import RasterModelGrid >>> from landlab.components import FlowAccumulator >>> from landlab.components import ChiFinder >>> mg = RasterModelGrid((3, 4)) >>> for nodes in ( ... mg.nodes_at_right_edge, ... mg.nodes_at_bottom_edge, ... mg.nodes_at_top_edge, ... ): ... mg.status_at_node[nodes] = mg.BC_NODE_IS_CLOSED >>> z = mg.add_field("topographic__elevation", mg.node_x.copy(), at="node") >>> z[4:8] = np.array([0.5, 1.0, 2.0, 0.0]) >>> fr = FlowAccumulator(mg, flow_director="D8") >>> cf = ChiFinder(mg, min_drainage_area=1.0, reference_concavity=1.0) >>> fr.run_one_step() >>> cf.calculate_chi() >>> mg.at_node["channel__chi_index"].reshape(mg.shape)[1, :] array([0.5, 1. , 2. , 0. ]) >>> coeffs = cf.best_fit_chi_elevation_gradient_and_intercept() >>> np.allclose(np.array([1.0, 0.0]), coeffs) True
- calculate_chi()[source]¶
Calculate local chi indices.
This is the main method. Call it to calculate local chi indices at all points with drainage areas greater than min_drainage_area.
Chi of any node without a defined value is reported as 0. These nodes are also identified in the mask retrieved with
hillslope_mask
.
- property chi_indices¶
Return the array of channel steepness indices.
Nodes not in the channel receive zeros.
- cite_as = ''¶
- property coords¶
Return the coordinates of nodes on grid attached to the component.
- create_chi_plot(channel_heads=None, label_axes=True, symbol='kx', plot_line=False, line_symbol='r-')[source]¶
Plots a “chi plot” (chi vs elevation for points in channel network).
If channel_heads is provided, only the channel nodes downstream of the provided points (and with area > min_drainage_area) will be plotted.
- Parameters:
channel_heads (int, list or array of ints, or None) – Node IDs of channel heads to from which plot downstream.
label_axes (bool) – If True, labels the axes as “Chi” and “Elevation (m)”.
symbol (str) – A matplotlib-style string for the style to use for the points.
plot_line (bool) – If True, will plot a linear best fit line through the data cloud.
line_symbol (str) – A matplotlib-style string for the style to use for the line, if plot_line.
- property current_time¶
Current time.
Some components may keep track of the current time. In this case, the
current_time
attribute is incremented. Otherwise it is set to None.- Return type:
current_time
- definitions = (('channel__chi_index', 'the local steepness index'), ('drainage_area', "Upstream accumulated surface area contributing to the node's discharge"), ('flow__link_to_receiver_node', 'ID of link downstream of each node, which carries the discharge'), ('flow__receiver_node', 'Node array of receivers (node that receives flow from current node)'), ('flow__upstream_node_order', 'Node array containing downstream-to-upstream ordered list of node IDs'), ('topographic__elevation', 'Land surface topographic elevation'), ('topographic__steepest_slope', 'The steepest *downhill* slope'))¶
- classmethod from_path(grid, path)¶
Create a component from an input file.
- property grid¶
Return the grid attached to the component.
- property hillslope_mask¶
Return a boolean array, False where steepness indices exist.
- initialize_optional_output_fields()¶
Create fields for a component based on its optional field outputs, if declared in _optional_var_names.
This method will create new fields (without overwrite) for any fields output by the component as optional. New fields are initialized to zero. New fields are created as arrays of floats, unless the component also contains the specifying property _var_type.
- initialize_output_fields(values_per_element=None)¶
Create fields for a component based on its input and output var names.
This method will create new fields (without overwrite) for any fields output by, but not supplied to, the component. New fields are initialized to zero. Ignores optional fields. New fields are created as arrays of floats, unless the component specifies the variable type.
- Parameters:
values_per_element (int (optional)) – On occasion, it is necessary to create a field that is of size (n_grid_elements, values_per_element) instead of the default size (n_grid_elements,). Use this keyword argument to acomplish this task.
- input_var_names = ('drainage_area', 'flow__link_to_receiver_node', 'flow__receiver_node', 'flow__upstream_node_order', 'topographic__elevation', 'topographic__steepest_slope')¶
- integrate_chi_avg_dx(valid_upstr_order, chi_integrand, chi_array, mean_dx)[source]¶
Calculates chi at each channel node by summing chi_integrand.
This method assumes a uniform, mean spacing between nodes. Method is deliberately split out for potential cythonization at a later stage.
- Parameters:
valid_upstr_order (array of ints) – nodes in the channel network in upstream order.
chi_integrand (array of floats) – The value (A0/A)**concavity, in upstream order.
chi_array (array of floats) – Array in which to store chi.
mean_dx (float) – The mean node spacing in the network.
Examples
>>> import numpy as np >>> from landlab import RasterModelGrid >>> from landlab.components import FlowAccumulator >>> from landlab.components import ChiFinder >>> mg = RasterModelGrid((5, 4)) >>> for nodes in ( ... mg.nodes_at_right_edge, ... mg.nodes_at_bottom_edge, ... mg.nodes_at_top_edge, ... ): ... mg.status_at_node[nodes] = mg.BC_NODE_IS_CLOSED >>> z = mg.node_x.copy() >>> z[[5, 13]] = z[6] # guard nodes >>> _ = mg.add_field("topographic__elevation", z, at="node") >>> fr = FlowAccumulator(mg, flow_director="D8") >>> cf = ChiFinder(mg) >>> fr.run_one_step() >>> ch_nodes = np.array([4, 8, 12, 5, 9, 13, 6, 10, 14]) >>> ch_integrand = 3.0 * np.ones(9, dtype=float) # to make calc clearer >>> chi_array = np.zeros(mg.number_of_nodes, dtype=float) >>> cf.integrate_chi_avg_dx(ch_nodes, ch_integrand, chi_array, 0.5) >>> chi_array.reshape(mg.shape) array([[0. , 0. , 0. , 0. ], [1.5, 3. , 4.5, 0. ], [1.5, 3. , 4.5, 0. ], [1.5, 3. , 4.5, 0. ], [0. , 0. , 0. , 0. ]])
- integrate_chi_each_dx(valid_upstr_order, chi_integrand_at_nodes, chi_array)[source]¶
Calculates chi at each channel node by summing chi_integrand*dx.
This method accounts explicitly for spacing between each node. Method is deliberately split out for potential cythonization at a later stage. Uses a trapezium integration method.
- Parameters:
valid_upstr_order (array of ints) – nodes in the channel network in upstream order.
chi_integrand_at_nodes (array of floats) – The value (A0/A)**concavity, in node order.
chi_array (array of floats) – Array in which to store chi.
Examples
>>> import numpy as np >>> from landlab import RasterModelGrid >>> from landlab.components import FlowAccumulator >>> from landlab.components import ChiFinder >>> mg = RasterModelGrid((5, 4), xy_spacing=3.0) >>> for nodes in ( ... mg.nodes_at_right_edge, ... mg.nodes_at_bottom_edge, ... mg.nodes_at_top_edge, ... ): ... mg.status_at_node[nodes] = mg.BC_NODE_IS_CLOSED >>> z = mg.node_x.copy() >>> z[[5, 13]] = z[6] # guard nodes >>> _ = mg.add_field("topographic__elevation", z, at="node") >>> fr = FlowAccumulator(mg, flow_director="D8") >>> cf = ChiFinder(mg) >>> fr.run_one_step() >>> ch_nodes = np.array([4, 8, 12, 5, 9, 13, 6, 10, 14]) >>> ch_integrand = 2.0 * np.ones( ... mg.number_of_nodes, dtype=float ... ) # to make calc clearer >>> chi_array = np.zeros(mg.number_of_nodes, dtype=float) >>> cf.integrate_chi_each_dx(ch_nodes, ch_integrand, chi_array) >>> chi_array.reshape(mg.shape) array([[ 0. , 0. , 0. , 0. ], [ 0. , 6. , 14.48528137, 0. ], [ 0. , 6. , 12. , 0. ], [ 0. , 6. , 14.48528137, 0. ], [ 0. , 0. , 0. , 0. ]]) >>> from landlab.components import FastscapeEroder >>> mg2 = RasterModelGrid((5, 5), xy_spacing=100.0) >>> for nodes in ( ... mg2.nodes_at_right_edge, ... mg2.nodes_at_bottom_edge, ... mg2.nodes_at_top_edge, ... ): ... mg2.status_at_node[nodes] = mg2.BC_NODE_IS_CLOSED >>> _ = mg2.add_zeros("topographic__elevation", at="node") >>> mg2.at_node["topographic__elevation"][mg2.core_nodes] = ( ... mg2.node_x[mg2.core_nodes] / 1000.0 ... ) >>> np.random.seed(0) >>> mg2.at_node["topographic__elevation"][mg2.core_nodes] += np.random.rand( ... mg2.number_of_core_nodes ... ) >>> fr2 = FlowAccumulator(mg2, flow_director="D8") >>> sp2 = FastscapeEroder(mg2, K_sp=0.01) >>> cf2 = ChiFinder( ... mg2, min_drainage_area=1.0, reference_concavity=0.5, use_true_dx=True ... ) >>> for i in range(10): ... mg2.at_node["topographic__elevation"][mg2.core_nodes] += 10.0 ... fr2.run_one_step() ... sp2.run_one_step(1000.0) ... >>> fr2.run_one_step() >>> output_array = np.zeros(25, dtype=float) >>> cf2.integrate_chi_each_dx( ... mg2.at_node["flow__upstream_node_order"], ... np.ones(25, dtype=float), ... output_array, ... ) >>> output_array.reshape(mg2.shape) array([[ 0. , 0. , 0. , 0. , 0. ], [ 0. , 100. , 200. , 382.84271247, 0. ], [ 0. , 100. , 241.42135624, 341.42135624, 0. ], [ 0. , 100. , 200. , 300. , 0. ], [ 0. , 0. , 0. , 0. , 0. ]])
- property masked_chi_indices¶
Returns a masked array version of the ‘channel__chi_index’ field. This enables easier plotting of the values with.
landlab.imshow_grid_at_node
or similar.Examples
Make a topographic map with an overlay of chi values:
>>> from landlab import imshow_grid_at_node >>> from landlab import RasterModelGrid >>> from landlab.components import FlowAccumulator, FastscapeEroder >>> from landlab.components import ChiFinder >>> mg = RasterModelGrid((5, 5), xy_spacing=100.0) >>> for nodes in ( ... mg.nodes_at_right_edge, ... mg.nodes_at_bottom_edge, ... mg.nodes_at_top_edge, ... ): ... mg.status_at_node[nodes] = mg.BC_NODE_IS_CLOSED >>> _ = mg.add_zeros("topographic__elevation", at="node") >>> mg.at_node["topographic__elevation"][mg.core_nodes] = ( ... mg.node_x[mg.core_nodes] / 1000.0 ... ) >>> np.random.seed(0) >>> mg.at_node["topographic__elevation"][mg.core_nodes] += np.random.rand( ... mg.number_of_core_nodes ... ) >>> fr = FlowAccumulator(mg, flow_director="D8") >>> sp = FastscapeEroder(mg, K_sp=0.01) >>> cf = ChiFinder(mg, min_drainage_area=20000.0) >>> for i in range(10): ... mg.at_node["topographic__elevation"][mg.core_nodes] += 10.0 ... fr.run_one_step() ... sp.run_one_step(1000.0) ... >>> fr.run_one_step() >>> cf.calculate_chi()
>>> imshow_grid_at_node(mg, "topographic__elevation", allow_colorbar=False) >>> imshow_grid_at_node( ... mg, cf.masked_chi_indices, color_for_closed=None, cmap="winter" ... )
- mean_channel_node_spacing(ch_nodes)[source]¶
Calculates the mean spacing between all adjacent channel nodes.
- Parameters:
ch_nodes (array of ints) – The nodes within the defined channel network.
- Returns:
mean_spacing – The mean spacing between all nodes in the network.
- Return type:
float (m)
Examples
>>> import numpy as np >>> from landlab import RasterModelGrid >>> from landlab.components import FlowAccumulator >>> from landlab.components import ChiFinder >>> mg = RasterModelGrid((5, 4), xy_spacing=2.0) >>> for nodes in ( ... mg.nodes_at_right_edge, ... mg.nodes_at_bottom_edge, ... mg.nodes_at_top_edge, ... ): ... mg.status_at_node[nodes] = mg.BC_NODE_IS_CLOSED >>> z = mg.node_x.copy() >>> z[[5, 13]] = z[6] # guard nodes >>> _ = mg.add_field("topographic__elevation", z, at="node") >>> fr = FlowAccumulator(mg, flow_director="D8") >>> cf = ChiFinder(mg) >>> fr.run_one_step() >>> ch_nodes = np.array([4, 8, 12, 5, 9, 13, 6, 10, 14]) >>> cf.mean_channel_node_spacing(ch_nodes) 2.2761423749153966
- name = 'ChiFinder'¶
- nodes_downstream_of_channel_head(channel_head)[source]¶
Find and return an array with nodes downstream of channel_head.
- Parameters:
channel_head (int) – Node ID of channel head from which to get downstream nodes.
Examples
>>> import numpy as np >>> from landlab import RasterModelGrid >>> from landlab.components import FlowAccumulator, ChiFinder >>> mg = RasterModelGrid((3, 4)) >>> for nodes in ( ... mg.nodes_at_right_edge, ... mg.nodes_at_bottom_edge, ... mg.nodes_at_top_edge, ... ): ... mg.status_at_node[nodes] = mg.BC_NODE_IS_CLOSED >>> z = mg.add_field("topographic__elevation", mg.node_x.copy(), at="node") >>> z[4:8] = np.array([0.5, 1.0, 2.0, 0.0]) >>> fr = FlowAccumulator(mg, flow_director="D8") >>> fr.run_one_step() >>> mg.at_node["flow__receiver_node"] array([ 0, 1, 2, 3, 4, 4, 5, 7, 8, 9, 10, 11]) >>> cf = ChiFinder(mg, min_drainage_area=0.0, reference_concavity=1.0) >>> cf.calculate_chi() >>> cf.nodes_downstream_of_channel_head(6) [6, 5, 4]
- optional_var_names = ()¶
- output_var_names = ('channel__chi_index',)¶
- property shape¶
Return the grid shape attached to the component, if defined.
- unit_agnostic = True¶
- units = (('channel__chi_index', 'variable'), ('drainage_area', 'm**2'), ('flow__link_to_receiver_node', '-'), ('flow__receiver_node', '-'), ('flow__upstream_node_order', '-'), ('topographic__elevation', 'm'), ('topographic__steepest_slope', '-'))¶
- classmethod var_definition(name)¶
Get a description of a particular field.
- Parameters:
name (str) – A field name.
- Returns:
A description of each field.
- Return type:
tuple of (name, *description*)
- classmethod var_help(name)¶
Print a help message for a particular field.
- Parameters:
name (str) – A field name.
- classmethod var_loc(name)¶
Location where a particular variable is defined.
- var_mapping = (('channel__chi_index', 'node'), ('drainage_area', 'node'), ('flow__link_to_receiver_node', 'node'), ('flow__receiver_node', 'node'), ('flow__upstream_node_order', 'node'), ('topographic__elevation', 'node'), ('topographic__steepest_slope', 'node'))¶