Here I describe the method used to extract phenological variables from GIMMS and MODIS NDVI data. This document is a bit detailed in order to show exactly what I have done, so it can be understood and critiqued if needed. It is a mix of code and text from which hopefully methods-type information can be extracted. I wrote it in english so it may be understood by more people if others need it.
The data can be easily downloaded and extracted using the excellent gimms package. First, we can use the updateInventory
function fromm the gimms package to list what is available.
library(gimms)
gimms_files_v1 <- updateInventory()
head(gimms_files_v1)
## [1] "https://ecocast.arc.nasa.gov/data/pub/gimms/3g.v1/ndvi3g_geo_v1_1981_0712.nc4"
## [2] "https://ecocast.arc.nasa.gov/data/pub/gimms/3g.v1/ndvi3g_geo_v1_1982_0106.nc4"
## [3] "https://ecocast.arc.nasa.gov/data/pub/gimms/3g.v1/ndvi3g_geo_v1_1982_0712.nc4"
## [4] "https://ecocast.arc.nasa.gov/data/pub/gimms/3g.v1/ndvi3g_geo_v1_1983_0106.nc4"
## [5] "https://ecocast.arc.nasa.gov/data/pub/gimms/3g.v1/ndvi3g_geo_v1_1983_0712.nc4"
## [6] "https://ecocast.arc.nasa.gov/data/pub/gimms/3g.v1/ndvi3g_geo_v1_1984_0106.nc4"
The data can then be downloaded with the downloadGimms
function. A path is given to tell the function where to store the files. The .nc4 files will take about 30 gig of space and it takes quite a while to download them.
path <- "C:/Users/rouf1703/Documents/UdeS/Consultation/L-ARenaud/GIMMS/"
gimms_files <- downloadGimms(x = as.Date("1981-01-01"), y = as.Date("2016-01-01"),
dsn = path, cores = 2L)
The data is brought into R using the rasterizeGimms
function. This will convert the data contained in the .nc4 files into raster data. Once converted to raster, here is what the content of the first file looks like. The data begins in July 1981. Each map represents a period of 15 days.
library(raster)
library(rasterVis)
x <- list.files(path)
world <- rasterizeGimms(x = paste0(path, x[1]), cores = 6)
levelplot(world, col.regions = rev(terrain.colors(100)), cuts = 99)
To get the data needed, we will use a shapefile of the region of interest to delimit the zone for which we want to extract the NDVI data. We will bring the region of interest in the R session as a Spatial
object. For making sure the extracted raster is large enough, we will use a buffer around the region to extract a bit more than what is needed. A 50 km buffer is used. We first determine the bounding box of the region to speed-up the buffer calculation.
library(sp)
library(rgdal)
library(rgeos)
regions <- readOGR("C:/Users/rouf1703/Documents/UdeS/Consultation/YPoisson/Doc",
layer = "largezone_BC_Alberta", verbose = FALSE)
buff <- gBuffer(gEnvelope(regions), width = 50000)
plot(buff)
plot(regions, add = TRUE)
The region is in a different coordinate system than the latlon system of the raster files. To use both, we project the region to the same coordinate system than the one from the NDVI raster data (see the familiar latlon WGS84 system epsg: 4326)
proj4string(regions)
## [1] "+proj=utm +zone=11 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0"
proj4string(world)
## [1] "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"
buff <- spTransform(buff, CRS(proj4string(world))) # en latlon
regions <- spTransform(regions, CRS(proj4string(world)))
The next step is to list all files downloaded and build date indices for each bi-monthly period. Because the bi-monthly periods are marked with the first date of the period, the middle date of the period will be used instead and a vector doy
(day of year) created to associate with values (confirm that using the middle date is the way to go, maybe the date given is already the one that best represents the mean value?) .
ts <- monthlyIndices(x, version = 1, timestamp = TRUE)
doy <- as.Date(as.character(ts + round(c(diff(ts), 17)/2, 0)))
The data is extracted from each file to a raster using again the rasterizeGimms
function and the extent of the buffer applied on the region. To speed-up the process, more than one core can be used.
r <- rasterizeGimms(x = paste0(path, x), ext = buff, cores = 6)
r
## class : RasterStack
## dimensions : 106, 180, 19080, 828 (nrow, ncol, ncell, nlayers)
## resolution : 0.08333333, 0.08333333 (x, y)
## extent : -124.1667, -109.1667, 48.33333, 57.16667 (xmin, xmax, ymin, ymax)
## coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
## names : ndvi.1.1, ndvi.2.1, ndvi.3.1, ndvi.4.1, ndvi.5.1, ndvi.6.1, ndvi.7.1, ndvi.8.1, ndvi.9.1, ndvi.10.1, ndvi.11.1, ndvi.12.1, ndvi.1.2, ndvi.2.2, ndvi.3.2, ...
## min values : -0.2180, -0.1546, -0.1546, -0.1579, -0.1534, -0.2488, -0.1519, -0.1523, -0.1447, -0.1466, -0.1899, -0.1930, -0.2290, -0.2105, -0.2100, ...
## max values : 0.9810, 0.9829, 0.9949, 0.9902, 0.9890, 0.9411, 0.9900, 0.9978, 0.9862, 0.9792, 0.8744, 0.8551, 0.8658, 0.8648, 0.9826, ...
The r
object is a RasterStack
object with 106 x 180 cells and 828 layers.
Let’s visualize the data for the first 6 layers of the raster stack to see if the correct region has been extracted.
levelplot(subset(r, 1:6), col.regions = rev(terrain.colors(100)), cuts = 99) +
layer(sp.polygons(regions, col = gray(0, 0.2)))
Alternatively, the region and the first layer of the raster can be plotted on an interactive map using the leaflet and the tmap package.
library(tmap)
tmap_mode("view")
tm_shape(r[[1]]) +
tm_raster(palette = rev(terrain.colors(100)),n=12) +
tm_shape(regions) +
tm_borders(lwd = 2,alpha = 0.3, col = "black") +
tm_layout(basemaps = c("Esri.WorldImagery", "Esri.WorldShadedRelief", "Esri.NatGeoWorldMap"))