User Tools

Site Tools


Calculation of stream-specific variables

GRASS GIS add-ons &

Script written by Sami Domisch, October 2015

Grass hydrological commands*_modules

This example contains the following steps:

  • Download an exemplary digital elevation model (DEM)
  • Extract the stream network from the DEM
  • Delineate major drainage basins
  • Crop data to a sub-basin
  • Calculate the sub-watersheds for each stream grid cell (
  • Calculate contiguous stream-specific variables (
The add-ons have been tested in the Linux environment. Microsoft Windows users: consider installing the OSGEO-Live Virtual machine that has GRASS GIS 7 already installed and is ready to use.

Update April 2016: the add-ons are currently being tested under Windows, please check back later for more details

Create and enter the folder where the data will be stored:

 export INDIR=$HOME/grass_hydro
 mkdir $INDIR 
 cd $INDIR

Download and unzip a DEM from WorldClim (

 wget -O  $INDIR/  ""
 unzip  -o $INDIR/  -d  $INDIR/dem
 gdalinfo $INDIR/dem/alt_16.tif        # check data

Create the GRASS GIS data base and enter GRASS:

 grass72  -text -c -e  $INDIR/dem/alt_16.tif  $INDIR/grass_location
 grass72 -text $INDIR/grass_location/PERMANENT  # enter GRASS

Read data into GRASS: input=$INDIR/dem/alt_16.tif    output=elevation elevation # check data

Open GUI and visualize the layers:

 g.gui wxpython

Run hydrological conditioning:

 g.extension  extension=r.hydrodem # download extension
 r.hydrodem  input=elevation  output=elevation_cond

Extract drainage direction and stream network

 r.watershed  --h  # see help regarding the options and flags
 r.watershed  elevation=elevation_cond  drainage=drainage   stream=stream  accumulation=accumulation  threshold=100  --o

Get drainage basins (last downstream segment: -l flag)

 g.extension  direction=drainage  stream_rast=stream  basins=basins_last  -l  --o

Categorize the single basins:

 r.clump -d input=basins_last  output=basins_cat  --o

Extract the data for one basin:

 r.mapcalc "drainage_sub = if (basins_cat==798, drainage, null() ) "  --o
 r.mapcalc "stream_sub = if (basins_cat==798, stream, null() ) "  --o

Write files to disk:

 r.out.gdal  input=drainage_sub   output=$INDIR/drainage_sub.tif  type=Int32  nodata=-9999  --o  -c    createopt="COMPRESS=LZW,ZLEVEL=9"
 r.out.gdal  input=stream_sub     output=$INDIR/stream_sub.tif    type=Int32  nodata=-9999  --o  -c    createopt="COMPRESS=LZW,ZLEVEL=9"

Create stream-specific variables, and limit the calculation only to a single basin.

Download and install the GRASS add-ons:

 g.extension  # use work-around below
 g.extension   # use work-around below

GRASS70; Work-around (October 2015):

 mkdir -p $HOME/.grass7/addons/scripts
 wget -O $HOME/.grass7/addons/scripts/   ""
 chmod 777  $HOME/.grass7/addons/scripts/
 wget -O $HOME/.grass7/addons/scripts/  ""
 chmod 777  $HOME/.grass7/addons/scripts/

GRASS72; Work-around (June 2017):*

 mkdir $HOME/.grass7/addons/scripts
 wget -O $HOME/.grass7/addons/scripts/   ""
 chmod 777  $HOME/.grass7/addons/scripts/
 wget -O $HOME/.grass7/addons/scripts/  ""
 chmod 777  $HOME/.grass7/addons/scripts/

Add-on 1: Calculate the sub-watershed and sub-stream sections for each stream grid cell using 2 processors: stream=stream_sub  drainage=drainage_sub  cpu=2

Add-on 2: Create stream-specific variables based on elevation  variable=elevation  output=cells,min,max,range,mean,stddev,coeff_var,sum  area=watershed  scale=1  cpu=2

Rename to the “elevation_cells” to “flow_accumulation” and check variables:

 r.mapcalc "flow_accummulation = elevation_cells"  --o  flow_accummulation  elevation_range

Get stream length (similar procedure as above):  variable=elevation  output=cells  area=stream  scale=1  cpu=2
 r.mapcalc "stream_length = elevation_cells"  --o  stream_length 

Calculate the amount of rainfall within the basin:

 wget -O  $INDIR/  ""
 unzip -q  -o $INDIR/  -d  $INDIR/prec input=$INDIR/prec/prec6_16.tif   output=prec6   # rainfall in June  variable=prec6  output=sum  area=watershed  scale=1  cpu=2

Run all 12 months in a loop:

 for var in $(seq 1 12); do input=$INDIR/prec/prec${var}_16.tif   output=prec$var  variable=prec$var  output=sum  area=watershed  scale=1  cpu=2

Other useful add-ons for hydrological applications:


Get the stream order:  stream_rast=stream_sub   direction=drainage_sub   strahler=str_order  --o

Get only streams and basins >=3rd order

 r.mapcalc "str_order_3rd = if(str_order >=3, str_order, null() ) "  --o  direction=drainage_sub  stream_rast=str_order_3rd  basins=basins_3rd_last   -l  --o

Stream distance - Calculates distance to and elevation above streams and outlet

 g.extension   stream_rast=stream_sub   direction=drainage_sub   elevation=elevation_cond  method=downstream   distance=str_distance    difference=str_elevation_diff  --o

Stream order statistics - Calculates Horton's statistics for Strahler and Horton ordered networks created with Print only order statistics:  stream_rast=stream_sub   direction=drainage_sub   elevation=elevation_cond  output=str_stats_o.txt    -o   
 more $INDIR/str_stats_o.txt

Print only catchment statistics:  stream_rast=stream_sub   direction=drainage_sub   elevation=elevation_cond  output=str_stats_c.txt    -c 
 more $INDIR/str_stats_c.txt
wiki/grassrivarvariable.txt · Last modified: 2017/06/08 09:06 by new_ost4sem_admin