Skip to content

Parameters

Alexander Michalek edited this page Aug 1, 2025 · 8 revisions

Parameters File

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.

Required CSV Columns

  • 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 from 0 (leaf nodes) up to the outlet. Used for level-based output and for validating network hierarchy.

  • parents:
    A semicolon-separated list of upstream index for the parent LinkIDs. 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.

Example Parameter File

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

Notes:

  • 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.

Generating the Network

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.

NetworkX Example

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 -1 if 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 levels

Step 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)

Clone this wiki locally