diff --git a/DESCRIPTION b/DESCRIPTION index 361ac1f..dc8c867 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -92,6 +92,7 @@ Collate: 'subset.R' 'twdtw.R' 'twdtwApply.R' + 'twdtwApplyParallel.R' 'twdtwAssess.R' 'twdtwClassify.R' 'twdtwCrossValidate.R' diff --git a/NAMESPACE b/NAMESPACE index 09bcdd4..2fcbd71 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -26,6 +26,7 @@ export(shiftDates) export(symmetric1) export(symmetric2) export(twdtwApply) +export(twdtwApplyParallel) export(twdtwClassify) exportMethods("[") exportMethods("[[") @@ -64,6 +65,7 @@ exportMethods(show) exportMethods(subset) exportMethods(summary) exportMethods(twdtwApply) +exportMethods(twdtwApplyParallel) exportMethods(twdtwAssess) exportMethods(twdtwClassify) exportMethods(twdtwCrossValidate) diff --git a/R/twdtwApplyParallel.R b/R/twdtwApplyParallel.R new file mode 100644 index 0000000..4c94749 --- /dev/null +++ b/R/twdtwApplyParallel.R @@ -0,0 +1,345 @@ +#' @include methods.R +#' @title Apply TWDTW analysis to twdtwRaster using parallel processing +#' @name twdtwApplyParallel +#' @author Victor Maus, \email{vwmaus1@@gmail.com} +#' +#' @description This function performs a multidimensional Time-Weighted DTW +#' analysis and retrieves the matches between the temporal patterns and +#' a set of time series [1]. +#' +#' @inheritParams twdtwApply +#' +#' @references +#' [1] Maus V, Camara G, Cartaxo R, Sanchez A, Ramos FM, de Queiroz, GR. +#' (2016). A Time-Weighted Dynamic Time Warping method for land use and land cover +#' mapping. IEEE Journal of Selected Topics in Applied Earth Observations and Remote +#' Sensing, vol.9, no.8, pp.3729-3739. +#' @references +#' [2] Giorgino, T. (2009). Computing and Visualizing Dynamic Time Warping Alignments in R: +#' The dtw Package. Journal of Statistical Software, 31, 1-24. +#' @references +#' [3] Muller, M. (2007). Dynamic Time Warping. In Information Retrieval for Music +#' and Motion (pp. 79-84). London: Springer London, Limited. +#' +#' @details The linear \code{linearWeight} and \code{logisticWeight} weight functions +#' can be passed to \code{twdtwApply} through the argument \code{weight.fun}. This will +#' add a time-weight to the dynamic time warping analysis. The time weight +#' creates a global constraint useful to analyse time series with phenological cycles +#' of vegetation that are usually bound to seasons. In previous studies by [1] the +#' logistic weight had better results than the linear for land cover classification. +#' See [1] for details about the method. +#' +#' @return An object of class twdtwRaster. +#' +#' @seealso +#' \code{\link[dtwSat]{twdtwRaster-class}}, and +#' \code{\link[dtwSat]{createPatterns}} +#' +#' @export +setGeneric(name = "twdtwApplyParallel", + def = function(x, y, resample=TRUE, length=NULL, weight.fun=NULL, + dist.method="Euclidean", step.matrix = symmetric1, n=NULL, + span=NULL, min.length=0, theta = 0.5, ...) standardGeneric("twdtwApplyParallel")) + + + +#' @rdname twdtwApplyParallel +#' @aliases twdtwApplyParallel-twdtwRaster +#' @examples +#' \dontrun{ +#' # Run TWDTW analysis for raster time series +#' patt = MOD13Q1.MT.yearly.patterns +#' evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) +#' ndvi = brick(system.file("lucc_MT/data/ndvi.tif", package="dtwSat")) +#' red = brick(system.file("lucc_MT/data/red.tif", package="dtwSat")) +#' blue = brick(system.file("lucc_MT/data/blue.tif", package="dtwSat")) +#' nir = brick(system.file("lucc_MT/data/nir.tif", package="dtwSat")) +#' mir = brick(system.file("lucc_MT/data/mir.tif", package="dtwSat")) +#' doy = brick(system.file("lucc_MT/data/doy.tif", package="dtwSat")) +#' timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") +#' rts = twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) +#' +#' time_interval = seq(from=as.Date("2007-09-01"), to=as.Date("2013-09-01"), +#' by="12 month") +#' log_fun = weight.fun=logisticWeight(-0.1,50) +#' +#' r_twdtw = twdtwApply(x=rts, y=patt, weight.fun=log_fun, breaks=time_interval, +#' filepath="~/test_twdtw", overwrite=TRUE, format="GTiff") +#' +#' plot(r_twdtw, type="distance") +#' +#' r_lucc = twdtwClassify(r_twdtw, format="GTiff", overwrite=TRUE) +#' +#' plot(r_lucc) +#' +#' plot(r_lucc, type="distance") +#' +#' } +#' @export +setMethod(f = "twdtwApplyParallel", "twdtwRaster", + def = function(x, y, resample, length, weight.fun, dist.method, step.matrix, n, span, min.length, theta, + breaks=NULL, from=NULL, to=NULL, by=NULL, overlap=0.5, chunk.size=1000, filepath=NULL, silent=FALSE, ...){ + if(!is(step.matrix, "stepPattern")) + stop("step.matrix is not of class stepPattern") + if(is.null(weight.fun)) + weight.fun = function(psi) 0 + if(!is(weight.fun, "function")) + stop("weight.fun is not a function") + if( overlap < 0 & 1 < overlap ) + stop("overlap out of range, it must be a number between 0 and 1") + if(is.null(breaks)) + if( !is.null(from) & !is.null(to) ){ + breaks = seq(as.Date(from), as.Date(to), by=by) + } else { + patt_range = lapply(index(y), range) + patt_diff = trunc(sapply(patt_range, diff)/30)+1 + min_range = which.min(patt_diff) + by = patt_diff[[min_range]] + from = patt_range[[min_range]][1] + to = from + month(to) = month(to) + by + year(from) = year(range(index(x))[1]) + year(to) = year(range(index(x))[2]) + if(to