t.rast.accumulate(1grass)
β¨ NAME β¨
okay so bestie, welcome to t.rast.accumulate(1grass) β the GRASS User's Manual page that computes cyclic accumulations of a space time raster dataset. It's giving temporal raster realness, and honestly? We're obsessed. π
π KEYWORDS π
temporal, accumulation, raster, time β the vibe-check tags, fr fr. β¨
πͺ SYNOPSIS πͺ
Here's the exact invocation tea, no cap:
t.rast.accumulate
t.rast.accumulate --help
t.rast.accumulate [-nr] input=name output=name [lower=name]
[upper=name] start=string [stop=string] cycle=string [offset=string]
[granularity=string] basename=string [suffix=name] limits=lower,upper
[scale=float] [shift=float] [method=string] [--overwrite]
[--help] [--verbose] [--quiet] [--ui]
π© Flags π©
-nβ register empty maps in the output space time raster dataset; otherwise they will be deleted. RIP to them, they're literally gone π-rβ reverse time direction in cyclic accumulation. time travel? kinda sorta π--overwriteβ allow output files to overwrite existing files. the "oops, did I mean that?" button, bestie.--helpβ print usage summary.--verboseβ verbose module output. give us ALL the tea β--quietβ quiet module output. shhh, main character silence π€«--uiβ force launching GUI dialog. pop-up era π
π Parameters π
input=name[required]β name of the input space time raster dataset.output=name[required]β name of the output space time raster dataset.lower=nameβ input space time raster dataset that defines the lower threshold. values lower than this threshold are excluded from accumulation. bye, low values πupper=nameβ input space time raster dataset that defines the upper threshold. values higher than this threshold are excluded from accumulation. high values, not today πstart=string[required]β the temporal starting point to begin the accumulation, egβ2001-01-01β.stop=stringβ the temporal date to stop the accumulation, egβ2009-01-01β.cycle=string[required]β the temporal cycle to restart the accumulation, egβ12 monthsβ.offset=stringβ the temporal offset to the beginning of the next cycle, egβ6 monthsβ.granularity=stringβ the granularity for accumulationβ1 dayβ. Default:1 day.basename=string[required]β basename of the new generated output maps. A numerical suffix separated by an underscore will be attached to create a unique identifier. uniqueness slay π₯suffix=nameβ suffix to add at basename: setβgranβfor granularity,βtimeβfor the full time format,βnumβfor numerical suffix with a specific number of digits (default%%05). Default:gran.limits=lower,upper[required]β use these limits in case lower and/or upper input space time raster datasets are not defined or contain NULL values.scale=floatβ scale factor for input space time raster dataset.shift=floatβ shift factor for input space time raster dataset.method=stringβ this method will be applied to compute the accumulative values from the input maps in a single granule. Growing Degree Days or Winkler indices; Mean:sum(input maps)/(number of input maps); Biologically Effective Degree Days; Huglin Heliothermal index. Options:mean,gdd,bedd,huglin. Default:mean.
π DESCRIPTION π
t.rast.accumulate is designed to perform temporal accumulations of space time raster datasets. This module expects a space time raster dataset as input that will be sampled by a given granularity. All maps that have the start time during the actual granule will be accumulated with the predecessor granule accumulation result using the raster module r.series.accumulate. The default granularity is 1 day, but any temporal granularity can be set. no limits, bestie β¨
The start time and the end time of the accumulation process must be set, eg. start="2000-03-01" end="2011-01-01". In addition, a cycle, eg. cycle="8 months", can be specified, that defines after which interval of time the accumulation process restarts. The offset option specifies the time that should be skipped between two cycles, eg. offset="4 months". it's giving scheduling drama ποΈ
The lower and upper limits of the accumulation process can be set, either by using space time raster datasets or by using fixed values for all raster cells and time steps. The raster maps that specify the lower and upper limits of the actual granule will be detected using the following temporal relations: equals, during, overlaps, overlapped and contains. First, all maps with time stamps equal to the current granule will be detected, the first lower map and the first upper map found will be used as limit definitions. If no equal maps are found, then maps with a temporal during relation are detected, then maps that temporally overlap the actual granules, until maps that have a temporal contain relation are detected. If no maps are found or lower/upper STRDS are not defined, then the limits option is used, eg. limits=10,30. deduction era π
The upper limit is only used in the Biologically Effective Degree Days calculation. very specific, very demure π
The options shift, scale and method are passed to r.series.accumulate. Please refer to the manual page of r.series.accumulate for detailed option description.
The output is a new space time raster dataset with the provided start time, end time and granularity containing the accumulated raster maps. The base name of the generated maps must always be set. The output space time raster dataset can then be analyzed using t.rast.accdetect to detect specific accumulation patterns. and that's the accumulation-to-detection pipeline, periodt π
β¨ EXAMPLE β¨
okay bestie, grab a snack because this is the full glow-up tutorial π«Ά we're gonna accumulate the daily mean temperature of Europe from 1990 to 2000 using the growing-degree-day method, all so we can detect grass hopper reproduction cycles that are critical to agriculture. yes. bug science. it's giving β¨applied entomologyβ¨ and honestly? obsessed.
first up, the setup era π β grab the data, make a temp project directory, boot GRASS up, import, and get the region right:
# Get the temperature data
wget http://www-pool.math.tu-berlin.de/~soeren/grass/temperature_mean_1990_2000_daily_celsius.tar.gz
# Create a temporary project directory
mkdir -p /tmp/grassdata/LL
# Start GRASS and create a new project with PERMANENT mapset
grass -c EPSG:4326 /tmp/grassdata/LL/PERMANENT
# Import the temperature data
t.rast.import input=temperature_mean_1990_2000_daily_celsius.tar.gz \
output=temperature_mean_1990_2000_daily_celsius directory=/tmp
# We need to set the region correctly
g.region -p raster=`t.rast.list input=temperature_mean_1990_2000_daily_celsius column=name | tail -1`
# We can zoom to the raster map
g.region -p zoom=`t.rast.list input=temperature_mean_1990_2000_daily_celsius column=name | tail -1`
okay so the computation of grashopper pest control cycles is based on:
- Using Growing Degree Days For Insect Management
- Nancy E. Adams
- Extension Educator, Agricultural Resources
available here: http://extension.unh.edu/agric/gddays/docs/growch.pdf
and now we compute the Biologically Effective Degree Days from 1990 - 2000 for each year (12 month cycle) with a granularity of one day. base temperature is 10Β°C, upper limit is 30Β°C. so the accumulation starts at 10Β°C and does not accumulate values above 30Β°C. periodt. π
#############################################################################
#### ACCUMULATION USING GDD METHOD ##########################################
#############################################################################
# The computation of grashopper pest control cycles is based on:
#
# Using Growing Degree Days For Insect Management
# Nancy E. Adams
# Extension Educator, Agricultural Resources
#
# available here: http://extension.unh.edu/agric/gddays/docs/growch.pdf
# Now we compute the Biologically Effective Degree Days
# from 1990 - 2000 for each year (12 month cycle) with
# a granularity of one day. Base temperature is 10Β°C, upper limit is 30Β°C.
# Hence the accumulation starts at 10Β°C and does not accumulate values above 30Β°C.
t.rast.accumulate input="temperature_mean_1990_2000_daily_celsius" \
output="temperature_mean_1990_2000_daily_celsius_accumulated_10_30" \
limits="10,30" start="1990-01-01" stop="2000-01-01" cycle="12 months" \
basename="temp_acc_daily_10_30" method="bedd"
next: ACCUMULATION PATTERN DETECTION π now we detect the three grasshopper pest control cycles. three of them. a whole trilogy, no cap.
first cycle at 325Β°C - 427Β°C GDD:
#############################################################################
#### ACCUMULATION PATTERN DETECTION #########################################
#############################################################################
# Now we detect the three grasshopper pest control cycles
# First cycle at 325Β°C - 427Β°C GDD
t.rast.accdetect input=temperature_mean_1990_2000_daily_celsius_accumulated_10_30@PERMANENT \
occ=leafhopper_occurrence_c1_1990_2000 start="1990-01-01" stop="2000-01-01" \
cycle="12 months" range=325,427 basename=lh_c1 indicator=leafhopper_indicator_c1_1990_2000
second cycle at 685Β°C - 813Β°C GDD:
# Second cycle at 685Β°C - 813Β°C GDD
t.rast.accdetect input=temperature_mean_1990_2000_daily_celsius_accumulated_10_30@PERMANENT \
occ=leafhopper_occurrence_c2_1990_2000 start="1990-01-01" stop="2000-01-01" \
cycle="12 months" range=685,813 basename=lh_c2 indicator=leafhopper_indicator_c2_1990_2000
third cycle, the finale, at 1047Β°C - 1179Β°C GDD:
# Third cycle at 1047Β°C - 1179Β°C GDD
t.rast.accdetect input=temperature_mean_1990_2000_daily_celsius_accumulated_10_30@PERMANENT \
occ=leafhopper_occurrence_c3_1990_2000 start="1990-01-01" stop="2000-01-01" \
cycle="12 months" range=1047,1179 basename=lh_c3 indicator=leafhopper_indicator_c3_1990_2000
then we do the YEARLY SPATIAL OCCURRENCE COMPUTATION OF ALL CYCLES π β extract the areas that have full cycles, flag the clean ones, and paint everything pretty. watch the `lh_cleann_all_cycles` spelling btw, it's double-n and it's iconic, don't touch it π
#############################################################################
#### YEARLY SPATIAL OCCURRENCE COMPUTATION OF ALL CYCLES ####################
#############################################################################
# Extract the areas that have full cycles
t.rast.aggregate input=leafhopper_indicator_c1_1990_2000 gran="1 year" \
output=leafhopper_cycle_1_1990_2000_yearly method=maximum basename=li_c1
t.rast.mapcalc input=leafhopper_cycle_1_1990_2000_yearly basename=lh_clean_c1 \
output=leafhopper_cycle_1_1990_2000_yearly_clean \
expression="if(leafhopper_cycle_1_1990_2000_yearly == 3, 1, null())"
t.rast.aggregate input=leafhopper_indicator_c2_1990_2000 gran="1 year" \
output=leafhopper_cycle_2_1990_2000_yearly method=maximum basename=li_c2
t.rast.mapcalc input=leafhopper_cycle_2_1990_2000_yearly basename=lh_clean_c2 \
output=leafhopper_cycle_2_1990_2000_yearly_clean \
expression="if(leafhopper_cycle_2_1990_2000_yearly == 3, 2, null())"
t.rast.aggregate input=leafhopper_indicator_c3_1990_2000 gran="1 year" \
output=leafhopper_cycle_3_1990_2000_yearly method=maximum basename=li_c3
t.rast.mapcalc input=leafhopper_cycle_3_1990_2000_yearly basename=lh_clean_c3 \
output=leafhopper_cycle_3_1990_2000_yearly_clean \
expression="if(leafhopper_cycle_3_1990_2000_yearly == 3, 3, null())"
t.rast.mapcalc input=leafhopper_cycle_1_1990_2000_yearly_clean,leafhopper_cycle_2_1990_2000_yearly_clean,leafhopper_cycle_3_1990_2000_yearly_clean \
basename=lh_cleann_all_cycles \
output=leafhopper_all_cycles_1990_2000_yearly_clean \
expression="if(isnull(leafhopper_cycle_3_1990_2000_yearly_clean), \
if(isnull(leafhopper_cycle_2_1990_2000_yearly_clean), \
if(isnull(leafhopper_cycle_1_1990_2000_yearly_clean), \
null() ,1),2),3)"
cat > color.table << EOF
3 yellow
2 blue
1 red
EOF
t.rast.colors input=leafhopper_cycle_1_1990_2000_yearly_clean rules=color.table
t.rast.colors input=leafhopper_cycle_2_1990_2000_yearly_clean rules=color.table
t.rast.colors input=leafhopper_cycle_3_1990_2000_yearly_clean rules=color.table
t.rast.colors input=leafhopper_all_cycles_1990_2000_yearly_clean rules=color.table
now DURATION COMPUTATION π§ how long does each cycle actually last, in days? three cycles, three times the min/max/subtract combo, and then rainbow colors because we're extra like that:
#############################################################################
################ DURATION COMPUTATION #######################################
#############################################################################
# Extract the duration in days of the first cycle
t.rast.aggregate input=leafhopper_occurrence_c1_1990_2000 gran="1 year" \
output=leafhopper_min_day_c1_1990_2000 method=minimum basename=occ_min_day_c1
t.rast.aggregate input=leafhopper_occurrence_c1_1990_2000 gran="1 year" \
output=leafhopper_max_day_c1_1990_2000 method=maximum basename=occ_max_day_c1
t.rast.mapcalc input=leafhopper_min_day_c1_1990_2000,leafhopper_max_day_c1_1990_2000 \
basename=occ_duration_c1 \
output=leafhopper_duration_c1_1990_2000 \
expression="leafhopper_max_day_c1_1990_2000 - leafhopper_min_day_c1_1990_2000"
# Extract the duration in days of the second cycle
t.rast.aggregate input=leafhopper_occurrence_c2_1990_2000 gran="1 year" \
output=leafhopper_min_day_c2_1990_2000 method=minimum basename=occ_min_day_c2
t.rast.aggregate input=leafhopper_occurrence_c2_1990_2000 gran="1 year" \
output=leafhopper_max_day_c2_1990_2000 method=maximum basename=occ_max_day_c2
t.rast.mapcalc input=leafhopper_min_day_c2_1990_2000,leafhopper_max_day_c2_1990_2000 \
basename=occ_duration_c2 \
output=leafhopper_duration_c2_1990_2000 \
expression="leafhopper_max_day_c2_1990_2000 - leafhopper_min_day_c2_1990_2000"
# Extract the duration in days of the third cycle
t.rast.aggregate input=leafhopper_occurrence_c3_1990_2000 gran="1 year" \
output=leafhopper_min_day_c3_1990_2000 method=minimum basename=occ_min_day_c3
t.rast.aggregate input=leafhopper_occurrence_c3_1990_2000 gran="1 year" \
output=leafhopper_max_day_c3_1990_2000 method=maximum basename=occ_max_day_c3
t.rast.mapcalc input=leafhopper_min_day_c3_1990_2000,leafhopper_max_day_c3_1990_2000 \
basename=occ_duration_c3 \
output=leafhopper_duration_c3_1990_2000 \
expression="leafhopper_max_day_c3_1990_2000 - leafhopper_min_day_c3_1990_2000"
t.rast.colors input=leafhopper_duration_c1_1990_2000 color=rainbow
t.rast.colors input=leafhopper_duration_c2_1990_2000 color=rainbow
t.rast.colors input=leafhopper_duration_c3_1990_2000 color=rainbow
MONTHLY CYCLES OCCURRENCE πΈ extract the monthly indicator that shows the start and end of a cycle β and yes we're doing all three cycles again, the girlies are thorough:
#############################################################################
################ MONTHLY CYCLES OCCURRENCE ##################################
#############################################################################
# Extract the monthly indicator that shows the start and end of a cycle
# First cycle
t.rast.aggregate input=leafhopper_indicator_c1_1990_2000 gran="1 month" \
output=leafhopper_indi_min_month_c1_1990_2000 method=minimum basename=occ_indi_min_month_c1
t.rast.aggregate input=leafhopper_indicator_c1_1990_2000 gran="1 month" \
output=leafhopper_indi_max_month_c1_1990_2000 method=maximum basename=occ_indi_max_month_c1
t.rast.mapcalc input=leafhopper_indi_min_month_c1_1990_2000,leafhopper_indi_max_month_c1_1990_2000 \
basename=indicator_monthly_c1 \
output=leafhopper_monthly_indicator_c1_1990_2000 \
expression="if(leafhopper_indi_min_month_c1_1990_2000 == 1, 1, if(leafhopper_indi_max_month_c1_1990_2000 == 3, 3, 2))"
# Second cycle
t.rast.aggregate input=leafhopper_indicator_c2_1990_2000 gran="1 month" \
output=leafhopper_indi_min_month_c2_1990_2000 method=minimum basename=occ_indi_min_month_c2
t.rast.aggregate input=leafhopper_indicator_c2_1990_2000 gran="1 month" \
output=leafhopper_indi_max_month_c2_1990_2000 method=maximum basename=occ_indi_max_month_c2
t.rast.mapcalc input=leafhopper_indi_min_month_c2_1990_2000,leafhopper_indi_max_month_c2_1990_2000 \
basename=indicator_monthly_c2 \
output=leafhopper_monthly_indicator_c2_1990_2000 \
expression="if(leafhopper_indi_min_month_c2_1990_2000 == 1, 1, if(leafhopper_indi_max_month_c2_1990_2000 == 3, 3, 2))"
# Third cycle
t.rast.aggregate input=leafhopper_indicator_c3_1990_2000 gran="1 month" \
output=leafhopper_indi_min_month_c3_1990_2000 method=minimum basename=occ_indi_min_month_c3
t.rast.aggregate input=leafhopper_indicator_c3_1990_2000 gran="1 month" \
output=leafhopper_indi_max_month_c3_1990_2000 method=maximum basename=occ_indi_max_month_c3
t.rast.mapcalc input=leafhopper_indi_min_month_c3_1990_2000,leafhopper_indi_max_month_c3_1990_2000 \
basename=indicator_monthly_c3 \
output=leafhopper_monthly_indicator_c3_1990_2000 \
expression="if(leafhopper_indi_min_month_c3_1990_2000 == 1, 1, if(leafhopper_indi_max_month_c3_1990_2000 == 3, 3, 2))"
cat > color.table << EOF
3 red
2 yellow
1 green
EOF
t.rast.colors input=leafhopper_monthly_indicator_c1_1990_2000 rules=color.table
t.rast.colors input=leafhopper_monthly_indicator_c2_1990_2000 rules=color.table
t.rast.colors input=leafhopper_monthly_indicator_c3_1990_2000 rules=color.table
and finally, VISUALIZATION π the main character moment. now we use g.gui.animation to visualize the yearly occurrence, the duration and the monthly occurrence:
#############################################################################
################ VISUALIZATION ##############################################
#############################################################################
# Now we use g.gui.animation to visualize the yearly occurrence, the duration and the monthly occurrence
# Yearly occurrence of all reproduction cycles
g.gui.animation strds=leafhopper_all_cycles_1990_2000_yearly_clean
# Yearly duration of reproduction cycle 1
g.gui.animation strds=leafhopper_duration_c1_1990_2000
# Yearly duration of reproduction cycle 2
g.gui.animation strds=leafhopper_duration_c2_1990_2000
# Yearly duration of reproduction cycle 3
g.gui.animation strds=leafhopper_duration_c3_1990_2000
# Monthly occurrence of reproduction cycle 1
g.gui.animation strds=leafhopper_monthly_indicator_c1_1990_2000
# Monthly occurrence of reproduction cycle 2
g.gui.animation strds=leafhopper_monthly_indicator_c2_1990_2000
# Monthly occurrence of reproduction cycle 3
g.gui.animation strds=leafhopper_monthly_indicator_c3_1990_2000
okay bestie, that's the whole workflow π six animations, three cycles, yearly and monthly, all lined up like a little buggy runway. go slay π¦
β¨ REFERENCES β¨
- Jones, G.V., Duff, A.A., Hall, A., Myers, J.W., 2010. Spatial Analysis of Climate in Winegrape Growing Regions in the Western United States. Am. J. Enol. Vitic. 61, 313-326.
yes the grape girlies really did write the paper that inspired a grass module π iconic behaviour, honestly
π SEE ALSO π
the whole extended friend group, go say hi:
t.rast.accdetectt.rast.aggregatet.rast.mapcalct.infog.regionr.series.accumulate
π AUTHOR π
SΓΆren Gebbert, ThΓΌnen Institute of Climate-Smart Agriculture β absolute legend, thank you for your service π«Ά
π SOURCE CODE π
Available at: t.rast.accumulate source code (history)
Latest change: Tuesday Jan 27 12:40:13 2026 in commit: 5e8b13d47dd4fc81efa5abefe90c34f7a8291fb9
Main index | Temporal index | Topics index | Keywords index | Graphical index | Full index
aaaand that's a wrap!! π¬β¨ this lil masterpiece is pulled straight out of the GRASS 8.5.0 Reference Manual, and the copyright vibe belongs to Β© 2003-2026 GRASS Development Team. no cap, go accumulate something beautiful π πΈ
π¦ where this page comes from
- alpine 3.24: grass-gis-doc 8.5.0-r1 Β· GPL-2.0-or-later
- ubuntu stonking: grass-doc 8.5.0-1ubuntu1 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms