Skip to content

About

This repository is an unofficial derivative of the TopoIndex utility distributed with the official (USGS) TRIGRS release. It is not an official USGS release and is not sponsored, endorsed, warranted, or maintained by USGS. It implements only the TopoIndex preprocessing workflow.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

TopoIndex Python Adaptation

简体中文 | English | Third-Party and Upstream Notices

Important

This repository is an unofficial derivative of the TopoIndex utility distributed with the official U.S. Geological Survey (USGS) TRIGRS release. It is not an official USGS release and is not sponsored, endorsed, warranted, or maintained by USGS. It implements only the TopoIndex preprocessing workflow; it does not include the complete TRIGRS rainfall-infiltration and slope-stability model.

This adaptation reads DEM and flow-direction rasters with GDAL, exposes part of the original TopoIndex Fortran computation through numpy.f2py, and rewrites part of the raster I/O, logging, and orchestration in Python. Its purpose is to generate downslope-cell, runoff-weight, cell-index, and grid-size inputs used by TRIGRS surface-runoff routing.

Scope

The project can:

  • read single-band DEM and flow-direction rasters supported by GDAL;
  • convert ESRI D8 flow-direction codes to TopoIndex/TRIGRS codes;
  • sort valid cells by elevation and correct their processing order;
  • identify the D8 downslope cell for each valid cell;
  • calculate routing weights using D8, uniform, slope-power, or a D-infinity variant;
  • write georeferenced GeoTIFFs plus TRIGRS text lists and grid-size parameters;
  • call a Fortran core through a prebuilt Windows CPython extension or rebuild it from source.

The project does not:

  • calculate rainfall infiltration, pore pressure, or factor of safety;
  • perform a complete landslide susceptibility or hazard assessment;
  • replace full TRIGRS, its official documentation, engineering judgment, or expert review;
  • guarantee binary or numerical compatibility with every TRIGRS, GDAL, Python, or compiler version.

Relationship to official TRIGRS / TopoIndex

TRIGRS is a Fortran model for the timing and spatial distribution of shallow, rainfall-induced landslides. The official distribution also contains companion utilities including TopoIndex, GridMatch, and UnitConvert. TopoIndex determines runoff-routing relationships from a DEM and flow-direction grid and prepares array sizes and routing weights for TRIGRS.

This repository adapts the TopoIndex portion as follows:

Area Implementation in this repository
Retained and modified computation sindex, nxtcel, slofac, plus parameter-reading and index-order logic separated or reorganized from the original workflow
Python rewrites Raster I/O and conversion corresponding to ssizgrd, srdgrd1, rdflodir, mpfldr, and isvgrd
Added integration topoindex.py orchestration, f2py interfaces, type hints, buffered logging, build scripts, and GeoTIFF output
Not included The complete TRIGRS solver, GridMatch, UnitConvert, official example data, and the full official documentation

Retained source metadata credits the original TopoIndex to Rex L. Baum (USGS). The 1.0.14 / 11May2015 banner currently present in the code identifies the adapted upstream TopoIndex component; it is not a release version assigned to this derivative project.

Official resources:

Processing flow

tpx_in.txt
    │
    ├── parameters, input paths, and output switches
    │
DEM ─┼── GDAL read, valid-cell numbering, elevation sort
    │
flow direction ─┼── GDAL read, optional ESRI D8 conversion
    │
    ├── Fortran: sindex → nxtcel → correct_order → slofac
    │
    └── GeoTIFF / TRIGRS text lists / grid size / log

Repository layout

topo_dev/
├── README.md                         # Chinese documentation
├── README_EN.md                      # English documentation
├── THIRD_PARTY_NOTICES.md            # provenance and redistribution notes
├── topoindex.py                      # Python workflow and public entry point
├── build_topoindex.cmd               # Windows f2py build script
├── build_topoindex.sh                # POSIX build script; loader still needs work
├── src/                              # adapted Fortran sources
├── topo_rewrite/                     # Python raster I/O and conversion
├── topo_utils/                       # logging and error handling
├── topoindex_f2py/
│   ├── __init__.py                   # Windows DLL search path and extension loader
│   ├── topoindex.pyi                 # f2py interface type hints
│   └── topoindex.cp312-win_amd64.pyd # supplied CPython 3.12 / Windows x64 build
└── lib/                              # supplied Windows runtime DLLs

__pycache__/, .idea/, .pyd, and DLL files are cache, development, or platform-specific artifacts. Decide whether to include them in a public release only after completing the relevant binary-license review.

Runtime requirements

Known target environment

Component Requirement or current state
Operating system The supplied prebuilt extension targets 64-bit Windows
Python CPython 3.12; the included .pyd cannot be loaded directly by Python 3.11, 3.13, or another ABI
NumPy Development notes use numpy==1.26.4; NumPy and f2py are required for rebuilding
GDAL The selected Python environment must support from osgeo import gdal
Build toolchain gfortran, Meson, Ninja, and C/Fortran tools compatible with the target Python ABI

Use Python, NumPy, GDAL, and their native libraries from one controlled Conda, OSGeo4W, or equivalent environment. Mixing DLLs from unrelated toolchains is a common cause of load failures.

Windows quick start

To use the supplied extension, install 64-bit CPython 3.12 and compatible NumPy and GDAL packages. A Conda/conda-forge or OSGeo4W environment is usually safer than mixing unrelated native packages manually.

Example environment:

conda create -n topoindex-py312 -c conda-forge python=3.12 numpy=1.26.4 gdal
conda activate topoindex-py312
python -c "from osgeo import gdal; import numpy; print(gdal.VersionInfo(), numpy.__version__)"
python -c "from topoindex_f2py import topoindex; print(topoindex.__file__)"

If python resolves to the Microsoft Store placeholder, use the actual python.exe from the selected environment.

Input requirements

DEM

  • A GDAL-readable, single-band raster;
  • an explicit NODATA value is recommended; the current fallback is -9999.0;
  • square pixels are assumed, and cell size is taken from the absolute X resolution;
  • elevation values are converted to float32 before entering the Fortran core.

Flow-direction raster

  • It must match the DEM in rows, columns, pixel alignment, resolution, extent, and valid/NODATA mask;
  • values are converted to int32;
  • use aif=1 for ESRI D8 codes or aif=2 for TopoIndex codes;
  • current range checks are partial and do not replace a full raster-congruence check.

ESRI-to-TopoIndex code mapping:

Direction ESRI D8 TopoIndex
Northwest 32 1
North 64 2
Northeast 128 3
West 16 4
Center/undefined — 5
East 1 6
Southwest 8 7
South 4 8
Southeast 2 9

tpx_in.txt initialization file

The parser retains the fixed line order used by official TopoIndex: descriptive and value lines alternate. Do not freely insert, remove, or reorder lines. Relative paths are resolved from the directory containing tpx_in.txt.

TopoIndex Python adaptation; project heading
Example project
Flow-direction numbering scheme (ESRI=1, TopoIndex=2)
1
Exponent, Number of iterations
-1, 10
Name of elevation grid file
data/dem.tif
Name of direction grid
data/directions.tif
Save listing of D8 downslope neighbor cells? T/F
T
Save grid of D8 downslope neighbor cells? T/F
T
Save cell index number grid? T/F
T
Save list of cell number and corresponding index number? T/F
T
Save remapped flow-direction grid? T/F
T
Save ridge-crest grid? T/F; Sparse (T) or dense (F)?
F,T
ID code for output files? (8 characters or less)
demo

Field reference:

Field Meaning
aif 1: ESRI D8; 2: TopoIndex 1–9 codes
pwr > 20 Route to the steepest downslope cell (D8)
pwr = 0 Distribute uniformly among downslope neighbors
pwr = 1 Distribute in proportion to absolute slope
0 < pwr <= 20 Distribute by abs(slope) ** pwr
pwr < 0 Use the upstream D-infinity variant; square pixels are required
itmax Maximum iterations for correcting cell processing order
Six T/F switches In order: neighbor list, neighbor grid, index grid, index list, remapped flow grid, and ridge grid
lspars Sparse (T) or dense (F) ridge output, used with the sixth switch
suffix Output identifier; the Fortran interface accepts at most 8 characters

The output directory is derived from the directory portion of the DEM path. For example, data/dem.tif writes output below data/ next to the initialization file. Create the target directory before running.

Running the workflow

Call the workflow explicitly from your own script:

from pathlib import Path

from topoindex import topoindex_main

init_file = Path(r"C:\path\to\project\tpx_in.txt")
topoindex_main(main_app=True, init_file=str(init_file))

main_app=True enables console progress messages. The function currently returns no result object; its main outputs are files on disk.

Warning

The __main__ block at the bottom of topoindex.py still contains an example absolute path from a developer machine. Change it before running python topoindex.py, or preferably use the explicit import shown above. Do not publish personal absolute paths.

Outputs

With suffix=demo, the current implementation may write:

File Condition Contents
TIdscelList_demo.txt Flow raster exists and processing continues Downslope-cell lists
TIwfactorList_demo.txt Flow raster exists and processing continues Runoff-routing weights
TIdsneiList__demo.txt Switch 1 is T D8 neighbor diagnostic list; the current code emits two underscores
TIdscelGrid_demo.tif Switch 2 is T D8 downslope-neighbor cell grid
TIcelindxGrid_demo.tif Switch 3 is T Corrected processing-order grid
TIcelindxList_demo.txt Switch 4 is T Cell-number and index-number list
TIflodirGrid_demo.tif aif=1 and switch 5 is T Flow grid remapped to TopoIndex codes
TIridge_crest_demo.tif pwr >= 0 and switch 6 is T Ridge-cell grid
TIgrid_size.txt No flow raster, or multiple downslope weights are produced imax / nrow / ncol / nwf parameters
TopoIndexLog.txt Main workflow completes normally Input listing, diagnostics, and run log

GeoTIFF outputs use Int32, LZW compression, tiled storage, and inherit the reference raster's geotransform and projection.

The two underscores in TIdsneiList__<suffix>.txt result from the current prefix and formatting expression. If a downstream application requires the official single-underscore convention, correct the naming code and revalidate the workflow.

Rebuilding the Fortran extension

The build scripts replace an existing extension for the same platform under topoindex_f2py/. Back up any binary that must be retained.

Windows

Make sure the selected environment provides Python, NumPy, Meson, Ninja, and gfortran:

python -m pip install "numpy==1.26.4" meson ninja
gfortran --version
python -c "import numpy; print(numpy.__version__)"
.\build_topoindex.cmd

Verify the result:

python -c "from topoindex_f2py import topoindex; print(topoindex.__file__)"

The compiler runtime must match the new .pyd. Do not assume that the DLLs already in this repository are compatible with every gfortran distribution.

Linux / macOS

build_topoindex.sh can create a .so, but topoindex_f2py/__init__.py currently calls the Windows-only os.add_dll_directory() unconditionally. POSIX loading is therefore an unfinished port, not a supported path. Add platform guards, rebuild, and run regression tests before claiming support.

Troubleshooting

ImportError: DLL load failed while importing topoindex

Typical causes include:

  • Python is not CPython 3.12 x64;
  • the .pyd does not match the NumPy or compiler ABI;
  • the matching gfortran runtime is absent from lib/, or unrelated DLLs with the same names are being loaded;
  • a GDAL/OSGeo environment changes DLL search order.

Prefer rebuilding in a clean, controlled environment over copying DLLs from an unknown source.

A raster cannot be opened

Confirm that:

  • from osgeo import gdal imports successfully;
  • relative paths are correct from the initialization-file directory;
  • the GDAL build includes the required raster driver;
  • both inputs are readable, single-band rasters.

nxtcel failed or the log reports mismatched cells

Check that the DEM and flow-direction raster are exactly congruent and that every valid DEM cell has a legal direction code. Equal row and column counts alone are insufficient.

Index correction does not converge

