File Formats ============ JSON Model Format ----------------- Input models are JSON files with the following structure: .. code-block:: json { "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 ^^^^^^^^^^^^^^^^ .. code-block:: json { "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: .. code-block:: 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: .. code-block:: python 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: .. code-block:: python 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: .. code-block:: python 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