File Formats

JSON Model Format

Input models are JSON files with the following structure:

{
  "reach_name": "String",
  "discharge": 500.0,
  "manning_n": 0.035,
  "cross_sections": [
    {
      "station": 0.0,
      "elevation": 100.0,
      "coordinates": [[0, 100], [10, 105], [20, 100]]
    }
  ]
}

Field Descriptions

reach_name (string)

Description of reach or project name

discharge (float)

Flow rate in cubic feet per second (cfs)

manning_n (float)

Manning’s roughness coefficient (0.02-0.08 typical)

cross_sections (list)

Array of cross-section objects

station (float)

Distance along reach centerline

elevation (float)

Channel bed elevation (datum)

coordinates (list of [x, z] pairs)

Channel geometry points (x = lateral distance, z = elevation)

Complete Example

{
  "reach_name": "Example Reach - Section 1",
  "discharge": 500.0,
  "manning_n": 0.035,
  "cross_sections": [
    {
      "station": 0.0,
      "elevation": 100.0,
      "coordinates": [
        [0, 100.0],
        [5, 102.0],
        [10, 104.0],
        [15, 102.0],
        [20, 100.0]
      ]
    },
    {
      "station": 100.0,
      "elevation": 99.5,
      "coordinates": [
        [0, 99.5],
        [5, 101.5],
        [10, 103.5],
        [15, 101.5],
        [20, 99.5]
      ]
    }
  ]
}

CSV Output Format

Results can be exported as CSV:

station,elevation,wse,velocity,depth,froude,friction_slope
0.0,100.0,102.5,1.23,2.5,0.45,0.0015
100.0,99.5,102.0,1.25,2.5,0.45,0.0016

Columns

station

Distance along reach

elevation

Channel bed elevation

wse

Water surface elevation

velocity

Average cross-section velocity

depth

Water depth (WSE - elevation)

froude

Froude number (V / sqrt(g*d))

friction_slope

Energy slope

HEC-RAS Import

Cross-sections can be extracted from HEC-RAS projects using the parser module:

from pyhnhtools.parsers import parse_ras_geometry

# Extract geometry from HEC-RAS project
reach_data = parse_ras_geometry('project.ras', 'Reach Name')

# Convert to pyhnhtools format
model_dict = {
    'reach_name': reach_data['name'],
    'discharge': 500.0,
    'manning_n': 0.035,
    'cross_sections': reach_data['sections']
}

GIS Integration

Cross-sections from GIS can be prepared using:

  1. Export from GIS: Cross-section line and DEM

  2. Sample DEM: Get elevation at regular intervals

  3. Convert to coordinates: Build (x, z) list

  4. Create JSON: Format for pyhnhtools

Python script example:

import json

# Sample cross-section from raster
xs_coordinates = []
for x_dist in range(0, 20, 1):
    z = sample_dem(x_dist, y_position)
    xs_coordinates.append([x_dist, z])

cs = {
    'station': 0.0,
    'elevation': min([z for x, z in xs_coordinates]),
    'coordinates': xs_coordinates
}

Best Practices

Coordinate System

  • Use consistent units (feet or meters)

  • Station along centerline

  • Cross-section coordinates perpendicular to flow

Elevation Data

  • Use surveyed data when available

  • Reference to common datum

  • Document units and datum

Manning’s n

  • Use calibration data if available

  • Research typical values for channel type

  • Consider seasonal variation

Cross-section Spacing

  • Closer spacing for rapidly varying geometry

  • 50-100 feet for uniform channels

  • Denser near structures or transitions

Validation

Before running solver, verify:

  • ✓ All fields present and non-empty

  • ✓ Discharge > 0

  • ✓ Manning’s n in reasonable range

  • ✓ Cross-sections ordered by station

  • ✓ Elevations consistent units

  • ✓ Coordinates define valid geometry

  • ✓ No missing or corrupt data

Python validation example:

def validate_model(model):
    assert model['discharge'] > 0
    assert 0.01 < model['manning_n'] < 0.1
    assert len(model['cross_sections']) >= 2
    for cs in model['cross_sections']:
        assert len(cs['coordinates']) >= 3
    return True