Crop Calendars datasets - Rwema25/AE-project GitHub Wiki
This crop calendar is a foundational input for global crop modeling, enabling harmonized and reproducible assessments of climate change impacts on agriculture.
Attribute | Description |
---|---|
Short Description | The AgMIP-GGCMI Crop Calendar is a global dataset providing multi-year average planting (sowing) and maturity (harvest) dates for 18 major crops, distinguishing between rainfed and irrigated systems, at 0.5° spatial resolution. It is a composite product merging various observational data sources and is designed to support harmonized crop modeling and climate impact assessments. |
Provider/Source | AgMIP (Agricultural Model Intercomparison and Improvement Project) and GGCMI (Global Gridded Crop Model Intercomparison), led by institutions including NASA GISS, Potsdam Institute for Climate Impact Research, University of Minnesota, and University of Goettingen. |
Homepage/Link | Zenodo Dataset |
License/Terms of Use | Open for research and non-commercial use; cite original sources as appropriate. |
Spatial Coverage | Global, 0.5° x 0.5° land grid cells. |
Temporal Coverage | Multi-year average (static growing periods; no interannual variability). |
Spatial Resolution | 0.5° x 0.5° latitude/longitude. |
Temporal Resolution | One growing season per crop per grid cell (with exceptions for wheat and rice). |
Key Variables | Planting day of year (DOY), maturity (harvest) day of year (DOY) for 18 crops, with separate values for rainfed and irrigated systems. |
18 crops covered | The 18 crops covered in the AgMIP-GGCMI Crop Calendar are: 1. Maize, 2. Wheat (including winter and spring wheat), 3. Rice (including two main growing seasons), 4. Soybean, 5. Barley, 6. Millet, 7. Rapeseed, 8. Rye, 9. Sorghum, 10. Sugar beet, 11. Sugar cane, 12. Cotton, 13. Cassava, 14. Groundnut, 15. Field pea, 16. Sunflower, 17. Dry bean, 18. Potato. |
Attribute | Description |
---|---|
Access Methods | Download from Zenodo; source code and tools available on GitHub. |
Data Formats | NetCDF (.nc), CSV, and R data objects. |
Data Organization | Organized by crop, grid cell, and management system (rainfed/irrigated); one growing season per crop/cell, except for wheat and rice (multiple seasons). |
Potential Challenges | Static averages only; no crop rotations or interannual variability; gap-filling and spatial extrapolation in areas lacking observations. |
Attribute | Description |
---|---|
File Naming Conventions | Typically includes crop name, management system, and phase (e.g., maize_rainfed_phase3.nc ). |
Variable Names & Units | Planting_day (DOY), Maturity_day (DOY); units are day of year (1–365/366). |
Coordinate Systems | Latitude and longitude in WGS 84 datum; grid cell centers. |
Data Processing | Composite of multiple observational sources; spatial extrapolation and gap-filling for uncultivated or missing areas; only a single season per crop/cell except for wheat and rice. |
Handling Missing Data | Gap-filled using best available sources; uncultivated areas extrapolated. |
API Availability | Description |
---|---|
Direct API | No direct API. |
Programmatic Access | Data and scripts available for download and batch processing via Zenodo and GitHub; R scripts provided for simulation and adaptation of crop calendars. |
Application/Strength/Limitation | Description |
---|---|
Potential Applications |
- Calibration of crop model phenology (e.g., heat unit/PHU requirements) - Harmonization of growing periods for multi-model crop simulations and climate impact studies - Assessment of climate change impacts on crop timing and yields at regional to global scales - Scenario development for adaptation strategies by simulating changes in planting/harvest dates |
Strengths |
- Consistent, global, crop-specific growing periods for 18 major crops - Distinguishes between rainfed and irrigated systems - Supports harmonized, reproducible crop modeling and climate impact research |
Limitations |
- Provides static (multi-year average) growing periods only; no annual variability or crop rotations - Extrapolated data in areas with sparse observations; users should check data quality for their region of interest |
Resource Type | Description/Link |
---|---|
User Guides/Documentation | Zenodo Dataset Documentation; GitHub Repository for Scripts. |
Primary Publication | Jägermeyr et al. (2021), "Climate impacts on global agriculture emerge earlier in new generation of climate and crop," Nature Food, DOI. |
Additional Studies | Minoli et al. (2022), "Global crop yields can be lifted by timely adaptation of growing periods to climate change," Nature Communications, DOI. |
Community/Support | Contact dataset authors via Zenodo or institutional affiliations listed in the dataset record. |
This crop calendar dataset provides globally gridded, multi-crop planting and maturity dates, serving as a key input for harmonized global crop modeling and climate impact assessments.
Attribute | Description |
---|---|
Short Description | The Jägermeyr Crop Calendar is a global dataset offering multi-year average planting (sowing) and maturity (harvest) dates for 18 major crops, distinguishing rainfed and irrigated systems at 0.5° spatial resolution. It is a composite product merging multiple observational sources, with gap-filling and spatial extrapolation to cover cultivated and uncultivated areas. Designed primarily for global gridded crop model intercomparison and climate impact studies. |
Provider/Source | Developed by Jonas Jägermeyr and collaborators, hosted by AgMIP-GGCMI (Agricultural Model Intercomparison and Improvement Project - Global Gridded Crop Model Intercomparison) with contributions from institutions including the Potsdam Institute for Climate Impact Research and NASA GISS. |
Homepage/Link | Zenodo Dataset |
License/Terms of Use | Open for research and non-commercial use; users should cite original publications appropriately. |
Spatial Coverage | Global land areas at 0.5° x 0.5° grid cells. |
Temporal Coverage | Multi-year average (static growing periods; no interannual variability). |
Spatial Resolution | 0.5° latitude/longitude grid cells. |
Temporal Resolution | One growing season per crop per grid cell, except for wheat (winter and spring) and rice (two main seasons). |
Key Variables | Planting day of year (DOY), maturity (harvest) day of year (DOY), separated by rainfed and irrigated management. |
Crops Covered | 18 crops: maize, wheat (winter and spring), rice (two seasons), soybean, barley, millet, rapeseed, rye, sorghum, sugar beet, sugar cane, cotton, cassava, groundnut, field pea, sunflower, dry bean, potato. |
Attribute | Description |
---|---|
Access Methods | Download via Zenodo; source code and modeling scripts available on GitHub. |
Data Formats | NetCDF (.nc), CSV, and R data objects. |
Data Organization | Data organized by crop, grid cell, and management system (rainfed/irrigated); includes one growing season per crop per cell except for wheat and rice with multiple seasons. |
Potential Challenges | Static averages only, no representation of crop rotations or year-to-year variability; spatial extrapolation and gap-filling applied in regions lacking observations. |
Attribute | Description |
---|---|
File Naming Conventions | Filenames typically include crop name, management system, and growth phase (e.g., maize_rainfed_phase3.nc ). |
Variable Names & Units |
Planting_day (DOY), Maturity_day (DOY); units are day of year (1–365/366). |
Coordinate Systems | Latitude and longitude in WGS 84 datum, grid cell centers. |
Data Processing | Composite product derived by merging multiple observational sources, with gap-filling and spatial extrapolation for uncultivated or data-sparse areas. |
Handling Missing Data | Missing data gap-filled using best available sources; uncultivated areas extrapolated based on neighboring data. |
API Availability | Description |
---|---|
Direct API | No direct API available. |
Programmatic Access | Data and scripts can be downloaded for batch processing from Zenodo and GitHub. R scripts support simulation and adaptation of crop calendars. |
Application/Strength/Limitation | Description |
---|---|
Potential Applications | - Calibration of crop model phenology (e.g., heat unit requirements) - Harmonization of growing periods for multi-model crop simulations and climate impact assessments - Evaluation of climate change impacts on crop timing and yields at regional to global scales - Development of adaptation scenarios via simulation of altered planting and harvest dates |
Strengths | - Globally consistent, crop-specific growing periods for 18 major crops - Differentiates rainfed and irrigated systems - Supports reproducible, harmonized global crop modeling and climate impact research |
Limitations | - Static multi-year averages only; no interannual variability or crop rotations - Spatial extrapolation in data-poor regions may reduce local accuracy; users should verify data quality for their area of interest |
Resource Type | Description/Link |
---|---|
User Guides/Documentation | Zenodo Dataset Documentation; GitHub Repository for Scripts |
Primary Publication | Jägermeyr et al. (2021), "Climate impacts on global agriculture emerge earlier in new generation of climate and crop," Nature Food, DOI |
Additional Studies | Minoli et al. (2022), "Global crop yields can be lifted by timely adaptation of growing periods to climate change," Nature Communications, DOI |
Community/Support | Contact dataset authors via Zenodo or institutional affiliations listed in the dataset record |
The MIRCA-OS dataset is a valuable resource for agroecological research, providing detailed spatial and temporal crop area information essential for modeling and monitoring agricultural systems globally.
Attribute | Description |
---|---|
Short Description | MIRCA-OS is a global, open-source dataset providing monthly irrigated and rainfed cropped area maps for 23 crop classes at 5-arcminute (~10 km) spatial resolution for the years 2000, 2005, 2010, and 2015. It combines subnational crop-specific harvested area statistics with global gridded land cover and crop calendar data to produce monthly growing area grids and annual harvested area maps. |
Provider/Source | Developed by an international team led by researchers associated with AgMIP and global land use modeling groups. |
Homepage/Link | MIRCA-OS Dataset Description (Nature Scientific Data) |
License/Terms of Use | Open for research and non-commercial use; citation of original dataset recommended. |
Spatial Coverage | Global (180°W to 180°E longitude, 90°S to 90°N latitude). |
Temporal Coverage | Years 2000, 2005, 2010, and 2015. |
Spatial Resolution | 5 arcminutes (approx. 10 km x 10 km); also annual maps at 0.5° resolution. |
Temporal Resolution | Monthly growing area grids representing crop growth stages from planting to maturity. |
Key Variables | Monthly growing area (ha) for irrigated and rainfed systems, annual harvested area (ha), crop calendars (planting and maturity months). |
23 crops covered | The 23 major crops covered in the MIRCA-OS dataset, with distinctions for irrigated and rainfed systems, are: 1. Barley, 2. Cassava (Tapioca), 3. Cocoa, 4. Coffee, 5. Cotton, 6. Fodder (Alfalfa; grasses and legumes; clover; hay; haylage), 7. Groundnuts (Peanuts), 8. Maize (Corn, including grain, silage, sweet corn, popcorn), 9. Millet (Pearl millet; finger millet; small millet), 10. Oil palm, 11. Potatoes, 12. Pulses (Chickpeas; pigeon peas; cowpeas; peas, beans; lentils; other pulses), 13. Rapeseed (Canola; mustard), 14. Rice (Paddy), 15. Rye, 16. Sugar beet, 17. Sugar cane, 18. Sorghum (grain and silage), 19. Soybeans, 20. Sunflower, 21. Wheat (spring soft wheat; winter soft wheat; durum), 22. Other perennials (e.g., almonds, apples, bananas, citrus fruits, grapes, olives, etc.), 23. Other annuals (various crops not listed above) |
Attribute | Description |
---|---|
Access Methods | Download via HydroShare, GitHub (code), and journal supplementary materials. |
Data Formats | GeoTIFF and NetCDF for spatial data; CSV for crop calendars. |
Data Organization | Organized by crop, year, irrigation system (irrigated/rainfed), and month; includes monthly growing area grids, maximum monthly growing area maps, and annual harvested area maps. |
Potential Challenges | Large file sizes; requires GIS or scientific programming tools to process (e.g., Python with xarray, R, QGIS). |
Attribute | Description |
---|---|
File Naming Conventions | Format includes crop name, sub-crop number (for multiple cropping), year, irrigation system, and version (e.g., MIRCA-OS_Rice1_2015_ir_v0.1.nc). |
Variable Names & Units | Growing area or harvested area in hectares (ha). Monthly layers numbered 1–12 represent January to December. |
Coordinate Systems | Longitude/latitude in WGS84 datum. |
Data Processing | Combines subnational harvested area statistics with global land cover and crop calendars; downscaled to 5-arcminute grids using area weighting and cropping calendars; gap-filling and mosaicking applied. |
Handling Missing Data | Areas with no crop presence assigned zero; gap-filling based on regional statistics and land cover. |
API Availability | Description |
---|---|
Direct API | No dedicated API available. |
Programmatic Access | Data and processing scripts available on GitHub; datasets downloadable for use in GIS and programming environments. |
Application/Strength/Limitation | Description |
---|---|
Potential Applications: |
- Mapping spatial and temporal distribution of crop areas for yield modeling and food security assessments - Differentiating irrigated and rainfed cropping systems in climate impact and water resource studies - Supporting crop phenology and cropping intensity analyses - Input for crop models requiring spatially explicit cropped area and calendar information |
Strengths: |
- High spatial (5 arcminutes) and temporal (monthly) resolution - Covers 23 major crops with irrigated and rainfed distinctions - Combines statistical and remote sensing data for improved accuracy |
Limitations: |
- Temporal coverage limited to four years (2000, 2005, 2010, 2015) - Static within each year, no interannual variability - Requires technical skills to process large spatial datasets |
Resource Type | Description/Link |
---|---|
User Guides/Documentation | Nature Scientific Data Article describing dataset and methodology. |
Code Repository | MIRCA-OS GitHub Repository with data processing scripts. |
Dataset Download | HydroShare MIRCA-OS Dataset |
Community/Support | Contact dataset authors via GitHub or corresponding publication. |
WorldCereal crop calendars are a foundational input for global crop mapping and monitoring, enabling harmonized and reproducible assessments of crop seasonality and supporting operational agricultural monitoring at scale.
Attribute | Description |
---|---|
Short Description | The WorldCereal Project Crop Calendars provide global, season-specific maps of the start (SOS) and end (EOS) of the growing seasons for key temporary crops, initially focusing on maize and wheat. These calendars are essential for global crop mapping and monitoring, supporting the generation of high-resolution, seasonally updated crop type and irrigation maps. |
Provider/Source | WorldCereal Consortium (funded by the European Space Agency, ESA) |
Homepage/Link |
WorldCereal Project Global crop calendars of maize and wheat (figshare) |
License/Terms of Use | Open and free for research and operational use under Creative Commons Attribution 4.0 License. |
Spatial Coverage | Global, with stratification into agro-ecological zones (AEZs). |
Temporal Coverage | Currently available for 2021 (Phase I); designed for seasonal and annual updates. |
Spatial Resolution | 0.5° x 0.5° latitude/longitude grid (approx. 50 km at equator); crop type maps at 10 m resolution. |
Temporal Resolution | Seasonally updated; provides start and end dates for each major growing season per crop. |
Key Variables | Start of Season (SOS), End of Season (EOS) for maize and wheat (winter and spring cereals); future versions will include additional crops (sunflower, rapeseed, millet, sorghum, barley, rye, soybean). |
Attribute | Description |
---|---|
Access Methods | Download from figshare dataset page (includes gridded SOS/EOS maps and documentation); additional products and documentation available on the WorldCereal website. |
Data Formats | NetCDF, GeoTIFF, and CSV for spatial data; PDF and web documentation. |
Data Organization | Organized by crop, season (winter cereals, main maize, secondary maize), and grid cell; maps provided globally at 0.5° resolution. |
Potential Challenges | Currently focused on maize and wheat; spatial resolution of crop calendars is coarser (0.5°) than crop type maps (10 m); future versions will expand crop and temporal coverage. |
Attribute | Description |
---|---|
File Naming Conventions | Files typically include crop, season, and variable (e.g., SOS_maize_main_2021.tif ). |
Variable Names & Units | SOS (start of season), EOS (end of season); units are day-of-year (1–365/366). |
Coordinate Systems | Latitude/longitude (WGS84 datum) for gridded data; crop type maps use UTM or geographic coordinates. |
Data Processing | Crop calendars are generated by merging national/subnational calendars (GEOGLAM, USDA-FAS, FAO, ASAP) and training a spatially aware Random Forest model using ERA5 climate data to estimate SOS/EOS at each grid cell. This enables stratification into zones with similar growing seasons for crop mapping. |
Handling Missing Data | In areas lacking source data, crop calendars are simulated using climate and geographic predictors; quality flags and confidence layers are provided. |
API Availability | Description |
---|---|
Direct API | No dedicated API for crop calendars. |
Programmatic Access | Data downloadable via figshare and WorldCereal website; can be integrated into GIS and remote sensing workflows using standard geospatial libraries. |
Application/Strength/Limitation | Description |
---|---|
Potential Applications |
- Crop-type mapping and monitoring at global and regional scales - Crop condition monitoring, yield estimation, and forecasting - Agroecological zoning and adaptation scenario development - Supporting operational crop monitoring systems and early warning - Input for crop models and remote sensing analysis |
Strengths |
- Combines multiple authoritative sources and machine learning for robust, spatially explicit crop calendars - Season-specific, global coverage for maize and wheat, with future expansion to more crops - Supports high-resolution (10 m) crop type and irrigation mapping |
Limitations |
- Currently limited to maize and wheat (expansion ongoing) - Crop calendars at 0.5° resolution, which may be coarse for local studies - Simulated data in regions with sparse observational input; users should review confidence layers |
Resource Type | Description/Link |
---|---|
User Guides/Documentation |
WorldCereal Final Report (PDF) ESSD Data Descriptor Article |
Dataset Download | figshare: Global crop calendars of maize and wheat |
Community/Support | Contact via WorldCereal website or through project partners. |
Accurately detecting the onset and duration of rainy seasons is essential for effective agricultural planning, water resource management, and assessing climate impacts. Traditional calendar-based definitions of rainy seasons often fall short because they do not account for local variability or year-to-year fluctuations in rainfall patterns. This limitation highlights the need for objective, data-driven methods that leverage rainfall time series to characterize seasonality more precisely.
Key aspects to identify in rainfall time series include:
- Onset of the rainy season: The point at which rainfall begins to increase consistently, signaling the start of the wet period.
- Cessation of the rainy season: When rainfall declines or stops, marking the end of the wet season.
- Length and intensity of rainy periods: The duration and magnitude of rainfall events that define the overall seasonality.
Several methodological approaches exist to detect the onset, duration, and cessation of rainy seasons from rainfall time series data. The main approaches include:
Approach | Description | Relevant R Packages |
---|---|---|
Threshold-based methods | Define rainfall thresholds (e.g., cumulative rainfall over a set number of days) to identify the start and end of rainy seasons. Simple and widely used in hydrological studies. |
hydroTSM (seasonality index), custom threshold scripts |
Change point detection | Use statistical techniques to detect significant shifts or changes in rainfall patterns, such as abrupt increases or decreases in rainfall intensity or frequency. |
changepoint , bfast
|
Time series decomposition | Separate rainfall data into trend, seasonal, and residual components using methods like STL (Seasonal-Trend decomposition using Loess), enabling clearer identification of seasonal cycles and anomalies. |
stats (base R stl() ), seas
|
Machine learning or signal processing methods | Employ advanced algorithms to recognize complex patterns in rainfall data, including clustering, classification, or neural networks, to detect seasonality and rainfall events. These methods can capture nonlinearities and interactions beyond traditional statistics. |
prophet , TSclust , caret
|
Each approach offers distinct advantages and can be selected based on data availability, complexity, and study objectives. Threshold methods provide a straightforward implementation, while change point and decomposition methods offer more nuanced detection of seasonality. Machine learning approaches are promising for large datasets and complex climatic regions but require more computational resources and expertise.
-
hydroTSM includes functions like
si()
to compute seasonality index from rainfall data. -
changepoint and bfast are popular for detecting structural changes (breakpoints) in time series.
-
bfast
decomposes time series into trend, seasonal, and remainder components and detects breaks in each. -
changepoint
provides various statistical methods to identify change points in mean or variance.
-
-
Base R’s stl() function (in the
stats
package) is widely used for seasonal-trend decomposition of time series. -
seas is specialized for seasonal analysis in hydrology and ecology.
-
prophet (by Facebook) is a powerful tool for time series forecasting and seasonality detection, capable of handling multiple seasonalities and trend changes.
-
TSclust and caret support clustering and machine learning workflows on time series data, useful for more advanced pattern recognition and classification tasks.
Threshold-based methods are among the simplest and most widely used approaches to detect the onset and cessation of rainy seasons. These methods define specific rainfall criteria, such as cumulative rainfall over a certain number of days or a minimum daily rainfall threshold, to objectively determine when the rainy season starts and ends.
Term | Definition | References |
---|---|---|
Onset Date (OD) | The first period of five consecutive days accumulating at least 25 mm of rainfall, with the first day and at least two others having rainfall ≥ 1 mm, and no dry spell (rainfall < 1 mm) lasting 7 days or more in the following 30 days. | Adelekan & Adegebo (2014); Mugo et al. (2016); Camberlin et al. (2009); Haleakala et al. (2018); Recha et al. (2012); Rwema et al. (2025) |
Cessation Date (CD) | The first day when the accumulated rainfall over ten consecutive days is less than half of the corresponding potential evapotranspiration (PET). | Kijazi & Reason (2012) ; Sebaziga et al. (2024) |
Season Length (SL) | The number of days between the onset and cessation dates, calculated by subtracting OD from CD for each year. | Gebremichael et al. (2014); Haleakala et al. (2018) |
The modified Hargreaves formula for PET is given by: Here is a display math formula:
where
-
$(R_a)$ is extraterrestrial radiation$(MJ m^{-2} day^{-1})$ -
$(T_{\max})$ ,$(T_{\min})$ are maximum and minimum air temperatures (°C) -
$(R)$ is rainfall (mm) -
$(T)$ is mean air temperature (°C)
We used tabulated Ra values from FAO56 Table 2.6
The following R code demonstrates how to detect the onset dates of the long and short rainy seasons for the year 1983 using our defined rainfall and dry spell criteria.
# --- Step 1: Load necessary libraries ---
library(readr) # For reading CSV files
library(dplyr) # For data manipulation
library(zoo) # For rolling sums
# --- Step 2: Import your dataset ---
# Replace "climatedataset.csv" with your actual file path if needed
rain_data <- read_csv("climatedataset.csv")
# --- Step 3: Convert 'Date' column to Date class ---
# Assuming Date is in YYYYMMDD format like 19830101
rain_data$Date <- as.Date(as.character(rain_data$Date), format = "%Y%m%d")
# --- Step 4: Check data loaded correctly ---
head(rain_data)
# --- Step 5: Filter data for the year of interest (e.g., 1983) ---
year_of_interest <- 1983
rain_year <- rain_data %>% filter(format(Date, "%Y") == as.character(year_of_interest))
# --- Step 6: Define the precise onset detection function ---
detect_onset_precise <- function(rainfall,
onset_cum_threshold = 25,
onset_window = 5,
min_rainy_days = 3, # including first day
min_first_day_rain = 1,
dry_threshold = 1,
max_dry_spell_length = 6, # less than 7 days allowed
dry_spell_check_days = 30) {
n <- length(rainfall)
rolling_sum <- zoo::rollapply(rainfall, width = onset_window, FUN = sum, align = "left", fill = NA)
for (i in 1:(n - onset_window - dry_spell_check_days + 1)) {
# Check cumulative rainfall in 5-day window
if (!is.na(rolling_sum[i]) && rolling_sum[i] >= onset_cum_threshold) {
window_rain <- rainfall[i:(i + onset_window - 1)]
# Check first day rainfall >= 1 mm
if (window_rain[1] < min_first_day_rain) {
next # skip this window
}
# Check at least two other days (besides first) with rainfall >= 1 mm
rainy_days_other <- sum(window_rain[-1] >= min_first_day_rain)
if (rainy_days_other < (min_rainy_days - 1)) {
next # skip this window
}
# Check dry spell in the next 30 days after the 5-day window
dry_period <- rainfall[(i + onset_window):(i + onset_window + dry_spell_check_days - 1)]
# Find lengths of consecutive dry days (< 1 mm)
rle_dry <- rle(dry_period < dry_threshold)
# Check if any dry spell length >= 7 days
if (any(rle_dry$values == TRUE & rle_dry$lengths >= 7)) {
next # reject this window due to long dry spell
}
# If all criteria met, return index of first day of onset
return(i)
}
}
return(NA) # no onset detected
}
# --- Step 7: Define function to detect onset within a date range ---
detect_onset_period <- function(data, start_date, end_date) {
period_data <- data %>% filter(Date >= start_date & Date <= end_date)
onset_idx <- detect_onset_precise(period_data$Rainfall)
if (!is.na(onset_idx)) {
return(period_data$Date[onset_idx])
} else {
return(NA)
}
}
# --- Step 8: Define rainy season periods for bimodal climate ---
long_rains_start <- as.Date(paste0(year_of_interest, "-03-01"))
long_rains_end <- as.Date(paste0(year_of_interest, "-06-30"))
short_rains_start <- as.Date(paste0(year_of_interest, "-09-01"))
short_rains_end <- as.Date(paste0(year_of_interest, "-12-31"))
# --- Step 9: Detect long rains onset ---
long_rains_onset <- detect_onset_period(rain_year, long_rains_start, long_rains_end)
# --- Step 10: Detect short rains onset ---
short_rains_onset <- detect_onset_period(rain_year, short_rains_start, short_rains_end)
# --- Step 11: Print results ---
cat("Year:", year_of_interest, "\n")
cat("Long rains onset:", ifelse(is.na(long_rains_onset), "No onset detected", as.character(long_rains_onset)), "\n")
cat("Short rains onset:", ifelse(is.na(short_rains_onset), "No onset detected", as.character(short_rains_onset)), "\n")
## Inspect rainfall data for March–June 1983
library(ggplot2)
ggplot(rain_year %>% filter(Date >= long_rains_start & Date <= long_rains_end), aes(x = Date, y = Rainfall)) +
geom_col(fill = "blue") +
labs(title = "Rainfall March-June 1983", y = "Daily Rainfall (mm)")
#Inspect rainfall data for September-December 1983
library(ggplot2)
ggplot(rain_year %>% filter(Date >= short_rains_start & Date <= short_rains_end), aes(x = Date, y = Rainfall)) +
geom_col(fill = "blue") +
labs(title = "Rainfall September-December 1983", y = "Daily Rainfall (mm)")
#Inspect rainfall data for the whole year 1983
library(ggplot2)
library(dplyr)
# Assuming rain_year is your filtered data for the year 1983
# If not filtered yet, filter as:
# rain_year <- rain_data %>% filter(format(Date, "%Y") == "1983")
# Plot daily rainfall for the whole year
ggplot(rain_year, aes(x = Date, y = Rainfall)) +
geom_col(fill = "blue") +
labs(title = paste("Daily Rainfall for Year", unique(format(rain_year$Date, "%Y"))),
x = "Date",
y = "Rainfall (mm)") +
theme_minimal() +
scale_x_date(date_breaks = "1 month", date_labels = "%b") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
The output below shows the detected onset dates for the long and short rainy seasons in 1983 based on the applied criteria.
> cat("Year:", year_of_interest, "\n")
Year: 1983
> cat("Long rains onset:", ifelse(is.na(long_rains_onset), "No onset detected", as.character(long_rains_onset)), "\n")
Long rains onset: No onset detected
> cat("Short rains onset:", ifelse(is.na(short_rains_onset), "No onset detected", as.character(short_rains_onset)), "\n")
Short rains onset: 1983-10-07
Below is the complete R script to detect the onset dates of the long and short rainy seasons for each year from 1983 to 2021, using a precise rainfall and dry spell definition. The code processes the daily rainfall data, applies the onset detection criteria, and outputs a clean summary of onset dates for both seasons.
# --- Load libraries ---
library(readr)
library(dplyr)
library(zoo)
# --- Import your dataset ---
rain_data <- read_csv("climatedataset.csv")
rain_data$Date <- as.Date(as.character(rain_data$Date), format = "%Y%m%d")
# --- Define onset detection function as per your precise criteria ---
detect_onset_precise <- function(rainfall,
onset_cum_threshold = 25,
onset_window = 5,
min_rainy_days = 3, # including first day
min_first_day_rain = 1,
dry_threshold = 1,
max_dry_spell_length = 6, # less than 7 days allowed
dry_spell_check_days = 30) {
n <- length(rainfall)
rolling_sum <- zoo::rollapply(rainfall, width = onset_window, FUN = sum, align = "left", fill = NA)
for (i in 1:(n - onset_window - dry_spell_check_days + 1)) {
if (!is.na(rolling_sum[i]) && rolling_sum[i] >= onset_cum_threshold) {
window_rain <- rainfall[i:(i + onset_window - 1)]
if (window_rain[1] < min_first_day_rain) next
rainy_days_other <- sum(window_rain[-1] >= min_first_day_rain)
if (rainy_days_other < (min_rainy_days - 1)) next
dry_period <- rainfall[(i + onset_window):(i + onset_window + dry_spell_check_days - 1)]
rle_dry <- rle(dry_period < dry_threshold)
if (any(rle_dry$values == TRUE & rle_dry$lengths >= 7)) next
return(i)
}
}
return(NA)
}
# --- Function to detect onset within a period for one year ---
detect_onset_period <- function(data, start_date, end_date) {
period_data <- data %>% filter(Date >= start_date & Date <= end_date)
onset_idx <- detect_onset_precise(period_data$Rainfall)
if (!is.na(onset_idx)) {
return(period_data$Date[onset_idx])
} else {
return(NA)
}
}
# --- Years to analyze ---
years <- 1983:2021
# --- Initialize results dataframe ---
results <- data.frame(
Year = integer(),
LongRainsOnset = as.Date(character()),
ShortRainsOnset = as.Date(character()),
stringsAsFactors = FALSE
)
# --- Loop over years ---
for (yr in years) {
rain_year <- rain_data %>% filter(format(Date, "%Y") == as.character(yr))
long_rains_start <- as.Date(paste0(yr, "-03-01"))
long_rains_end <- as.Date(paste0(yr, "-06-30"))
short_rains_start <- as.Date(paste0(yr, "-09-01"))
short_rains_end <- as.Date(paste0(yr, "-12-31"))
long_onset <- detect_onset_period(rain_year, long_rains_start, long_rains_end)
short_onset <- detect_onset_period(rain_year, short_rains_start, short_rains_end)
results <- rbind(results, data.frame(
Year = yr,
LongRainsOnset = long_onset,
ShortRainsOnset = short_onset
))
}
# --- View results ---
print(results)
# Optional: save results to CSV
# write.csv(results, "rainy_season_onsets_1983_2021.csv", row.names = FALSE)
The table below summarizes the detected onset dates for the long and short rainy seasons from 1983 to 2021 based on the applied rainfall and dry spell criteria.
print(results)
Year LongRainsOnset ShortRainsOnset
1 1983 <NA> 1983-10-07
2 1984 <NA> 1984-11-06
3 1985 1985-03-19 <NA>
4 1986 1986-04-10 1986-10-26
5 1987 1987-05-02 1987-10-16
6 1988 1988-03-15 <NA>
7 1989 <NA> <NA>
8 1990 1990-03-04 1990-10-17
9 1991 <NA> <NA>
10 1992 <NA> <NA>
11 1993 1993-04-14 1993-11-01
12 1994 <NA> 1994-10-07
13 1995 <NA> 1995-10-30
14 1996 1996-03-06 1996-09-05
15 1997 1997-03-15 1997-10-21
16 1998 1998-03-03 1998-10-13
17 1999 1999-03-10 1999-11-02
18 2000 <NA> 2000-10-20
19 2001 2001-03-15 2001-09-18
20 2002 2002-03-03 2002-09-21
21 2003 2003-03-18 2003-10-12
22 2004 2004-03-05 2004-10-22
23 2005 <NA> <NA>
24 2006 2006-03-07 2006-10-20
25 2007 2007-03-14 2007-10-03
26 2008 <NA> <NA>
27 2009 2009-03-01 2009-10-05
28 2010 <NA> 2010-10-06
29 2011 2011-04-03 <NA>
30 2012 2012-04-19 2012-10-24
31 2013 2013-03-18 2013-11-20
32 2014 <NA> 2014-11-11
33 2015 <NA> <NA>
34 2016 <NA> <NA>
35 2017 <NA> 2017-11-10
36 2018 2018-03-01 2018-10-17
37 2019 <NA> 2019-09-27
38 2020 2020-03-01 2020-10-17
39 2021 2021-03-16 2021-09-15
The following R code demonstrates how to detect the cessation dates of the long and short rainy seasons for the year 1983 using our defined criteria.
# --- Load necessary libraries ---
library(readr)
library(dplyr)
library(zoo)
# --- Import your dataset ---
# Replace "climatedataset.csv" with the correct path to your file
rain_data <- read_csv("climatedataset.csv")
# --- Convert 'Date' column to Date class ---
rain_data$Date <- as.Date(as.character(rain_data$Date), format = "%Y%m%d")
# --- Add Month column for Ra assignment ---
rain_data <- rain_data %>%
mutate(Month = as.integer(format(Date, "%m")))
# --- Create Ra lookup table for Kigali (approximate FAO56 values at 0° latitude) ---
ra_lookup <- data.frame(
Month = 1:12,
Ra = c(36.2, 37.5, 37.9, 36.8, 34.8, 33.4, 33.9, 35.7, 37.2, 37.4, 36.3, 35.6) # MJ m-2 day-1
)
# --- Join Ra values by Month ---
rain_data <- rain_data %>%
left_join(ra_lookup, by = "Month")
# --- Calculate mean temperature and PET ---
rain_data <- rain_data %>%
mutate(
Tmean = (Tmax + Tmin) / 2,
temp_diff = pmax(Tmax - Tmin - 0.0123 * Rainfall, 0),
PET = 0.00102 * Ra * (temp_diff)^0.76 * (Tmean + 17)
)
# --- Calculate rolling 10-day rainfall sum (including current day) ---
rain_data <- rain_data %>%
arrange(Date) %>%
mutate(
Rainfall_10d = rollapply(Rainfall, width = 10, FUN = sum, align = "right", fill = NA, na.rm = TRUE)
)
# --- Mark cessation candidate days where 10-day rainfall < 0.5 * PET ---
rain_data <- rain_data %>%
mutate(
CessationCandidate = ifelse(Rainfall_10d < 0.5 * PET, TRUE, FALSE)
)
# --- Define cessation detection function for a given period ---
detect_cessation_period <- function(data, start_date, end_date) {
period_data <- data %>% filter(Date >= start_date & Date <= end_date)
cessation_days <- period_data %>% filter(CessationCandidate == TRUE)
if (nrow(cessation_days) == 0) {
return(NA) # No cessation detected in this period
}
# Return earliest cessation candidate date (customize logic if needed)
return(min(cessation_days$Date))
}
# --- Apply cessation detection for year 1983 ---
year_of_interest <- 1983
# Define bimodal rainy season periods for 1983
long_rains_start <- as.Date(paste0(year_of_interest, "-03-01"))
long_rains_end <- as.Date(paste0(year_of_interest, "-06-30"))
short_rains_start <- as.Date(paste0(year_of_interest, "-09-01"))
short_rains_end <- as.Date(paste0(year_of_interest, "-12-31"))
# Detect cessation dates
cessation_long <- detect_cessation_period(rain_data, long_rains_start, long_rains_end)
cessation_short <- detect_cessation_period(rain_data, short_rains_start, short_rains_end)
# Print results
cat("Year:", year_of_interest, "\n")
cat("Long rains cessation:", ifelse(is.na(cessation_long), "No cessation detected", as.character(cessation_long)), "\n")
cat("Short rains cessation:", ifelse(is.na(cessation_short), "No cessation detected", as.character(cessation_short)), "\n")
##for visualisation
library(ggplot2)
# Filter data for long rains period in 1983
long_rains_data <- rain_data %>%
filter(Date >= long_rains_start & Date <= long_rains_end)
ggplot(long_rains_data, aes(x = Date)) +
geom_col(aes(y = Rainfall), fill = "blue", alpha = 0.6) +
geom_line(aes(y = PET), color = "red", size = 1) +
geom_vline(xintercept = as.numeric(cessation_long), linetype = "dashed", color = "darkgreen") +
labs(title = "Long Rains 1983: Rainfall, PET and Cessation",
y = "Rainfall (mm) / PET (MJ m-2 day-1)") +
theme_minimal()
library(ggplot2)
# Filter data for short rains period in 1983
short_rains_data <- rain_data %>%
filter(Date >= short_rains_start & Date <= short_rains_end)
ggplot(short_rains_data, aes(x = Date)) +
geom_col(aes(y = Rainfall), fill = "blue", alpha = 0.6) +
geom_line(aes(y = PET), color = "red", size = 1) +
geom_vline(xintercept = as.numeric(cessation_short), linetype = "dashed", color = "darkgreen") +
labs(title = "Short Rains 1983: Rainfall, PET and Cessation",
y = "Rainfall (mm) / PET (MJ m-2 day-1)",
x = "Date") +
theme_minimal()
library(ggplot2)
library(dplyr)
# Filter data for the year of interest, e.g., 1983
year_of_interest <- 1983
rain_year <- rain_data %>% filter(format(Date, "%Y") == as.character(year_of_interest))
# Plot daily Rainfall as bars and PET as a red line over the whole year
ggplot(rain_year, aes(x = Date)) +
geom_col(aes(y = Rainfall), fill = "blue", alpha = 0.6) +
geom_line(aes(y = PET), color = "red", size = 1) +
labs(title = paste("Daily Rainfall and PET for Year", year_of_interest),
y = "Rainfall (mm) / PET (MJ m⁻² day⁻¹)",
x = "Date") +
theme_minimal() +
scale_x_date(date_breaks = "1 month", date_labels = "%b") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
The output below shows the detected cessation dates for the long and short rainy seasons in 1983 based on the applied criteria.
cat("Year:", year_of_interest, "\n")
Year: 1983
> cat("Long rains cessation:", ifelse(is.na(cessation_long), "No cessation detected", as.character(cessation_long)), "\n")
Long rains cessation: 1983-03-12
> cat("Short rains cessation:", ifelse(is.na(cessation_short), "No cessation detected", as.character(cessation_short)), "\n")
Short rains cessation: 1983-09-01
Below is the complete R script to detect the cessation dates of the long and short rainy seasons for each year from 1983 to 2021, using the provided definition.
# --- Load necessary libraries ---
library(readr)
library(dplyr)
library(zoo)
library(ggplot2)
library(tidyr)
# --- Step 1: Import your dataset ---
rain_data <- read_csv("climatedataset.csv")
rain_data$Date <- as.Date(as.character(rain_data$Date), format = "%Y%m%d")
# --- Step 2: Prepare data ---
rain_data <- rain_data %>%
mutate(
Year = as.integer(format(Date, "%Y")),
Month = as.integer(format(Date, "%m"))
)
# --- Step 3: Assign extraterrestrial radiation (Ra) for Kigali ---
ra_lookup <- data.frame(
Month = 1:12,
Ra = c(36.2, 37.5, 37.9, 36.8, 34.8, 33.4, 33.9, 35.7, 37.2, 37.4, 36.3, 35.6) # MJ m-2 day-1
)
rain_data <- rain_data %>%
left_join(ra_lookup, by = "Month")
# --- Step 4: Calculate PET ---
rain_data <- rain_data %>%
mutate(
Tmean = (Tmax + Tmin) / 2,
temp_diff = pmax(Tmax - Tmin - 0.0123 * Rainfall, 0),
PET = 0.00102 * Ra * (temp_diff)^0.76 * (Tmean + 17)
)
# --- Step 5: Calculate rolling 10-day rainfall sum ---
rain_data <- rain_data %>%
arrange(Date) %>%
group_by(Year) %>%
mutate(
Rainfall_10d = rollapply(Rainfall, width = 10, FUN = sum, align = "right", fill = NA, na.rm = TRUE)
) %>%
ungroup()
# --- Step 6: Mark cessation candidate days ---
rain_data <- rain_data %>%
mutate(
CessationCandidate = ifelse(Rainfall_10d < 0.5 * PET, TRUE, FALSE)
)
# --- Step 7: Define cessation detection function ---
detect_cessation_period <- function(data, start_date, end_date) {
period_data <- data %>% filter(Date >= start_date & Date <= end_date)
cessation_days <- period_data %>% filter(CessationCandidate == TRUE)
if (nrow(cessation_days) == 0) return(NA)
return(min(cessation_days$Date))
}
# --- Step 8: Loop over years to detect cessation for bimodal seasons ---
years <- unique(rain_data$Year)
results <- data.frame(
Year = integer(),
LongRainsCessation = as.Date(character()),
ShortRainsCessation = as.Date(character()),
stringsAsFactors = FALSE
)
for (yr in years) {
long_start <- as.Date(paste0(yr, "-03-01"))
long_end <- as.Date(paste0(yr, "-06-30"))
short_start <- as.Date(paste0(yr, "-09-01"))
short_end <- as.Date(paste0(yr, "-12-31"))
data_year <- rain_data %>% filter(Year == yr)
long_cessation <- detect_cessation_period(data_year, long_start, long_end)
short_cessation <- detect_cessation_period(data_year, short_start, short_end)
results <- rbind(results, data.frame(
Year = yr,
LongRainsCessation = long_cessation,
ShortRainsCessation = short_cessation
))
}
# --- Step 9: Print summary of cessation dates ---
print(results)
The table below summarizes the detected cessation dates for the long and short rainy seasons from 1983 to 2021 based on the definition we defined before.
print(results)
Year LongRainsCessation ShortRainsCessation
1 1983 1983-03-12 1983-09-01
2 1984 1984-03-27 1984-09-06
3 1985 1985-03-08 1985-09-01
4 1986 1986-03-26 1986-09-01
5 1987 1987-03-06 1987-09-01
6 1988 1988-05-31 1988-09-08
7 1989 1989-03-04 1989-09-11
8 1990 1990-05-04 1990-09-01
9 1991 1991-03-07 1991-09-01
10 1992 1992-03-04 1992-09-01
11 1993 1993-05-16 1993-09-01
12 1994 1994-04-08 1994-09-01
13 1995 1995-05-23 1995-09-01
14 1996 1996-05-08 1996-10-15
15 1997 1997-05-27 1997-09-10
16 1998 1998-05-25 1998-12-09
17 1999 1999-05-10 1999-09-22
18 2000 2000-05-23 2000-09-01
19 2001 2001-05-18 2001-09-01
20 2002 2002-05-26 2002-09-01
21 2003 2003-03-14 2003-09-05
22 2004 2004-05-13 2004-09-01
23 2005 2005-04-06 2005-09-01
24 2006 2006-05-28 2006-09-06
25 2007 2007-03-12 2007-09-01
26 2008 2008-05-02 2008-09-05
27 2009 2009-03-21 2009-09-01
28 2010 2010-03-16 2010-09-01
29 2011 2011-03-03 2011-09-08
30 2012 2012-03-14 2012-09-06
31 2013 2013-05-20 2013-09-01
32 2014 2014-03-08 2014-09-09
33 2015 2015-03-13 2015-09-01
34 2016 2016-03-10 2016-09-01
35 2017 2017-04-17 2017-09-01
36 2018 2018-06-14 <NA>
37 2019 2019-03-26 2019-09-12
38 2020 2020-05-26 2020-09-01
39 2021 2021-04-01 2021-09-11
In evaluating rain-based seasonal detection methods, it is essential to consider criteria that reflect both scientific rigor and practical applicability. Key factors include the types of input variables required, the generalizability of the method across diverse climatic and soil conditions, and the extent to which the method has been adopted by major institutions and operational projects globally. It is important to balance methodological sophistication with feasibility, especially in data-limited contexts, while also ensuring that the approach aligns with real-world agricultural decision-making needs. This evaluation focuses on three representative methods that span this spectrum, from simple rainfall thresholds to integrated soil moisture models and advanced satellite vegetation indices, providing a comprehensive overview of their strengths, limitations, and institutional relevance.
- Input Variables: Daily rainfall only.
-
Generalizability:
- Regional: Hard-coded parameters (e.g., "25mm in first dekad, 20mm in next two") limit global applicability.
- Soil Blindness: Ignores soil properties (e.g., drainage in sandy vs. clay soils), reducing accuracy in heterogeneous regions.
-
Institutional Adoption:
- High: FAO’s standard method for agrometeorological bulletins and seasonal maps.
- Approach Type: Heuristic, rule-based method using fixed rainfall thresholds.
- Strengths: Low technical barriers, ideal for resource-limited regions.
- Weaknesses: Fails in climate-variable zones; no evaporation/temperature integration.
- Documentation: FAO Handbook (2019).
- Input Variables: Rainfall, soil type, temperature, evapotranspiration.
-
Generalizability:
- Moderate-High: Accounts for soil water-holding capacity (e.g., sand vs. clay) and climate.
- Adaptability: Adjustable parameters for regional calibration (e.g., using SoilGrids data).
-
Institutional Adoption:
- Moderate: World Bank projects (e.g., East Africa climate-smart agriculture); not yet FAO-adopted.
- Approach Type: Model-based, incorporating soil water balance and climate variables.
- Strengths: Reflects actual planting conditions; superior to rainfall-only methods.
- Weaknesses: Requires soil data and local calibration.
- Documentation:
- Input Variables: Satellite vegetation indices (NDVI/PRI), rainfall, temperature.
-
Generalizability:
- High: Tracks actual plant "green-up" via satellite; applicable globally.
- Strength: Less noise from dry spells; captures phenology (e.g., growing season length).
-
Institutional Adoption:
- Emerging: NASA/ESA projects (e.g., MODIS VI); limited operational use in agriculture.
- Approach Type: Model-based using remote sensing to track vegetation phenology.
- Strengths: Direct biomass monitoring; large-scale suitability.
- Weaknesses: Cloud cover disrupts data; technical capacity required.
- Documentation:
Method | Input Variables | Approach Type | Generalizability | Institutional Adoption | Strengths | Limitations |
---|---|---|---|---|---|---|
Rainfall Threshold | Rainfall only | Heuristic (rule-based) | Regional; parameters often hard-coded for specific climates and soils | High (FAO widely used) | Simple, low data needs, easy to implement | Limited transferability; ignores soil and temp |
Soil Moisture-Integrated | Rainfall + soil + climate | Model-based | Moderate-High; adaptable with soil and climate data | Moderate (World Bank projects) | More accurate; accounts for soil water retention | Requires soil data and calibration; moderate complexity |
Vegetation Index (MVDI) | Satellite vegetation indices + climate | Model-based | High; applicable globally via remote sensing | Emerging (NASA/ESA) | Captures actual plant phenology; large-scale monitoring | Cloud cover issues; technical and data intensive |
-
Tiered Implementation:
- Resource-Limited: FAO rainfall threshold (simple, low-cost).
- Data-Rich Regions: Soil moisture method (balanced accuracy/feasibility).
- Advanced Monitoring: NDVI/MVDI for research/policy (e.g., climate adaptation).
-
Validation Protocol:
- Ground-truth methods using farmer-reported planting dates.
- FAO Rainfall Threshold: FAO Handbook (2019)
- Soil Moisture Guidance: Drought.gov Soil Moisture Data Quality
- NDVI Algorithms: MODIS VI Algorithm (NASA)
- NDVI/PRI Guide: METER Group NDVI/PRI Guide
Normalized Difference Vegetation Index (NDVI) data is a valuable resource for monitoring vegetation health and phenology, widely used in agricultural and environmental applications. Accessing NDVI data for specific locations or regions can be done through several common sources and tools, including satellite products and cloud-based platforms.
-
MODIS Satellite Products (NASA)
MODIS provides global NDVI data at moderate spatial and temporal resolutions. It is freely available and widely used for vegetation monitoring.
Documentation and access: MODIS Vegetation Indices (NASA) -
Sentinel-2 (ESA)
Sentinel-2 offers high-resolution multispectral imagery, including bands suitable for NDVI calculation. It is ideal for finer-scale vegetation analysis.
Information: Sentinel-2 Overview (ESA) -
Google Earth Engine (GEE) APIs
GEE provides a powerful cloud computing platform with access to a vast archive of satellite imagery, including MODIS, Sentinel-2, Landsat, and others. It enables extraction of NDVI time series for points or regions via APIs.
Tutorials and API docs:
-
MODISTools (R package)
Facilitates downloading and processing MODIS NDVI data directly within R for user-defined locations.
CRAN page: MODISTools -
rgee (R interface to Google Earth Engine)
Provides an R interface to the GEE platform, allowing users to run GEE scripts and extract NDVI data programmatically.
GitHub repository and documentation: rgee
Google Earth Engine (GEE) provides access to several high-quality NDVI datasets derived from different satellite platforms, enabling global vegetation monitoring at various spatial and temporal resolutions.
-
MODIS Vegetation Indices (MOD13 series)
The MOD13 products provide 16-day and monthly NDVI composites at 250m to 1km resolution. These are widely used for global vegetation monitoring and are available as:-
MOD13Q1
(16-day, 250m) -
MOD13A2
(16-day, 1km) -
MOD13A3
(monthly, 1km)
Documentation: MODIS Vegetation Indices (NASA)
-
-
Landsat Series (e.g., Landsat 8 OLI)
Landsat provides higher spatial resolution (30m) multispectral imagery, from which NDVI can be calculated on demand. Suitable for detailed local and regional analyses.
Example GEE collection:LANDSAT/LC08/C02/T1_TOA
More info: Landsat Collections in GEE -
Sentinel-2 MSI
Sentinel-2 offers 10-20m resolution multispectral data with frequent revisit times, ideal for fine-scale NDVI mapping.
GEE collection:COPERNICUS/S2
More info: Sentinel-2 Overview (ESA) -
GIMMS NDVI (1982–2022)
The GIMMS dataset provides a long-term NDVI record from AVHRR and MODIS sensors at 8km resolution, useful for climate and vegetation trend studies.
GEE asset:"projects/sat-io/open-datasets/PKU-GIMMS-NDVI/AVHRR_MODIS_CONSOLIDATED"
More info: GIMMS NDVI in GEE