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.accdetect
  • t.rast.aggregate
  • t.rast.mapcalc
  • t.info
  • g.region
  • r.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