Check for pits, loops, invalid directions, and NODATA-boundary problems before cautiously increasing itmax. More iterations cannot repair invalid input topology.

Validation checklist

Before research or production use:

  1. establish a baseline with the official USGS tutorial data and record the exact TRIGRS/TopoIndex version;
  2. compare valid-cell counts, downslope lists, processing order, and routing weights;
  3. verify that valid weights for a cell sum as expected;
  4. check output rows, columns, NODATA, CRS, resolution, and pixel alignment;
  5. test ESRI code conversion with a small nine-cell fixture;
  6. pin and record Python, NumPy, GDAL, gfortran, and runtime-DLL versions and provenance;
  7. independently review scientific results rather than treating a successful run as model validation.

Known limitations

  • No ready-to-run tpx_in.txt, test data, or automated tests are included;
  • the prebuilt extension targets only CPython 3.12 / Windows x64;
  • the POSIX package loader is not yet portable;
  • the direct script entry point contains a developer-specific path;
  • some legacy Fortran control flow and numerical conventions remain, without a complete behavioral-regression report;
  • no repository-wide license has been selected for the new adaptation code;
  • the exact compiler distribution, corresponding source, and license bundle for the supplied DLLs have not been archived in the repository.

Licensing, attribution, and release compliance

Read THIRD_PARTY_NOTICES.md before redistribution. The essential rules are:

  1. Preserve provenance. State that the code is adapted from TopoIndex in the USGS TRIGRS distribution and retain the Rex L. Baum / USGS credits.
  2. Do not imply endorsement. Do not describe the project as an official, approved, or USGS-maintained release, and do not use USGS marks without authorization.
  3. Do not apply an inaccurate blanket license. The public-domain status of USGS-origin material does not automatically place this project's new code under CC0, MIT, or another license.
  4. License original contributions deliberately. There is currently no root LICENSE covering the original adaptation work. The rightsholder should select one only after confirming ownership and defining its scope.
  5. Treat binaries carefully. The GCC/Fortran/MCF runtimes in lib/ and the prebuilt .pyd need exact provenance, versions, license texts, and any required corresponding-source or acquisition information. Until those materials are complete, the conservative public-release option is to omit the binaries and require users to build from a known toolchain.
  6. Dependencies retain their own terms. NumPy, GDAL, and optional GDAL dependencies are not covered by the USGS public-domain statement.

Public visibility is not an open-source grant. Until a license for the original adaptation code is selected, downstream users should not assume permission to copy, modify, or redistribute those new portions.

This is an engineering compliance summary, not legal advice. Commercial, paid-service, cross-border, or organization-regulated distribution should be reviewed by qualified counsel against the actual source history and binary supply chain.

Citation

When publishing work that uses this repository, cite at least the official TRIGRS software release and foundational report, and separately identify this repository as an unofficial Python adaptation:

Baum, R. L., and Alvioli, M., 2016, TRIGRS version 2.1:
U.S. Geological Survey software release. https://doi.org/10.5066/F7M044QS

Baum, R. L., Savage, W. Z., and Godt, J. W., 2008,
TRIGRS—A Fortran program for transient rainfall infiltration and
grid-based regional slope-stability analysis, version 2.0:
U.S. Geological Survey Open-File Report 2008-1159, 75 p.
https://doi.org/10.3133/ofr20081159

For reproducibility, also record the repository commit, modification date, Python/NumPy/GDAL versions, and compiler toolchain.

Disclaimer

This project is provided “as is,” without express or implied warranties. Topographic, hydrologic, and slope-stability analyses are highly sensitive to input data, parameter choices, model assumptions, and implementation details. Do not use its output as the sole basis for life-safety, engineering-design, emergency-response, land-use, or investment decisions. Users are responsible for validating results and accepting all risks of use.

About

This repository is an unofficial derivative of the TopoIndex utility distributed with the official (USGS) TRIGRS release. It is not an official USGS release and is not sponsored, endorsed, warranted, or maintained by USGS. It implements only the TopoIndex preprocessing workflow.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages