-
Notifications
You must be signed in to change notification settings - Fork 1
Parameters
Model parameters are supplied via a CSV file specified in config.yaml under the parameters.filename field. This file defines both the network structure and the routing parameters for each stream link.
While the network topology can be generated by any preprocessing tool, the stream levels must follow a strict hierarchical order:
Level 0 corresponds to the leaves of the network (i.e., headwater streams), and levels must increment consecutively up to the outlet (the highest level).
Refer to the background documentation for more on the stream network structure.
-
index:
A sequential index representing the solve order of stream links, starting at 0. This determines the order of operations and result storage.
Must follow topological order (i.e., all parents of a link appear before the link itself). -
node:
The unique identifier (LinkID) for each stream link. -
level:
The stream level, starting from0(leaf nodes) up to the outlet. Used for level-based output and for validating network hierarchy. -
parents:
A semicolon-separated list of upstreamindexfor the parentLinkIDs. Leave blank for level 0 nodes (no upstream). -
params:
Semicolon-separated routing parameters for each stream link in the format:
A_h; L; λ₁; v₀
where:-
A_h= Hillslope area (m²) ranges from (0,Inf). -
L= Link length (m) ranges from (0,Inf). -
λ₁= Discharge exponent (unitless) ranges from [0, 1). -
v₀= Reference velocity (m/s) ranges from (0,Inf).
NOTE: All parameters must be positive and not zero.
λ₁cannot be 1. -
index,node,level,parents,params
0,1001,0,,500.0;300.0;0.1;0.5
1,1002,0,,450.0;280.0;0.1;0.5
2,2001,1,0;1,950.0;500.0;0.2;0.6
3,3000,2,2,1100.0;700.0;0.25;0.7- The file must be sorted by index, not node, to maintain correct evaluation order.
- Use consistent formatting—no extra whitespace or trailing semicolons in the parents or params fields.
- Units must match model expectations (e.g., SI units unless otherwise specified).
- This file is critical for correct model operation; invalid structure may result in runtime errors or incorrect routing behavior.
As previously stated, any preprocessing tool can be utilized to generate the stream topology. However, we recommend the Python package NetworkX due to its robust tools for graph traversal, hierarchy construction, and topological sorting — all essential for preparing routing input.
Below is an example of how to use NetworkX to generate the parameter CSV structure shown earlier.
This example assumes you have a DataFrame df (typically taken from a shapefile or geopackage) with at least two columns:
-
stream: Unique ID for each stream link -
next_stream: The downstream link (or-1if it's the outlet)
Step 0: Libraries
import networkx as nx
from collections import defaultdict
import pandas as pd
df = pd.DataFrame({
"stream": [1001, 1002, 2001, 3000],
"next_stream": [2001, 2001, 3000, -1],
"A_h": [500.0, 450.0, 950.0, 1100.0],
"L": [300.0, 280.0, 500.0, 700.0],
"lambda_1": [0.1, 0.1, 0.2, 0.25],
"v_0": [0.5, 0.5, 0.6, 0.7]
})
df["params"] = df[["A_h", "L", "lambda_1", "v_0"]].astype(str).agg(";".join, axis=1)Step 1: Define a helper to compute stream levels
def compute_levels(G):
levels = {}
for node in nx.topological_sort(G):
preds = list(G.predecessors(node))
if preds:
levels[node] = max(levels[p] for p in preds) + 1
else:
levels[node] = 0
return levelsStep 2: Build the directed stream network
# Create directed graph
G = nx.DiGraph()
streams_set = set(df['stream']) # ensure not including next streams that are clipped
# Add edges where next_stream is not -1
for _, row in df.iterrows():
src = row['stream']
dst = row['next_stream']
if dst != -1 and dst in streams_set:
G.add_edge(src, dst)
# Add all streams as nodes in case some are disconnected (e.g., with next_stream = -1)
for stream in df['stream'].unique():
G.add_node(stream)Step 3: Compute topological order, levels, and upstream connections
# Get topological order
topo_order = list(nx.topological_sort(G))
node_to_index = {node: i for i, node in enumerate(topo_order)}
# Build upstream map
predecessors = {
node: [node_to_index[p] for p in G.predecessors(node)]
for node in topo_order
}
levels = compute_levels(G)Step 4: Create the parameter file
rows = []
for node in topo_order:
idx = node_to_index[node]
level = levels[node]
parents = predecessors.get(node, [])
params = df['params'][df['stream']==node].values[0]
row = {
"index": idx,
"node": node,
"level": level,
"parents": ";".join(map(str, parents)) if parents else "",
"params": params
}
rows.append(row)
df_out = pd.DataFrame(rows)
df_out = df_out.astype({"index": "int32", "node": "int32", "level": "int32"})
df_out.to_csv("params.csv", index=False)Getting Started
User Guide
- Background
- Compiling
- OpenMP
- Solver
- The YAML File
- Parameters
- Initial Conditions
- Boundary Conditions
- Reservoirs
- Runoff Forcings
- Output Files
Programmer Guide