简体中文 | 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.
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.
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:
- USGS TRIGRS v2.1 software page
- Official USGS source, v2.1.0
- Historical USGS GitHub mirror, v2.1.0
- TRIGRS 2.0 report and user documentation
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
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.
| 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.
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.
- 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
float32before entering the Fortran core.
- It must match the DEM in rows, columns, pixel alignment, resolution, extent, and valid/NODATA mask;
- values are converted to
int32; - use
aif=1for ESRI D8 codes oraif=2for 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 |
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.
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.
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.
The build scripts replace an existing extension for the same platform under topoindex_f2py/. Back up any binary that must be retained.
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.cmdVerify 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.
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.
Typical causes include:
- Python is not CPython 3.12 x64;
- the
.pyddoes 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.
Confirm that:
from osgeo import gdalimports 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.
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.
Check for pits, loops, invalid directions, and NODATA-boundary problems before cautiously increasing itmax. More iterations cannot repair invalid input topology.
Before research or production use:
- establish a baseline with the official USGS tutorial data and record the exact TRIGRS/TopoIndex version;
- compare valid-cell counts, downslope lists, processing order, and routing weights;
- verify that valid weights for a cell sum as expected;
- check output rows, columns, NODATA, CRS, resolution, and pixel alignment;
- test ESRI code conversion with a small nine-cell fixture;
- pin and record Python, NumPy, GDAL, gfortran, and runtime-DLL versions and provenance;
- independently review scientific results rather than treating a successful run as model validation.
- 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.
Read THIRD_PARTY_NOTICES.md before redistribution. The essential rules are:
- Preserve provenance. State that the code is adapted from TopoIndex in the USGS TRIGRS distribution and retain the Rex L. Baum / USGS credits.
- 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.
- 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.
- License original contributions deliberately. There is currently no root
LICENSEcovering the original adaptation work. The rightsholder should select one only after confirming ownership and defining its scope. - Treat binaries carefully. The GCC/Fortran/MCF runtimes in
lib/and the prebuilt.pydneed 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. - 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.
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.
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.