From 5f4b5b64b2920adf4b9207cfcc3bc410f36c4912 Mon Sep 17 00:00:00 2001 From: vwmaus Date: Sat, 15 Jul 2023 13:54:46 +0200 Subject: [PATCH] Clean repo --- .travis.yml | 54 -- DESCRIPTION | 95 +-- NAMESPACE | 132 +--- NEWS.md | 2 +- R/class-crossValidation.R | 115 ---- R/class-twdtwAssessment.R | 95 --- R/class-twdtwMatches.R | 148 ---- R/class-twdtwRaster.R | 256 ------- R/class-twdtwTimeSeries.R | 155 ----- R/createPatterns.R | 173 ----- R/create_patterns.R | 100 +++ R/data.R | 19 - R/dtw.R | 134 ---- R/dwtSat.R | 35 - R/getInternals.R | 84 --- R/getMatchingDates.R | 18 - R/getTimeSeries.R | 195 ------ R/linearWeight.R | 50 -- R/logisticWeight.R | 50 -- R/methods.R | 630 ------------------ R/miscellaneous.R | 144 +--- R/plot.R | 231 ------- R/plotAccuracy.R | 165 ----- R/plotAdjustedArea.R | 94 --- R/plotAlignments.R | 107 --- R/plotArea.R | 134 ---- R/plotChanges.R | 121 ---- R/plotClassification.R | 114 ---- R/plotCostMatrix.R | 124 ---- R/plotDistance.R | 97 --- R/plotMapSamples.R | 48 -- R/plotMaps.R | 103 --- R/plotMatches.R | 150 ----- R/plotPaths.R | 129 ---- R/plotTimeSeries.R | 82 --- R/{plotPatterns.R => plot_patterns.R} | 24 +- R/resampleTimeSeries.R | 64 -- R/subset.R | 171 ----- R/twdtw.R | 164 ----- R/twdtwApply.R | 513 -------------- R/twdtwAssess.R | 359 ---------- R/twdtwClassify.R | 281 -------- R/twdtwCrossValidate.R | 117 ---- R/twdtwDist.R | 11 - R/twdtwXtable.R | 302 --------- R/twdtw_reduce_time.R | 263 -------- R/utils.R | 24 - R/zzz.R | 74 +- README.Rmd | 46 -- _config.yml | 1 - figure/plot-MOD13Q1.ts-ts-1.png | Bin 77723 -> 0 bytes figure/plot-alignment-1.png | Bin 23537 -> 0 bytes figure/plot-area-1.png | Bin 7282 -> 0 bytes figure/plot-area-uncertainty-1.png | Bin 12498 -> 0 bytes figure/plot-changes-1.png | Bin 24077 -> 0 bytes figure/plot-group-1.png | Bin 90036 -> 0 bytes figure/plot-maps-1.png | Bin 6914 -> 0 bytes figure/plot-match-1.png | Bin 42711 -> 0 bytes figure/plot-path-1.png | Bin 31485 -> 0 bytes figure/plot-patterns-1.png | Bin 76915 -> 0 bytes figure/plot-patterns-map-1.png | Bin 66063 -> 0 bytes figure/plot-users-prodcucers-1.png | Bin 12273 -> 0 bytes man/MOD13Q1.MT.yearly.patterns.Rd | 16 +- man/MOD13Q1.patterns.list.Rd | 20 +- man/MOD13Q1.ts.Rd | 18 +- man/MOD13Q1.ts.labels.Rd | 2 +- man/MOD13Q1.ts.list.Rd | 20 +- man/createPatterns.Rd | 104 --- man/create_pattern.Rd | 58 ++ man/dtwSat.Rd | 26 - man/get.Rd | 56 -- man/getTimeSeries.Rd | 94 --- ...tDatesFromDOY.Rd => get_dates_from_doy.Rd} | 21 +- man/linearWeight.Rd | 45 -- man/logisticWeight.Rd | 45 -- man/plot.Rd | 66 -- man/plotAccuracy.Rd | 65 -- man/plotAdjustedArea.Rd | 60 -- man/plotAlignments.Rd | 63 -- man/plotArea.Rd | 106 --- man/plotChanges.Rd | 85 --- man/plotClassification.Rd | 68 -- man/plotCostMatrix.Rd | 62 -- man/plotDistance.Rd | 68 -- man/plotMapSamples.Rd | 120 ---- man/plotMaps.Rd | 85 --- man/plotMatches.Rd | 76 --- man/plotPaths.Rd | 56 -- man/plotTimeSeries.Rd | 43 -- man/{plotPatterns.Rd => plot_patterns.Rd} | 30 +- man/reexports.Rd | 19 - man/resampleTimeSeries.Rd | 40 -- man/shiftDates.Rd | 55 -- man/shift_dates.Rd | 29 + man/subset.Rd | 87 --- man/twdtwApply.Rd | 272 -------- man/twdtwAssess.Rd | 284 -------- man/twdtwAssessment-class.Rd | 48 -- man/twdtwClassify.Rd | 576 ---------------- man/twdtwCrossValidate.Rd | 81 --- man/twdtwCrossValidation-class.Rd | 85 --- man/twdtwMatches-class.Rd | 131 ---- man/twdtwRaster-class.Rd | 203 ------ man/twdtwReduceTime.Rd | 108 --- man/twdtwTimeSeries-class.Rd | 127 ---- man/twdtwXtable.Rd | 139 ---- src/bestmatches.f | 80 --- src/computecost.f | 89 --- src/ellapsed.f | 17 - src/g.f | 37 - src/init.c | 33 - src/logtwdtw.f | 31 - src/tracepath.f | 77 --- src/twdtw.f | 157 ----- tic.R | 1 - vignettes/twdtw01.Rmd | 109 --- vignettes/twdtw02-lucc.Rmd | 180 ----- vignettes/twdtw03-speed.Rmd | 64 -- 118 files changed, 268 insertions(+), 11266 deletions(-) delete mode 100644 .travis.yml delete mode 100644 R/class-crossValidation.R delete mode 100644 R/class-twdtwAssessment.R delete mode 100644 R/class-twdtwMatches.R delete mode 100644 R/class-twdtwRaster.R delete mode 100644 R/class-twdtwTimeSeries.R delete mode 100644 R/createPatterns.R create mode 100644 R/create_patterns.R delete mode 100644 R/dtw.R delete mode 100644 R/dwtSat.R delete mode 100644 R/getInternals.R delete mode 100644 R/getMatchingDates.R delete mode 100644 R/getTimeSeries.R delete mode 100644 R/linearWeight.R delete mode 100644 R/logisticWeight.R delete mode 100644 R/methods.R delete mode 100644 R/plot.R delete mode 100644 R/plotAccuracy.R delete mode 100644 R/plotAdjustedArea.R delete mode 100644 R/plotAlignments.R delete mode 100644 R/plotArea.R delete mode 100644 R/plotChanges.R delete mode 100644 R/plotClassification.R delete mode 100644 R/plotCostMatrix.R delete mode 100644 R/plotDistance.R delete mode 100644 R/plotMapSamples.R delete mode 100644 R/plotMaps.R delete mode 100644 R/plotMatches.R delete mode 100644 R/plotPaths.R delete mode 100644 R/plotTimeSeries.R rename R/{plotPatterns.R => plot_patterns.R} (60%) delete mode 100644 R/resampleTimeSeries.R delete mode 100644 R/subset.R delete mode 100644 R/twdtw.R delete mode 100644 R/twdtwApply.R delete mode 100644 R/twdtwAssess.R delete mode 100644 R/twdtwClassify.R delete mode 100644 R/twdtwCrossValidate.R delete mode 100644 R/twdtwDist.R delete mode 100644 R/twdtwXtable.R delete mode 100644 R/twdtw_reduce_time.R delete mode 100644 R/utils.R delete mode 100644 README.Rmd delete mode 100644 _config.yml delete mode 100644 figure/plot-MOD13Q1.ts-ts-1.png delete mode 100644 figure/plot-alignment-1.png delete mode 100644 figure/plot-area-1.png delete mode 100644 figure/plot-area-uncertainty-1.png delete mode 100644 figure/plot-changes-1.png delete mode 100644 figure/plot-group-1.png delete mode 100644 figure/plot-maps-1.png delete mode 100644 figure/plot-match-1.png delete mode 100644 figure/plot-path-1.png delete mode 100644 figure/plot-patterns-1.png delete mode 100644 figure/plot-patterns-map-1.png delete mode 100644 figure/plot-users-prodcucers-1.png delete mode 100644 man/createPatterns.Rd create mode 100644 man/create_pattern.Rd delete mode 100644 man/dtwSat.Rd delete mode 100644 man/get.Rd delete mode 100644 man/getTimeSeries.Rd rename man/{getDatesFromDOY.Rd => get_dates_from_doy.Rd} (61%) delete mode 100644 man/linearWeight.Rd delete mode 100644 man/logisticWeight.Rd delete mode 100644 man/plot.Rd delete mode 100644 man/plotAccuracy.Rd delete mode 100644 man/plotAdjustedArea.Rd delete mode 100644 man/plotAlignments.Rd delete mode 100644 man/plotArea.Rd delete mode 100644 man/plotChanges.Rd delete mode 100644 man/plotClassification.Rd delete mode 100644 man/plotCostMatrix.Rd delete mode 100644 man/plotDistance.Rd delete mode 100644 man/plotMapSamples.Rd delete mode 100644 man/plotMaps.Rd delete mode 100644 man/plotMatches.Rd delete mode 100644 man/plotPaths.Rd delete mode 100644 man/plotTimeSeries.Rd rename man/{plotPatterns.Rd => plot_patterns.Rd} (68%) delete mode 100644 man/reexports.Rd delete mode 100644 man/resampleTimeSeries.Rd delete mode 100644 man/shiftDates.Rd create mode 100644 man/shift_dates.Rd delete mode 100644 man/subset.Rd delete mode 100644 man/twdtwApply.Rd delete mode 100644 man/twdtwAssess.Rd delete mode 100644 man/twdtwAssessment-class.Rd delete mode 100644 man/twdtwClassify.Rd delete mode 100644 man/twdtwCrossValidate.Rd delete mode 100644 man/twdtwCrossValidation-class.Rd delete mode 100644 man/twdtwMatches-class.Rd delete mode 100644 man/twdtwRaster-class.Rd delete mode 100644 man/twdtwReduceTime.Rd delete mode 100644 man/twdtwTimeSeries-class.Rd delete mode 100644 man/twdtwXtable.Rd delete mode 100644 src/bestmatches.f delete mode 100644 src/computecost.f delete mode 100644 src/ellapsed.f delete mode 100644 src/g.f delete mode 100644 src/init.c delete mode 100644 src/logtwdtw.f delete mode 100644 src/tracepath.f delete mode 100644 src/twdtw.f delete mode 100644 tic.R delete mode 100644 vignettes/twdtw01.Rmd delete mode 100644 vignettes/twdtw02-lucc.Rmd delete mode 100644 vignettes/twdtw03-speed.Rmd diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3994ef3..0000000 --- a/.travis.yml +++ /dev/null @@ -1,54 +0,0 @@ -language: r - -r: - - release -# - devel - -deploy.skip_cleanup: true - -sudo: required -dist: trusty - -cache: - - packages - - ccache - -latex: true - -r_github_packages: - - r-lib/covr - -bioc_packages: - - Biobase - -addons: - apt: - sources: - - sourceline: 'ppa:ubuntugis/ubuntugis-unstable' - packages: - - libproj-dev - - libgeos-dev - - libspatialite-dev - - libgdal-dev - -before_install: - - R -e 'install.packages("rgdal", repos="http://R-Forge.R-project.org")' - - R -q -e 'install.packages("remotes"); remotes::install_github("ropenscilabs/tic"); tic::prepare_all_stages()' - -r_packages: - - covr - -after_success: - - Rscript -e 'library(covr); codecov()' - -after_success: - - R -q -e 'covr::codecov(quiet = FALSE)' - -install: R -q -e 'tic::install()' -script: R -q -e 'tic::script()' -before_deploy: R -q -e 'tic::before_deploy()' -deploy: - provider: script - script: R -q -e 'tic::deploy()' - on: - branch: master diff --git a/DESCRIPTION b/DESCRIPTION index edb5e33..bfbce85 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,7 +2,7 @@ Package: dtwSat Type: Package Title: Time-Weighted Dynamic Time Warping for Satellite Image Time Series Analysis Version: 1.0.0 -Date: 2023-06-30 +Date: 2023-07-31 Authors@R: c(person(given = "Victor", family = "Maus", @@ -30,90 +30,19 @@ Description: Provides an implementation of the Time-Weighted Dynamic Time perform TWDTW analysis for satellite datasets, visualize the results of the analysis, produce land cover maps, create temporal plots for land cover change, and compute accuracy metrics. -Depends: - R (>= 3.5.0), - zoo, - raster, - ggplot2 -Imports: - methods, - rgdal, - dtw, - proxy, - scales, - reshape2, - grDevices, - RColorBrewer, - plyr, - stats, - sp, - lubridate, - caret, - mgcv, - xtable, - Rdpack, - data.table, - foreach -Suggests: - gridExtra, - grid, - png, - Hmisc, - rbenchmark, - doParallel, - knitr, - rmarkdown -License: GPL (>= 3) | file LICENSE -URL: https://www.victor-maus.com/dtwSat/, https://github.com/vwmaus/dtwSat/ +License: GPL (>= 3) +URL: https://github.com/vwmaus/dtwSat/ BugReports: https://github.com/vwmaus/dtwSat/issues/ Maintainer: Victor Maus LazyData: true -VignetteBuilder: - knitr Encoding: UTF-8 +Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 -Collate: - 'class-crossValidation.R' - 'class-twdtwRaster.R' - 'class-twdtwAssessment.R' - 'class-twdtwTimeSeries.R' - 'class-twdtwMatches.R' - 'createPatterns.R' - 'data.R' - 'dtw.R' - 'dwtSat.R' - 'getInternals.R' - 'getMatchingDates.R' - 'getTimeSeries.R' - 'linearWeight.R' - 'logisticWeight.R' - 'methods.R' - 'miscellaneous.R' - 'plot.R' - 'plotAccuracy.R' - 'plotAdjustedArea.R' - 'plotAlignments.R' - 'plotArea.R' - 'plotChanges.R' - 'plotClassification.R' - 'plotCostMatrix.R' - 'plotDistance.R' - 'plotMapSamples.R' - 'plotMaps.R' - 'plotMatches.R' - 'plotPaths.R' - 'plotPatterns.R' - 'plotTimeSeries.R' - 'resampleTimeSeries.R' - 'subset.R' - 'twdtw.R' - 'twdtwApply.R' - 'twdtwAssess.R' - 'twdtwClassify.R' - 'twdtwCrossValidate.R' - 'twdtwDist.R' - 'twdtwXtable.R' - 'twdtw_reduce_time.R' - 'utils.R' - 'zzz.R' -RdMacros: Rdpack +Depends: + twdtw +Imports: + stats, + mgcv +Suggests: + rbenchmark, + testthat diff --git a/NAMESPACE b/NAMESPACE index 5c60500..49b478b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,130 +1,10 @@ # Generated by roxygen2: do not edit by hand -export(asymmetric) -export(createPatterns) -export(getDatesFromDOY) -export(linearWeight) -export(logisticWeight) -export(plot) -export(plotAccuracy) -export(plotAdjustedArea) -export(plotAlignments) -export(plotArea) -export(plotChanges) -export(plotClassification) -export(plotCostMatrix) -export(plotDistance) -export(plotMapSamples) -export(plotMaps) -export(plotMatches) -export(plotPaths) -export(plotPatterns) -export(plotTimeSeries) -export(rabinerJuangStepPattern) -export(resampleTimeSeries) -export(shiftDates) -export(symmetric1) -export(symmetric2) -export(twdtwApply) -export(twdtwClassify) -export(twdtwReduceTime) -exportMethods("[") -exportMethods("[[") -exportMethods(as.data.frame) -exportMethods(as.list) -exportMethods(as.twdtwTimeSeries) -exportMethods(bands) -exportMethods(coordinates) -exportMethods(coverages) -exportMethods(createPatterns) -exportMethods(crop) -exportMethods(dim) -exportMethods(extent) -exportMethods(getAlignments) -exportMethods(getInternals) -exportMethods(getMatches) -exportMethods(getPatterns) -exportMethods(getTimeSeries) -exportMethods(index) -exportMethods(is.twdtwMatches) -exportMethods(is.twdtwRaster) -exportMethods(is.twdtwTimeSeries) -exportMethods(labels) -exportMethods(layers) -exportMethods(length) -exportMethods(levels) -exportMethods(names) -exportMethods(ncol) -exportMethods(nlayers) -exportMethods(nrow) -exportMethods(plot) -exportMethods(projecttwdtwRaster) -exportMethods(res) -exportMethods(resampleTimeSeries) -exportMethods(shiftDates) -exportMethods(show) -exportMethods(subset) -exportMethods(summary) -exportMethods(twdtwApply) -exportMethods(twdtwAssess) -exportMethods(twdtwClassify) -exportMethods(twdtwCrossValidate) -exportMethods(twdtwMatches) -exportMethods(twdtwRaster) -exportMethods(twdtwTimeSeries) -exportMethods(twdtwXtable) -exportMethods(writeRaster) -import(ggplot2) -import(methods) -import(raster) -import(rgdal) -import(zoo) -importFrom(RColorBrewer,brewer.pal) -importFrom(Rdpack,reprompt) -importFrom(caret,createDataPartition) -importFrom(data.table,rbindlist) -importFrom(dtw,asymmetric) -importFrom(dtw,rabinerJuangStepPattern) -importFrom(dtw,symmetric1) -importFrom(dtw,symmetric2) -importFrom(foreach,"%dopar%") -importFrom(foreach,foreach) -importFrom(grDevices,gray.colors) -importFrom(grDevices,terrain.colors) -importFrom(lubridate,"day<-") -importFrom(lubridate,"month<-") -importFrom(lubridate,"year<-") -importFrom(lubridate,day) -importFrom(lubridate,month) -importFrom(lubridate,year) +export(create_pattern) +export(get_dates_from_doy) +export(plot_patterns) +export(shift_dates) +import(stars) +import(twdtw) importFrom(mgcv,gam) importFrom(mgcv,predict.gam) -importFrom(plyr,alply) -importFrom(proxy,dist) -importFrom(proxy,pr_DB) -importFrom(reshape2,melt) -importFrom(scales,date_format) -importFrom(scales,percent) -importFrom(scales,pretty_breaks) -importFrom(sp,CRS) -importFrom(sp,Polygon) -importFrom(sp,Polygons) -importFrom(sp,SpatialPoints) -importFrom(sp,SpatialPointsDataFrame) -importFrom(sp,SpatialPolygons) -importFrom(sp,bbox) -importFrom(sp,coordinates) -importFrom(sp,over) -importFrom(sp,spTransform) -importFrom(stats,ave) -importFrom(stats,na.omit) -importFrom(stats,qnorm) -importFrom(stats,sd) -importFrom(stats,window) -importFrom(stats,xtabs) -importFrom(utils,flush.console) -importFrom(utils,globalVariables) -importFrom(utils,packageDescription) -importFrom(xtable,print.xtable) -importFrom(xtable,xtable) -useDynLib(dtwSat, .registration = TRUE) diff --git a/NEWS.md b/NEWS.md index 9c7a3f0..46b8eed 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # dtwSat v1.0.0 -* Major release: drops dependencies on rgdal and rgeos +* Major release: drops dependencies and simplifies package # dtwSat v0.2.8 diff --git a/R/class-crossValidation.R b/R/class-crossValidation.R deleted file mode 100644 index 297b73a..0000000 --- a/R/class-crossValidation.R +++ /dev/null @@ -1,115 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-11-27 # -# # -############################################################### - - -#' @title class "twdtwCrossValidation" -#' @name twdtwCrossValidation-class -#' @aliases twdtwCrossValidation -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description This class stores the results of the cross-validation. -#' -#' @param object an object of class twdtwCrossValidation. -#' -#' @param conf.int specifies the confidence level (0-1) for interval estimation of the -#' population mean. For more details see \code{\link[ggplot2]{mean_cl_boot}}. -#' -#' @param ... Other arguments. Not used. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{createPatterns}}, and -#' \code{\link[dtwSat]{twdtwApply}}. -#' -#' @section Slots : -#' \describe{ -#' \item{\code{partitions}:}{A list with the indices of time series used for training.} -#' \item{\code{accuracy}:}{A list with the accuracy and other TWDTW information for each -#' data partitions.} -#' } -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' \dontrun{ -#' # Data folder -#' data_folder = system.file("lucc_MT/data", package = "dtwSat") -#' -#' # Read dates -#' dates = scan(paste(data_folder,"timeline", sep = "/"), what = "dates") -#' -#' # Read raster time series -#' evi = brick(paste(data_folder,"evi.tif", sep = "/")) -#' raster_timeseries = twdtwRaster(evi, timeline = dates) -#' -#' # Read field samples -#' field_samples = read.csv(paste(data_folder,"samples.csv", sep = "/")) -#' table(field_samples[["label"]]) -#' -#' # Read field samples projection -#' proj_str = scan(paste(data_folder,"samples_projection", sep = "/"), -#' what = "character") -#' -#' # Get sample time series from raster time series -#' field_samples_ts = getTimeSeries(raster_timeseries, -#' y = field_samples, proj4string = proj_str) -#' field_samples_ts -#' -#' # Run cross validation -#' set.seed(1) -#' # Define TWDTW weight function -#' log_fun = logisticWeight(alpha=-0.1, beta=50) -#' cross_validation = twdtwCrossValidate(field_samples_ts, times=3, p=0.1, -#' freq = 8, formula = y ~ s(x, bs="cc"), weight.fun = log_fun) -#' cross_validation -#' -#' summary(cross_validation) -#' -#' plot(cross_validation) -#' -#' } -NULL -setClass( - Class = "twdtwCrossValidation", - slots = c(partitions = "list", accuracy = "list"), - validity = function(object){ - if(!is(object@partitions, "list")){ - stop("[twdtwCrossValidation: validation] Invalid partitions, class different from list.") - }else{} - if(!is(object@accuracy, "list")){ - stop("[twdtwCrossValidation: validation] Invalid accuracy, class different from list.") - }else{} - return(TRUE) - } -) - -setMethod("initialize", - signature = "twdtwCrossValidation", - definition = - function(.Object, partitions, accuracy){ - .Object@partitions = list(Resample1=NULL) - .Object@accuracy = list(OverallAccuracy=NULL, UsersAccuracy=NULL, ProducersAccuracy=NULL, - ErrorMatrix=table(NULL), data=data.frame(NULL)) - if(!missing(partitions)) - .Object@partitions = partitions - if(!missing(accuracy)) - .Object@accuracy = accuracy - validObject(.Object) - return(.Object) - } -) - diff --git a/R/class-twdtwAssessment.R b/R/class-twdtwAssessment.R deleted file mode 100644 index c935454..0000000 --- a/R/class-twdtwAssessment.R +++ /dev/null @@ -1,95 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2017-01-18 # -# # -############################################################### - -#' @include class-twdtwRaster.R -#' @title class "twdtwAssessment" -#' @name twdtwAssessment-class -#' @aliases twdtwAssessment -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description This class stores the map assessment metrics. -#' -#' @param object an object of class twdtwAssessment. -#' -#' @seealso \code{\link[dtwSat]{twdtwClassify}}, -#' \code{\link[dtwSat]{twdtwAssess}}, and -#' \code{\link[dtwSat]{twdtwXtable}}. -#' -#' @section Slots : -#' \describe{ -#' \item{\code{accuracySummary}:}{Overall Accuracy, User's Accuracy, Producer's Accuracy, -#' Error Matrix (confusion matrix), and Estimated Area, considering all time periods.} -#' \item{\code{accuracyByPeriod}:}{Overall Accuracy, User's Accuracy, Producer's Accuracy, -#' Error Matrix (confusion matrix), and Estimated Area, for each time periods independently -#' from each other.} -#' \item{\code{data}:}{A \code{\link[sp]{SpatialPointsDataFrame}} with sample ID, period, -#' date from, date to, reference labels, predicted labels, and TWDTW distance.} -#' \item{\code{map}:}{A \code{\link[dtwSat]{twdtwRaster}} with the raster maps.} -#' } -#' -#' @details -#' If the twdtwRaster is unprojected (longitude/latitude) the estimated area is the sum of the approximate -#' surface area in km2 of each cell (pixel). If the twdtwRaster is projected the estimated area is calculated -#' using the the pixel resolution in the map unit. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -NULL -setClass( - Class = "twdtwAssessment", - slots = c(accuracySummary = "list", accuracyByPeriod = "list", data = "SpatialPointsDataFrame", map = "twdtwRaster"), - validity = function(object){ - if(!is(object@accuracySummary, "list")){ - stop("[twdtwAssessment: validation] Invalid partitions, class different from list.") - }else{} - if(!is(object@accuracyByPeriod, "list")){ - stop("[twdtwAssessment: validation] Invalid accuracy, class different from list.") - }else{} - if(!is(object@data, "SpatialPointsDataFrame")){ - stop("[twdtwAssessment: validation] Invalid accuracy, class different from SpatialPointsDataFrame.") - }else{} - if(!is(object@map, "twdtwRaster")){ - stop("[twdtwAssessment: validation] Invalid accuracy, class different from twdtwRaster.") - }else{} - return(TRUE) - } -) - -setMethod("initialize", - signature = "twdtwAssessment", - definition = - function(.Object, accuracySummary, accuracyByPeriod, data, map){ - .Object@accuracySummary = list(OverallAccuracy=NULL, UsersAccuracy=NULL, ProducersAccuracy=NULL, ErrorMatrix=table(NULL)) - .Object@accuracyByPeriod = list(list(OverallAccuracy=NULL, UsersAccuracy=NULL, ProducersAccuracy=NULL, - ErrorMatrix=table(NULL))) - .Object@data = SpatialPointsDataFrame(coords = cbind(0,0), - data = data.frame(Sample.id=0, Period=NA, from=NA, to=NA, Distance=NA, Predicted=NA, Reference=NA, Distance=NA)) - .Object@map = new("twdtwRaster") - if(!missing(accuracySummary)) - .Object@accuracySummary = accuracySummary - if(!missing(accuracyByPeriod)) - .Object@accuracyByPeriod = accuracyByPeriod - if(!missing(data)) - .Object@data = data - if(!missing(map)) - .Object@map = map - validObject(.Object) - return(.Object) - } -) - - diff --git a/R/class-twdtwMatches.R b/R/class-twdtwMatches.R deleted file mode 100644 index 26b7861..0000000 --- a/R/class-twdtwMatches.R +++ /dev/null @@ -1,148 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2015-09-01 # -# # -############################################################### - - -#' @title class "twdtwMatches" -#' @name twdtwMatches-class -#' @aliases twdtwMatches -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Class for Time-Weighted Dynamic Time Warping results. -#' -#' @param labels a vector with labels of the time series. -#' @param x an object of class twdtwMatches. -#' @param object an object of class twdtwMatches. -#' @param timeseries a \code{\link[dtwSat]{twdtwTimeSeries}} object. -#' @param patterns a \code{\link[dtwSat]{twdtwTimeSeries}} object. -#' @param alignments an object of class list with the TWDTW results with -#' the same length as \code{timeseries} or a list of twdtwMatches. -#' -#' @include class-twdtwTimeSeries.R -#' -#' @section Slots : -#' \describe{ -#' \item{\code{timeseries}:}{An object of class \code{\link[dtwSat]{twdtwTimeSeries-class}} with the satellite time series.} -#' \item{\code{pattern}:}{An object of class \code{\link[dtwSat]{twdtwTimeSeries-class}} with the temporal patterns.} -#' \item{\code{alignments}:}{A \code{\link[base]{list}} of TWDTW results with the same length as -#' the \code{timeseries}. Each element in this list has the following results for each temporal pattern -#' in \code{patterns}: -#' \cr\code{from}: a vector with the starting dates of each match in the format "YYYY-MM-DD", -#' \cr\code{to}: a vector with the ending dates of each match in the format "YYYY-MM-DD", -#' \cr\code{distance}: a vector with TWDTW dissimilarity measure, and -#' \cr\code{K}: the number of matches of the pattern. -#' } -#' \item{This list might have additional elements:}{ if \code{keep=TRUE} in the \code{twdtwApply} call -#' the list is extended to include internal structures used during the TWDTW computation: -#' \cr\code{costMatrix}: cumulative cost matrix, -#' \cr\code{directionMatrix}: directions of steps that would be taken from each element of matrix, -#' \cr\code{startingMatrix}: the starting points of each element of the matrix, -#' \cr\code{stepPattern}: \code{\link[dtw]{stepPattern}} used for the -#' computation, see package \code{\link[dtw]{dtw}}, -#' \cr\code{N}: the length of the \code{pattern}, -#' \cr\code{M}: the length of the time series \code{timeseries}, -#' \cr\code{timeWeight}: time weight matrix, -#' \cr\code{localMatrix}: local cost matrix, -#' \cr\code{matching}: A list whose elements have the matching points for -#' each match between pattern the time series, such that: -#' \cr--\code{index1}: a vector with matching points of the pattern, and -#' \cr--\code{index2}: a vector with matching points of the time series. -#' } -#' } -#' -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{twdtwTimeSeries-class}}, and -#' \code{\link[dtwSat]{twdtwRaster-class}} -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' ts = twdtwTimeSeries(timeseries=MOD13Q1.ts.list) -#' patterns = twdtwTimeSeries(timeseries=MOD13Q1.patterns.list) -#' matches = twdtwApply(x = ts, y = patterns, keep=TRUE, legacy=TRUE) -#' class(matches) -#' length(matches) -#' matches -NULL -setClass( - Class = "twdtwMatches", - slots = c(timeseries="twdtwTimeSeries", - patterns = "twdtwTimeSeries", - alignments = "list"), - validity = function(object){ - if(!is(object@alignments, "list")){ - stop("[twdtwMatches: validation] Invalid alignments object, class different from list.") - }else{} - if(!is(object@timeseries, "twdtwTimeSeries")){ - stop("[twdtwMatches: validation] Invalid timeseries object, class different from twdtwTimeSeries.") - }else{} - if(!is(object@patterns, "twdtwTimeSeries")){ - stop("[twdtwMatches: validation] Invalid patterns object, class different from list of twdtwTimeSeries.") - }else{} - return(TRUE) - } -) - -setMethod("initialize", - signature = "twdtwMatches", - definition = - function(.Object, timeseries, patterns, alignments){ - .Object@timeseries = new("twdtwTimeSeries") - .Object@patterns = new("twdtwTimeSeries") - .Object@alignments = list() - if(!missing(alignments)) - .Object@alignments = alignments - if(!missing(timeseries)) - .Object@timeseries = timeseries - if(!missing(patterns)) - .Object@patterns = patterns - validObject(.Object) - return(.Object) - } -) - -setGeneric(name = "twdtwMatches", - def = function(timeseries=NULL, patterns=NULL, alignments=NULL) standardGeneric("twdtwMatches") -) - -#' @inheritParams twdtwMatches-class -#' @aliases twdtwMatches-create -#' @describeIn twdtwMatches Create object of class twdtwMatches. -#' -#' @examples -#' # Creating objects of class twdtwMatches -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' mat = twdtwApply(ts, patt, weight.fun = logisticWeight(-0.1, 100), -#' keep=TRUE, legacy=TRUE) -#' mat = twdtwMatches(ts, patterns=patt, alignments=mat) -#' mat -#' -#' @export -setMethod(f = "twdtwMatches", - definition = function(timeseries, patterns, alignments){ - aligs = alignments - if(is(alignments, "twdtwMatches")) alignments = list(alignments) - if(all(sapply(alignments, is.twdtwMatches))) { - aligs = alignments - if(is(alignments, "list")) aligs = do.call("c", lapply(alignments, function(x) x@alignments)) - if(is.null(timeseries)) timeseries = do.call("twdtwTimeSeries", lapply(alignments, function(x) subset(x@timeseries))) - if(is.null(patterns)) patterns=alignments[[1]]@patterns - } - new("twdtwMatches", timeseries=timeseries, patterns=patterns, alignments=aligs) - }) diff --git a/R/class-twdtwRaster.R b/R/class-twdtwRaster.R deleted file mode 100644 index 8fd9bd8..0000000 --- a/R/class-twdtwRaster.R +++ /dev/null @@ -1,256 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-02-18 # -# # -############################################################### - - -#' @title class "twdtwRaster" -#' @name twdtwRaster-class -#' @aliases twdtwRaster -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Class for set of satellite time series. -#' -#' @param ... objects of class \code{\link[raster]{RasterBrick-class}} or -#' \code{\link[raster]{RasterStack-class}}. -#' -#' @param timeline a vector with the dates of the satellite images -#' in the format of "YYYY-MM-DD". -#' -#' @param layers a vector with the names of the \code{Raster*} objects -#' passed to "\code{...}". If not provided the layers are set to the -#' names of objects in "\code{...}". -#' -#' @param labels a vector of class \code{\link[base]{character}} with -#' labels of the values in the Raster* objects. This is -#' useful for categorical Raster* values of land use classes. -#' -#' @param levels a vector of class \code{\link[base]{numeric}} with -#' levels of the values in the Raster* objects. This is -#' useful for categorical Raster* values of land use classes. -#' -#' @param doy A \code{\link[raster]{RasterBrick-class}} or -#' \code{\link[raster]{RasterStack-class}} with a sequence of days of the year for each pixel. -#' \code{doy} must have the same spatial and temporal extents as the Raster* objects passed to \code{...}. -#' If \code{doy} is not provided then at least one Raster* object must be passed through \code{...}. -#' -#' @param filepath A character. The path to save the raster time series. If provided the -#' function saves a raster file for each Raster* object in the list, \emph{i.e} one file -#' for each time series. This way the function retrieves a list of -#' \code{\link[raster]{RasterBrick-class}}. It is useful when the time series are -#' originally stored in separated files. See details. -#' -#' @param object an object of class twdtwRaster. -#' -#' @param x an object of class twdtwRaster. -#' -#' @details The performance of the functions \code{\link[dtwSat]{twdtwApply}} and -#' \code{\link[dtwSat]{getTimeSeries}} is improved if the Raster* objects are connected -#' to files with the whole time series for each attribute. -#' -#' @section Slots : -#' \describe{ -#' \item{\code{timeseries}:}{A list of multi-layer Raster* objects -#' with the satellite image time series.} -#' \item{\code{timeline}:}{A vector of class \code{\link[base]{date}} -#' with dates of the satellite images in \code{timeseries}.} -#' \item{\code{layers}:}{A vector of class \code{\link[base]{character}} -#' with the names of the Raster* objects.} -#' \item{\code{labels}:}{A vector of class \code{\link[base]{factor}} -#' with levels and labels of the values in the Raster* objects. This -#' is useful for categorical Raster* values of land use classes.} -#' } -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{getTimeSeries}}, -#' \code{\link[dtwSat]{twdtwMatches-class}}, and -#' \code{\link[dtwSat]{twdtwTimeSeries-class}} -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' # Creating a new object of class twdtwTimeSeries -#' evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) -#' timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") -#' rts = new("twdtwRaster", timeseries = evi, timeline = timeline) -#' -NULL -setClass( - Class = "twdtwRaster", - slots = c(timeseries = "list", timeline="Date", layers = "character", labels = "character", levels="numeric"), - validity = function(object){ - if(!is(object@timeline, "Date")){ - stop("[twdtwTimeSeries: validation] Invalid timeline object, class different from Date.") - }else{} - if(any(!(sapply(object@timeseries, is, "RasterBrick") | sapply(object@timeseries, is, "RasterStack") | sapply(object@timeseries, is, "RasterLayer")))){ - stop("[twdtwRaster: validation] Invalid timeseries object, class different from Raster*.") - }else{} - if(!is(object@layers, "character")){ - stop("[twdtwTimeSeries: validation] Invalid layers object, class different from character.") - }else{} - if( length(object@layers)>0 & length(object@layers)!=length(object@timeseries) ){ - stop("[twdtwTimeSeries: validation] Invalid length, layers and timeseries do not have the same length.") - }else{} - if(!is(object@labels, "character")){ - stop("[twdtwTimeSeries: validation] Invalid labels object, class different from character.") - }else{} - if(!is(object@levels, "numeric")){ - stop("[twdtwTimeSeries: validation] Invalid levels object, class different from numeric.") - }else{} - if( length(object@labels) != length(object@levels) ){ - stop("[twdtwTimeSeries: validation] Invalid length, labels and levels do not have the same length.") - }else{} - lapply(object@timeseries, FUN=compareRaster, object@timeseries[[1]], extent=TRUE, rowcol=TRUE, - crs=TRUE, res=TRUE, orig=TRUE, rotation=TRUE, stopiffalse=TRUE) - return(TRUE) - } -) - -setMethod("initialize", - signature = "twdtwRaster", - definition = - function(.Object, timeseries, timeline, doy, layers, labels, levels){ - - .Object@timeseries = list(Layer0=brick()) - .Object@timeline = as.Date(0) - .Object@labels = as.character() - .Object@levels = numeric() - if(!missing(timeseries)){ - if(is(timeseries, "RasterBrick") | is(timeseries, "RasterStack") | is(timeseries, "RasterLayer") ) - timeseries = list(timeseries) - .Object@timeseries = timeseries - if(is.null(names(.Object@timeseries))) - names(.Object@timeseries) = paste0("Layer", seq_along(.Object@timeseries)-1) - } else { - if(!missing(layers)) - names(.Object@timeseries) = layers - } - if(!missing(doy)) - .Object@timeseries = c(doy = doy, .Object@timeseries) - .Object@layers = names(.Object@timeseries) - if(!missing(labels)) - .Object@labels = as.character(labels) - if(missing(levels)) - levels = seq_along(.Object@labels) - .Object@levels = as.numeric(levels) - if(!missing(timeline)) - .Object@timeline = as.Date(timeline) - validObject(.Object) - names(.Object@timeline) = paste0("date.", format(.Object@timeline,"%Y.%m.%d")) - .Object@timeseries = lapply(.Object@timeseries, function(x) { names(x)=names(.Object@timeline); x}) - return(.Object) - } -) - - -setGeneric(name = "twdtwRaster", - def = function(..., timeline, doy=NULL, layers=NULL, labels=NULL, levels=NULL, filepath=NULL) - standardGeneric("twdtwRaster") -) - - -#' @inheritParams twdtwRaster -#' @aliases twdtwRaster-create -#' @describeIn twdtwRaster Create object of class twdtwRaster. -#' -#' @examples -#' \dontrun{ -#' # Creating objects of class twdtwRaster -#' evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) -#' timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") -#' ts_evi = twdtwRaster(evi, timeline=timeline) -#' -#' ndvi = brick(system.file("lucc_MT/data/ndvi.tif", package="dtwSat")) -#' blue = brick(system.file("lucc_MT/data/blue.tif", package="dtwSat")) -#' red = brick(system.file("lucc_MT/data/red.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")) -#' rts = twdtwRaster(doy, evi, ndvi, blue, red, nir, mir, timeline = timeline) -#' } -#' @export -setMethod(f = "twdtwRaster", - definition = function(..., timeline, doy, layers, labels, levels){ - arg_names = names(list(...)) - not_named = setdiff(as.character(match.call(expand.dots=TRUE)), as.character(match.call(expand.dots=FALSE))) - if(is.null(arg_names)){ - arg_names = not_named - } else { - arg_names[arg_names==""] = not_named[arg_names==""] - } - x = list(...) - names(x) = c(arg_names) - if(missing(doy)){ - if(any(arg_names %in% "doy")){ - doy = x[[which(arg_names %in% "doy")]] - x = x[which(!(arg_names %in% "doy"))] - } - } - I = which(sapply(x, is, "RasterBrick") | sapply(x, is, "RasterStack") | sapply(x, is, "RasterLayer")) - if(length(I) < 1) - stop("There are no Raster* objects in the list of arguments") - # Split arguments - timeseries = x[I] - dotargs = x[-I] - creat.twdtwRaster(timeseries=timeseries, timeline=as.Date(timeline), doy=doy, - layers=layers, labels=labels, levels=levels, dotargs=dotargs) - }) - - -creat.twdtwRaster = function(timeseries, timeline, doy, layers, labels, levels, dotargs){ - - # Check timeline - nl = sapply(c(timeseries), nlayers) - if(!is.null(doy)) - nl = c(nlayers(doy), nl) - if(any(nl!=length(timeline))) - stop("Raster objects do not have the same length as the timeline") - - res = timeseries - # Save a single file (complete time series) for each raster attribute - # if (filepath != "") { - # dir.create(filepath, showWarnings = FALSE) - # write(as.character(timeline), file = paste(filepath, "timeline", sep="/")) - # aux = res - # if(!is.null(doy)) - # aux = c(doy=doy, res) - # res_brick = lapply(names(aux), function(i){ - # filename = paste(filepath, i, sep="/") - # dotargs = c(x = aux[[i]], filename = filename, dotargs) - # r = do.call(writeRaster, dotargs) - # r - # }) - # names(res_brick) = names(aux) - # doy = NULL - # res = res_brick - # if(any(names(res)=="doy")){ - # res = res_brick[-1] - # doy = res_brick[[1]] - # } - # } - if(is.null(layers)) layers = names(res) - if(is.null(doy)) - return(new("twdtwRaster", timeseries = res, timeline = timeline, layers = layers, labels = labels, levels=levels)) - new("twdtwRaster", timeseries = res, timeline = timeline, doy=doy, layers = layers, labels = labels, levels=levels) -} - -.creat.doy = function(x, timeline){ - array_data = rep(as.numeric(format(as.Date(timeline), "%j")), each=ncell(x)) - e = extent(x) - brick(array(array_data, dim = dim(x)), xmn=e[1], xmx=e[2], ymn=e[3], ymx=e[4], crs = projection(x)) -} - - diff --git a/R/class-twdtwTimeSeries.R b/R/class-twdtwTimeSeries.R deleted file mode 100644 index 1b5a8fb..0000000 --- a/R/class-twdtwTimeSeries.R +++ /dev/null @@ -1,155 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-02-18 # -# # -############################################################### - -#' @title class "twdtwTimeSeries" -#' @name twdtwTimeSeries-class -#' @aliases twdtwTimeSeries -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Class for setting irregular time series. -#' -#' @param ... \code{\link[dtwSat]{twdtwTimeSeries}} objects, -#' \code{\link[zoo]{zoo}} objects or a list of \code{\link[zoo]{zoo}} objects. -#' @param labels a vector with labels of the time series. -#' @param object an object of class twdtwTimeSeries. -#' @param x an object of class twdtwTimeSeries. -#' -#' @section Slots : -#' \describe{ -#' \item{\code{timeseries}:}{A list of \code{\link[zoo]{zoo}} objects.} -#' \item{\code{labels}:}{A vector of class \code{\link[base]{factor}} with time series labels.} -#' } -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{twdtwRaster-class}}, -#' \code{\link[dtwSat]{getTimeSeries}}, and -#' \code{\link[dtwSat]{twdtwApply}} -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' # Creating a new object of class twdtwTimeSeries -#' ptt = new("twdtwTimeSeries", timeseries = MOD13Q1.patterns.list, -#' labels = names(MOD13Q1.patterns.list)) -#' class(ptt) -#' labels(ptt) -#' levels(ptt) -#' length(ptt) -#' nrow(ptt) -#' ncol(ptt) -#' dim(ptt) -NULL -setClass( - Class = "twdtwTimeSeries", - slots = c(timeseries = "list", labels = "factor"), - validity = function(object){ - if(!is(object@timeseries, "list")){ - stop("[twdtwTimeSeries: validation] Invalid timeseries object, class different from list.") - }else{} - if(any(length(object@timeseries)>1 & !sapply(object@timeseries, is.zoo))){ - stop("[twdtwTimeSeries: validation] Invalid timeseries object, class different from list of zoo objects.") - }else{} - if(!is(object@labels, "factor")){ - stop("[twdtwTimeSeries: validation] Invalid labels object, class different from character.") - }else{} - if( length(object@labels)!=0 & length(object@labels)!=length(object@timeseries) ){ - stop("[twdtwTimeSeries: validation] Invalid labels, labels and timeseries do not have the same length.") - }else{} - return(TRUE) - } -) - -setMethod("initialize", - signature = "twdtwTimeSeries", - definition = - function(.Object, timeseries, labels){ - .Object@timeseries = list() - .Object@labels = factor(NULL) - if(!missing(timeseries)){ - if(is(timeseries, "zoo")) timeseries = list(timeseries) - .Object@timeseries = timeseries - .Object@labels = factor( paste0("ts",seq_along(timeseries)) ) - if(!is.null(names(timeseries))) .Object@labels = factor(names(timeseries)) - } - if(!missing(labels)){ - .Object@labels = factor(labels) - names(.Object@timeseries) = as.character(labels) - } - validObject(.Object) - return(.Object) - } -) - -setGeneric(name = "twdtwTimeSeries", - def = function(...) standardGeneric("twdtwTimeSeries") -) - -#' @inheritParams twdtwTimeSeries-class -#' @aliases twdtwTimeSeries-create -#' -#' @describeIn twdtwTimeSeries Create object of class twdtwTimeSeries. -#' -#' @examples -#' # Creating objects of class twdtwTimeSeries from zoo objects -#' ts = twdtwTimeSeries(MOD13Q1.ts) -#' ts -#' -#' # Creating objects of class twdtwTimeSeries from list of zoo objects -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' patt -#' -#' # Joining objects of class twdtwTimeSeries -#' tsA = twdtwTimeSeries(MOD13Q1.ts.list[[1]], labels = "A") -#' tsB = twdtwTimeSeries(B = MOD13Q1.ts.list[[2]]) -#' ts = twdtwTimeSeries(tsA, tsB, C=MOD13Q1.ts) -#' ts -#' -#' @export -setMethod(f = "twdtwTimeSeries", - definition = function(..., labels=NULL){ - timeseries = list(...) - joint_timeseries = list() - timeseries_class = sapply(timeseries, class) - zoo_obj = NULL - list_obj = NULL - twdtw_obj = NULL - check_class = c("zoo", "list", "twdtwTimeSeries") %in% timeseries_class - if(check_class[1]){ - zoo_obj = timeseries[which(timeseries_class=="zoo")] - names(zoo_obj) = names(timeseries)[which(timeseries_class=="zoo")] - if(is.null(names(zoo_obj))) names(zoo_obj) = paste0("ts",seq_along(zoo_obj)) - joint_timeseries = c(joint_timeseries, zoo_obj) - } else {} - if(check_class[2]){ - list_obj = c(do.call("c", timeseries[which(timeseries_class=="list")])) - if(is.null(names(list_obj))) names(list_obj) = paste0("ts", seq_along(list_obj)) - joint_timeseries = c(joint_timeseries, list_obj) - } else {} - if(check_class[3]){ - twdtw_obj = do.call("c", lapply(timeseries[which(timeseries_class=="twdtwTimeSeries")], getTimeSeries)) - names(twdtw_obj) = as.character(unlist(lapply(timeseries[which(timeseries_class=="twdtwTimeSeries")], labels))) - joint_timeseries = c(joint_timeseries, twdtw_obj) - } else {} - if(is.null(labels)) labels = names(joint_timeseries) - new("twdtwTimeSeries", timeseries = joint_timeseries, labels = labels) - }) - - - - - diff --git a/R/createPatterns.R b/R/createPatterns.R deleted file mode 100644 index f737743..0000000 --- a/R/createPatterns.R +++ /dev/null @@ -1,173 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-02-18 # -# # -############################################################### - - -#' @title Create patterns -#' @name createPatterns -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Create temporal patterns from objects of class twdtwTimeSeries. -#' -#' @param x an object of class \code{\link[dtwSat]{twdtwTimeSeries}}. -#' -#' @param from A character or \code{\link[base]{Dates}} object in the format -#' "yyyy-mm-dd". If not provided it is equal to the smallest date of the -#' first element in x. See details. -#' -#' @param to A \code{\link[base]{character}} or \code{\link[base]{Dates}} -#' object in the format "yyyy-mm-dd". If not provided it is equal to the -#' greatest date of the first element in x. See details. -#' -#' @param attr A vector character or numeric. The attributes in \code{x} to be used. -#' If not declared the function uses all attributes. -#' -#' @param freq An integer. The sampling frequency of the output patterns. -#' -#' @param split A logical. If TRUE the samples are split by label. If FALSE -#' all samples are set to the same label. -#' -#' @param formula A formula. Argument to pass to \code{\link[mgcv]{gam}}. -#' -#' @param ... other arguments to pass to the function \code{\link[mgcv]{gam}} in the -#' package \pkg{mgcv}. -#' -#' @return an object of class \code{\link[dtwSat]{twdtwTimeSeries}} -#' -#' -#' @details The hidden assumption is that the temporal pattern is a cycle the repeats itself -#' within a given time interval. Therefore, all time series samples in \code{x} are aligned -#' with each other, keeping their respective sequence of days of the year. The function fits a -#' Generalized Additive Model (GAM) to the aligned set of samples. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{twdtwTimeSeries-class}}, -#' \code{\link[dtwSat]{getTimeSeries}}, and -#' \code{\link[dtwSat]{twdtwApply}} -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @export -setGeneric("createPatterns", function(x, from=NULL, to=NULL, freq=1, attr=NULL, split=TRUE, formula, ...) standardGeneric("createPatterns")) - -#' @rdname createPatterns -#' @aliases createPatterns-twdtwMatches -#' @examples -#' # Creating patterns from objects of class twdtwTimeSeries -#' evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) -#' ndvi = brick(system.file("lucc_MT/data/ndvi.tif", package="dtwSat")) -#' timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") -#' rts = twdtwRaster(evi, ndvi, timeline=timeline) -#' -#' # Read field samples -#' \dontrun{ -#' field_samples = read.csv(system.file("lucc_MT/data/samples.csv", package="dtwSat")) -#' prj_string = scan(system.file("lucc_MT/data/samples_projection", package="dtwSat"), -#' what = "character") -#' -#' # Extract time series -#' ts = getTimeSeries(rts, y = field_samples, proj4string = prj_string) -#' -#' # Create temporal patterns -#' patt = createPatterns(x=ts, from="2005-09-01", to="2006-09-01", freq=8, formula = y~s(x)) -#' -#' # Plot patterns -#' autoplot(patt[[1]], facets = NULL) + xlab("Time") + ylab("Value") -#' -#' } -#' @export -setMethod("createPatterns", "twdtwTimeSeries", - function(x, from, to, freq, attr, split, formula, ...) { - - # Get formula variables - if(!is(formula, "formula")) - stop("missing formula") - vars = all.vars(formula) - - # Split samples according to their labels - if(split) { - levels = as.character(levels(x)) - labels = as.character(labels(x)) - names(levels) = levels - x = lapply(levels, function(l) x[labels==l] ) - } else { - levels = as.character(levels(x)[1]) - labels = rep(levels, length(x)) - names(levels) = levels - x@labels = factor(labels) - x = list(x) - names(x) = levels - } - - # Create patterns - res = lapply(x, FUN = .createPattern, from=from, to=to, freq=freq, attr=attr, formula=formula, ...) - twdtwTimeSeries(res) -}) - - -.createPattern = function(x, from, to, freq, attr, formula, ...){ - - # Pattern period - if( is.null(from) | is.null(to) ){ - from = as.Date(min(index(x[[1]]))) - to = as.Date(max(index(x[[1]]))) - } - - from = as.Date(from) - to = as.Date(to) - - # Get formula variables - vars = all.vars(formula) - - # Shift dates to match the same period - df = do.call("rbind", lapply(as.list(x), function(x){ - res = shiftDates(x, year=as.numeric(format(to, "%Y"))) - res = window(res, start = from, end = to) - res = data.frame(time=index(res), res) - names(res) = c("time", names(x)) - res - })) - names(df)[1] = vars[2] - - dates = as.Date(df[[vars[2]]]) - pred_time = seq(from, to, freq) - - fun = function(y, ...){ - df = data.frame(y, as.numeric(dates)) - names(df) = vars - fit = gam(data = df, formula = formula, ...) - time = data.frame(as.numeric(pred_time)) - names(time) = vars[2] - predict.gam(fit, newdata = time) - } - - if(is.null(attr)) attr = names(df)[-which(names(df) %in% vars[2])] - - res = sapply(as.list(df[attr]), FUN=fun, ...) - zoo(data.frame(res), as.Date(pred_time)) -} - - - - - - - - - - - diff --git a/R/create_patterns.R b/R/create_patterns.R new file mode 100644 index 0000000..24d5dca --- /dev/null +++ b/R/create_patterns.R @@ -0,0 +1,100 @@ +#' @title Create patterns +#' @author Victor Maus, \email{vwmaus1@@gmail.com} +#' +#' @description Create temporal patterns from objects of class twdtwTimeSeries. +#' +#' @param x an object of class \code{\link[dtwSat]{twdtwTimeSeries}}. +#' +#' @param from A character or \code{\link[base]{Dates}} object in the format +#' "yyyy-mm-dd". If not provided it is equal to the smallest date of the +#' first element in x. See details. +#' +#' @param to A \code{\link[base]{character}} or \code{\link[base]{Dates}} +#' object in the format "yyyy-mm-dd". If not provided it is equal to the +#' greatest date of the first element in x. See details. +#' +#' @param attr A vector character or numeric. The attributes in \code{x} to be used. +#' If not declared the function uses all attributes. +#' +#' @param freq An integer. The sampling frequency of the output patterns. +#' +#' @param split A logical. If TRUE the samples are split by label. If FALSE +#' all samples are set to the same label. +#' +#' @param formula A formula. Argument to pass to \code{\link[mgcv]{gam}}. +#' +#' @param ... other arguments to pass to the function \code{\link[mgcv]{gam}} in the +#' package \pkg{mgcv}. +#' +#' @return an object of class \code{\link[dtwSat]{twdtwTimeSeries}} +#' +#' +#' @details The hidden assumption is that the temporal pattern is a cycle the repeats itself +#' within a given time interval. Therefore, all time series samples in \code{x} are aligned +#' with each other, keeping their respective sequence of days of the year. The function fits a +#' Generalized Additive Model (GAM) to the aligned set of samples. +#' +#' @seealso +#' \code{\link[dtwSat]{twdtwMatches-class}}, +#' \code{\link[dtwSat]{twdtwTimeSeries-class}}, +#' \code{\link[dtwSat]{getTimeSeries}}, and +#' \code{\link[dtwSat]{twdtwApply}} +#' +#' @references +#' \insertRef{Maus:2019}{dtwSat} +#' +#' \insertRef{Maus:2016}{dtwSat} +#' +#' @export +create_pattern = function(x, from, to, freq, attr, formula, ...){ + + # Pattern period + if( is.null(from) | is.null(to) ){ + from = as.Date(min(index(x[[1]]))) + to = as.Date(max(index(x[[1]]))) + } + + from = as.Date(from) + to = as.Date(to) + + # Get formula variables + vars = all.vars(formula) + + # Shift dates to match the same period + df = do.call("rbind", lapply(as.list(x), function(x){ + res = shiftDates(x, year=as.numeric(format(to, "%Y"))) + res = window(res, start = from, end = to) + res = data.frame(time=index(res), res) + names(res) = c("time", names(x)) + res + })) + names(df)[1] = vars[2] + + dates = as.Date(df[[vars[2]]]) + pred_time = seq(from, to, freq) + + fun = function(y, ...){ + df = data.frame(y, as.numeric(dates)) + names(df) = vars + fit = gam(data = df, formula = formula, ...) + time = data.frame(as.numeric(pred_time)) + names(time) = vars[2] + predict.gam(fit, newdata = time) + } + + if(is.null(attr)) attr = names(df)[-which(names(df) %in% vars[2])] + + res = sapply(as.list(df[attr]), FUN=fun, ...) + zoo(data.frame(res), as.Date(pred_time)) +} + + + + + + + + + + + diff --git a/R/data.R b/R/data.R index af40ca9..629d191 100644 --- a/R/data.R +++ b/R/data.R @@ -1,22 +1,3 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2015-09-01 # -# # -############################################################### - - -############################################################### -#### DATASET DOCUMENTATION - - #' @title Data: patterns time series #' @author Victor Maus, \email{vwmaus1@@gmail.com} #' diff --git a/R/dtw.R b/R/dtw.R deleted file mode 100644 index 6b80399..0000000 --- a/R/dtw.R +++ /dev/null @@ -1,134 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# call Fortran DTW inplementation - 2015-10-27 # -# # -############################################################### - - -# @useDynLib dtwSat computecost -.computecost = function(cm, step.matrix){ - - cm = rbind(0, cm) - n = nrow(cm) - m = ncol(cm) - - if(is.loaded("computecost", PACKAGE = "dtwSat", type = "Fortran")){ - out = .Fortran(computecost, - CM = matrix(as.double(cm), n, m), - DM = matrix(as.integer(0), n, m), - VM = matrix(as.integer(0), n, m), - SM = matrix(as.integer(step.matrix), nrow(step.matrix), ncol(step.matrix)), - N = as.integer(n), - M = as.integer(m), - NS = as.integer(nrow(step.matrix))) - } else { - stop("Fortran computecost lib is not loaded") - } - - res = list() - res$costMatrix = out$CM[-1,] - res$directionMatrix = out$DM[-1,] - res$startingMatrix = out$VM[-1,] - res$stepPattern = step.matrix - res$N = n - 1 - res$M = m - res -} - - -# @useDynLib dtwSat tracepath -.tracepath = function(dm, step.matrix, jmin){ - - n = nrow(dm) - m = ncol(dm) - if(is.null(jmin)) - jmin = m - - if(is.loaded("tracepath", PACKAGE = "dtwSat", type = "Fortran")){ - aloc = length(jmin)*10*n - paths = .Fortran(tracepath, - DM = matrix(as.integer(dm), n, m), - SM = matrix(as.integer(step.matrix), nrow(step.matrix), ncol(step.matrix)), - JMIN = as.vector(as.integer(jmin)), - IND1 = rep(as.integer(0), aloc), - IND2 = rep(as.integer(0), aloc), - POS = as.vector(rep(as.integer(0),length(jmin)+1)), - N = as.integer(n), - M = as.integer(m), - NS = as.integer(nrow(step.matrix)), - NJ = as.integer(length(jmin)), - AL = as.integer(aloc)) - - res = lapply(seq_along(paths$POS)[-1], function(p){ - I = (paths$POS[p]:((paths$POS[p-1])+1)) - # -I[1] removes first row in the matrix which was created artificially - list(index1 = paths$IND1[I][-I[1]], index2 = paths$IND2[I][-tail(I, 1)]) - }) - }else{ - stop("Fortran tracepath lib is not loaded") - } - - res -} - -# @useDynLib dtwSat bestmatches -.bestmatches = function(x, m, n, levels, breaks, overlap, fill=9999){ - if(is.loaded("bestmatches", PACKAGE = "dtwSat", type = "Fortran")){ - if(length(x[[1]]$distance)<1){ - res = list( - XM = matrix(as.integer(c(as.numeric(x[[1]]$from), as.numeric(x[[1]]$to))), ncol = 2), - AM = matrix(as.double(fill), nrow = n, ncol = m), - DM = as.double(x[[1]]$distance), - DP = as.integer(as.numeric(breaks)), - X = as.integer(match(x[[1]]$label, levels)), - IM = matrix(as.integer(0), nrow = n, ncol = 3), - DB = as.double(x[,2]), - A = as.integer(x[[1]]$Alig.N), - K = as.integer(length(x)), - P = as.integer(length(breaks)), - L = as.integer(length(levels)), - OV = as.double(overlap)) - } else { - res = try(.Fortran(bestmatches, - XM = matrix(as.integer(c(as.numeric(x[[1]]$from), as.numeric(x[[1]]$to))), ncol = 2), - AM = matrix(as.double(fill), nrow = n, ncol = m), - DM = as.double(x[[1]]$distance), - DP = as.integer(as.numeric(breaks)), - X = as.integer(match(x[[1]]$label, levels)), - IM = matrix(as.integer(0), nrow = n, ncol = 3), - DB = as.double(rep(0, n)), - A = as.integer(x[[1]]$Alig.N), - K = as.integer(length(x[[1]]$Alig.N)), - P = as.integer(length(breaks)), - L = as.integer(length(levels)), - OV = as.double(overlap))) - } - } else { - stop("Fortran bestmatches lib is not loaded") - } - if(is(res, "try-error")){ - res = list( - XM = matrix(as.integer(c(as.numeric(x[[1]]$from), as.numeric(x[[1]]$to))), ncol = 2), - AM = array(as.double(fill), dim=c(n, m)), - DM = as.double(x[[1]]$distance), - DP = as.integer(as.numeric(breaks)), - X = as.integer(match(x[[1]]$label, levels)), - IM = matrix(as.integer(0), nrow = n, ncol = 3), - DB = as.double(x[,2]), - A = as.integer(x[[1]]$Alig.N), - K = as.integer(length(x)), - P = as.integer(length(breaks)), - L = as.integer(length(levels)), - OV = as.double(overlap) - ) - } - res -} diff --git a/R/dwtSat.R b/R/dwtSat.R deleted file mode 100644 index d352d15..0000000 --- a/R/dwtSat.R +++ /dev/null @@ -1,35 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-07-14 # -# # -############################################################### - -#' @title Time-Weighted Dynamic Time Warping for Satellite Image Time Series -#' @name dtwSat -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Provides an implementation of the Time-Weighted Dynamic Time Warping -#' (TWDTW) method for land use and land cover mapping using satellite image time series -#' \insertCite{Maus:2016,Maus:2019}{dtwSat}. -#' TWDTW is based on the Dynamic Time Warping technique and has achieved high accuracy -#' for land use and land cover classification using satellite data. The method is based -#' on comparing unclassified satellite image time series with a set of known temporal -#' patterns (e.g. phenological cycles associated with the vegetation). Using 'dtwSat' -#' the user can build temporal patterns for land cover types, apply the TWDTW analysis -#' for satellite datasets, visualize the results of the time series analysis, produce -#' land cover maps, and create temporal plots for land cover change analysis. -#' -#' @references -#' \insertAllCited{} -#' -#' @seealso \code{\link[dtwSat]{twdtwApply}} -#' -NULL \ No newline at end of file diff --git a/R/getInternals.R b/R/getInternals.R deleted file mode 100644 index bbc0740..0000000 --- a/R/getInternals.R +++ /dev/null @@ -1,84 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-02-18 # -# # -############################################################### - -setGeneric("getInternals", function(object, timeseries.labels=NULL, patterns.labels=NULL) standardGeneric("getInternals")) -setGeneric("getAlignments", function(object, timeseries.labels=NULL, patterns.labels=NULL) standardGeneric("getAlignments")) -setGeneric("getMatches", function(object, timeseries.labels=NULL, patterns.labels=NULL) standardGeneric("getMatches")) - -#' @title Get elements from twdtwMatches objects -#' @name get -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Get elements from \code{\link[dtwSat]{twdtwMatches-class}} objects. -#' -#' @inheritParams twdtwMatches-class -#' @param timeseries.labels a vector with labels of the time series. -#' @param patterns.labels a vector with labels of the patterns. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, and -#' \code{\link[dtwSat]{twdtwApply}} -#' -#' @examples -#' # Getting patterns from objects of class twdtwMatches -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' mat = twdtwApply(x=ts, y=patt, weight.fun=logisticWeight(-0.1,100), -#' keep=TRUE, legacy = TRUE) -#' getPatterns(mat) -#' getTimeSeries(mat) -#' getAlignments(mat) -#' getMatches(mat) -#' getInternals(mat) -#' -#' @return a list with TWDTW results or an object \code{\link[dtwSat]{twdtwTimeSeries-class}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' -NULL - -#' @aliases getAlignments -#' @inheritParams get -#' @rdname get -#' @export -setMethod("getAlignments", c("twdtwMatches","ANY","ANY"), - function(object, timeseries.labels, patterns.labels) - getAlignments.twdtwMatches(object, timeseries.labels, patterns.labels, attr = c("label", "from", "to", "distance", "K")) ) - -#' @aliases getInternals -#' @inheritParams get -#' @rdname get -#' @export -setMethod("getInternals", c("twdtwMatches","ANY","ANY"), - function(object, timeseries.labels, patterns.labels) - getAlignments.twdtwMatches(object, timeseries.labels, patterns.labels, attr = c("internals")) ) - -#' @aliases getMatches -#' @inheritParams get -#' @rdname get -#' @export -setMethod("getMatches", c("twdtwMatches","ANY","ANY"), - function(object, timeseries.labels, patterns.labels) - getAlignments.twdtwMatches(object, timeseries.labels, patterns.labels, attr = c("matching")) ) - -getAlignments.twdtwMatches = function(object, timeseries.labels, patterns.labels, attr){ - if(is.null(timeseries.labels)) timeseries.labels = labels(object@timeseries) - if(is.null(patterns.labels)) patterns.labels = labels(object@patterns) - res = object[timeseries.labels, patterns.labels, drop=FALSE] - lapply(res, function(x) lapply(x, function(x) x[attr]) ) -} \ No newline at end of file diff --git a/R/getMatchingDates.R b/R/getMatchingDates.R deleted file mode 100644 index a590f48..0000000 --- a/R/getMatchingDates.R +++ /dev/null @@ -1,18 +0,0 @@ -getMatchingDates <- function(x){ - - best_aligs <- x$internals$alignments[x$internals$alignments[,6]==1,,drop=FALSE] - best_aligs <- best_aligs[order(best_aligs[,1]),,drop=FALSE] - - out <- lapply(1:nrow(best_aligs), function(i){ - ts_id <- best_aligs[i,5] - idx <- as.data.frame(.tracepath(dm = x$internals$internals[[ts_id]]$DM, - step.matrix = x$internals$internals[[ts_id]]$SM, - jmin = best_aligs[i,3])) - idx$patternDates <- x$internals$internals[[ts_id]]$patternDates[idx$index1] - idx$tsDates <- x$internals$internals[[ts_id]]$tsDates[idx$index2] - return(idx) - }) - - return(out) - -} diff --git a/R/getTimeSeries.R b/R/getTimeSeries.R deleted file mode 100644 index 2bec0d6..0000000 --- a/R/getTimeSeries.R +++ /dev/null @@ -1,195 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-02-18 # -# # -############################################################### - -setGeneric("getTimeSeries", function(object, ...) standardGeneric("getTimeSeries")) -setGeneric("getPatterns", function(object, ...) standardGeneric("getPatterns")) - -#' @title Get time series from twdtw* objects -#' @name getTimeSeries -#' @aliases getPatterns -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Get time series from objects of class twdtw*. -#' -#' @param object an object of class twdtw*. -#' -#' @param y a \code{\link[base]{data.frame}} whose attributes are: longitude, -#' latitude, the start ''from'' and the end ''to'' of the time interval -#' for each sample. This can also be a \code{\link[sp]{SpatialPointsDataFrame}} -#' whose attributes are the start ''from'' and the end ''to'' of the time interval. -#' If missing ''from'' and/or ''to'', they are set to the time range of the -#' \code{object}. -#' -#' @param id.labels a numeric or character with an column name from \code{y} to -#' be used as sample labels. Optional. -#' -#' @param labels character vector with time series labels. For signature -#' \code{\link[dtwSat]{twdtwRaster}} this argument can be used to set the -#' labels for each sample in \code{y}, or it can be combined with \code{id.labels} -#' to select samples with a specific label. -#' -#' @param proj4string projection string, see \code{\link[sp]{CRS-class}}. Used -#' if \code{y} is a \code{\link[base]{data.frame}}. -#' -#' @return An object of class \code{\link[dtwSat]{twdtwTimeSeries}}. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwRaster-class}}, -#' \code{\link[dtwSat]{twdtwTimeSeries-class}}, and -#' \code{\link[dtwSat]{twdtwMatches-class}} -#' -#' @return a list with TWDTW results or an object \code{\link[dtwSat]{twdtwTimeSeries-class}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' # Getting time series from objects of class twdtwTimeSeries -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' getTimeSeries(ts, 2) -#' # Getting time series from objects of class twdtwTimeSeries -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' mat = twdtwApply(x=ts, y=patt, keep=TRUE, legacy=TRUE) -#' getTimeSeries(mat, 2) -#' -#' ## This example creates a twdtwRaster object and extract time series from it. -#' -#' # Creating objects of class twdtwRaster with evi and ndvi time series -#' evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) -#' ndvi = brick(system.file("lucc_MT/data/ndvi.tif", package="dtwSat")) -#' timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") -#' rts = twdtwRaster(evi, ndvi, timeline=timeline) -#' -#' # Location and time range -#' ts_location = data.frame(longitude = -55.96957, latitude = -12.03864, -#' from = "2007-09-01", to = "2013-09-01") -#' prj_string = "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0" -#' -#' # Extract time series -#' ts = getTimeSeries(rts, y = ts_location, proj4string = prj_string) -#' -#' autoplot(ts[[1]], facets = NULL) + xlab("Time") + ylab("Value") -#' -NULL - - -#' @aliases getTimeSeries-twdtwTimeSeries -#' @inheritParams getTimeSeries -#' @rdname getTimeSeries -#' @export -setMethod("getTimeSeries", "twdtwTimeSeries", - function(object, labels=NULL) getTimeSeries.twdtwTimeSeries(object=object, labels=labels) ) - -#' @aliases getTimeSeries-twdtwMatches -#' @inheritParams getTimeSeries -#' @rdname getTimeSeries -#' @export -setMethod("getTimeSeries", "twdtwMatches", - function(object, labels=NULL) getTimeSeries(object=object@timeseries, labels=labels) ) - - -#' @aliases getPatterns-twdtwMatches -#' @inheritParams getTimeSeries -#' @rdname getTimeSeries -#' @export -setMethod("getPatterns", "twdtwMatches", - function(object, labels=NULL) getTimeSeries(object=object@patterns, labels=labels) ) - -# Get time series from object of class twdtwTimeSeries by labels -getTimeSeries.twdtwTimeSeries = function(object, labels){ - res = subset(object, labels) - res@timeseries -} - -#' @aliases getTimeSeries-twdtwRaster -#' @inheritParams getTimeSeries -#' @rdname getTimeSeries -#' @export -setMethod("getTimeSeries", "twdtwRaster", - function(object, y, labels=NULL, proj4string = NULL, id.labels=NULL){ - - y = .adjustLabelID(y, labels, id.labels) - - if(!"from"%in%names(y)) - y$from = as.Date(index(object)[1]) - if(!"to"%in%names(y)) - y$to = as.Date(tail(index(object),1)) - - y = .toSpatialPointsDataFrame(y, object, proj4string) - - extractTimeSeries.twdtwRaster(object, y) - }) - -extractTimeSeries.twdtwRaster = function(x, y){ - - # Reproject points to raster projection - y = spTransform(y, CRS(projection(x@timeseries[[1]]))) - # Check if the coordinates are over the raster extent - pto = .getPointsOverRaster(x, y) - if(length(pto)<1) - stop("Extents do not overlap") - if(length(pto) # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-19 # -# # -############################################################### - - -#' @title Linear weight function -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Builds a linear time weight -#' function to compute the TWDTW local cost matrix [1]. -#' -#' @param a numeric. The slop of the line. -#' @param b numeric. The intercept of the line. -#' -#' @docType methods -#' @return A \code{\link[base]{function}} object. -#' -#' @details The linear \code{linearWeight} and \code{logisticWeight} weight functions -#' can be passed to \code{\link[dtwSat]{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 -#' \insertCite{Maus:2016;textual}{dtwSat} the logistic weight had better results than the -#' linear for land cover classification. See \insertCite{Maus:2016;textual}{dtwSat} and -#' \insertCite{Maus:2019;textual}{dtwSat}. -#' -#' @seealso \code{\link[dtwSat]{twdtwApply}} -#' -#' @references -#' \insertAllCited{} -#' -#' @examples -#' lin_fun = linearWeight(a=0.1) -#' lin_fun -#' -#' @export -linearWeight = function(a, b=0){ - function(phi, psi) phi + a*psi + b -} - diff --git a/R/logisticWeight.R b/R/logisticWeight.R deleted file mode 100644 index f36764e..0000000 --- a/R/logisticWeight.R +++ /dev/null @@ -1,50 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Logistic weight function -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Builds a logistic time weight -#' function to compute the TWDTW local cost matrix [1]. -#' -#' @param alpha numeric. The steepness of logistic weight. -#' @param beta numeric. The midpoint of logistic weight. -#' -#' @docType methods -#' @return A \code{\link[base]{function}} object. -#' -#' @details The linear \code{linearWeight} and \code{logisticWeight} weight functions -#' can be passed to \code{\link[dtwSat]{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 analyze time series with phenological cycles -#' of vegetation that are usually bound to seasons. In previous studies by -#' \insertCite{Maus:2016;textual}{dtwSat} the logistic weight had better results than the -#' linear for land cover classification. See \insertCite{Maus:2016;textual}{dtwSat} and -#' \insertCite{Maus:2019;textual}{dtwSat}. -#' -#' @seealso \code{\link[dtwSat]{twdtwApply}} -#' -#' @references -#' \insertAllCited{} -#' -#' @examples -#' log_fun = logisticWeight(alpha=-0.1, beta=100) -#' log_fun -#' -#' @export -logisticWeight = function(alpha, beta){ - function(phi, psi) phi + 1 / (1 + exp(alpha * (psi - beta ))) -} - diff --git a/R/methods.R b/R/methods.R deleted file mode 100644 index 8ecc054..0000000 --- a/R/methods.R +++ /dev/null @@ -1,630 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-02-22 # -# # -############################################################### - -setGeneric("layers", - function(x) standardGeneric("layers")) - -setGeneric("index", - function(x) standardGeneric("index")) - -setGeneric("coverages", - function(x) standardGeneric("coverages")) - -setGeneric("as.twdtwTimeSeries", - function(x) standardGeneric("as.twdtwTimeSeries")) - -setGeneric("bands", - function(x) standardGeneric("bands")) - -setGeneric("is.twdtwTimeSeries", - function(x) standardGeneric("is.twdtwTimeSeries")) - -setGeneric("is.twdtwMatches", - function(x) standardGeneric("is.twdtwMatches")) - -setGeneric("is.twdtwRaster", - function(x) standardGeneric("is.twdtwRaster")) - -setGeneric("projecttwdtwRaster", - function(x, ...) standardGeneric("projecttwdtwRaster")) - -as.data.frame.twdtwTimeSeries <- function(x){ - lapply(x[], function(y){ - out <- data.frame(date = index(y), y) - rownames(out) <- NULL - return(out) - }) -} - -as.list.twdtwTimeSeries = function(x) lapply(seq_along(x), function(i) - new("twdtwTimeSeries", x[[i]], labels(x)[i]) ) - -as.list.twdtwRaster = function(x) { - I = coverages(x) - names(I) = I - lapply(I, function(i) x[[i]]) -} - -as.list.twdtwMatches = function(x) lapply(seq_along(x@timeseries), function(i) - new("twdtwMatches", new("twdtwTimeSeries", x@timeseries[[i]], labels(x@timeseries)[i]), x@patterns, list(x@alignments[[i]])) ) - -dim.twdtwTimeSeries = function(x){ - res = data.frame(as.character(labels(x)), t(sapply(x@timeseries, dim))) - names(res) = c("label", "nrow", "ncol") - row.names(res) = NULL - res -} - -dim.twdtwRaster = function(x){ - res = c(nlayers(x), dim=dim(x@timeseries[[1]])) - names(res) = c("nlayers", "nrow", "ncol", "ntime") - res -} - -res.twdtwRaster = function(x){ - res(x@timeseries[[1]]) -} - -extent.twdtwRaster = function(x){ - extent(x@timeseries[[1]]) -} - -writeRaster.twdtwRaster = function(x, filepath, ...){ - lapply(names(x@timeseries), function(i) writeRaster(x@timeseries[[i]], filename = paste0(filepath, "/", i, ".grd"), ...)) -} - -ncol.twdtwRaster = function(x){ - ncol(x@timeseries[[1]]) -} - -nrow.twdtwRaster = function(x){ - nrow(x@timeseries[[1]]) -} - -nlayers.twdtwRaster = function(x){ - length(coverages(x)) -} - -levels.twdtwRaster = function(x){ - x@levels -} - -layers.twdtwRaster = function(x){ - x@layers -} - -coverages.twdtwRaster = function(x){ - x@layers -} - -bands.twdtwRaster = function(x){ - x@layers -} - -names.twdtwRaster = function(x){ - names(x@timeline) -} - -length.twdtwRaster = function(x){ - nlayers(x) -} - -index.twdtwRaster = function(x){ - x@timeline -} - -index.twdtwTimeSeries = function(x){ - lapply(x@timeseries, index) -} - -index.twdtwMatches = function(x){ - lapply(getTimeSeries(x), index) -} - -length.twdtwTimeSeries = function(x){ - length(x@timeseries) -} - -length.twdtwMatches = function(x){ - if(length(x@alignments)<1) return(x@alignments) - sum(sapply(x[], nrow)) -} - -nrow.twdtwTimeSeries = function(x){ - res = sapply(x@timeseries, nrow) - names(res) = as.character(labels(x)) - res -} - -ncol.twdtwTimeSeries = function(x){ - res = sapply(x@timeseries, ncol) - names(res) = as.character(labels(x)) - res -} - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod(f = "dim", "twdtwTimeSeries", - definition = dim.twdtwTimeSeries) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "dim", "twdtwRaster", - definition = dim.twdtwRaster) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "res", "twdtwRaster", - definition = res.twdtwRaster) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "extent", "twdtwRaster", - definition = extent.twdtwRaster) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod("writeRaster", "twdtwRaster", - definition = function(x, filepath = ".", ...) { - writeRaster.twdtwRaster(x, filepath, ...) - } -) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "ncol", "twdtwRaster", - definition = ncol.twdtwRaster) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "nrow", "twdtwRaster", - definition = nrow.twdtwRaster) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "nlayers", "twdtwRaster", - definition = nlayers.twdtwRaster) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "levels", "twdtwRaster", - definition = levels.twdtwRaster) - -#' @aliases layers -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "layers", "twdtwRaster", - definition = layers.twdtwRaster) - -#' @aliases coverages -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "coverages", "twdtwRaster", - definition = coverages.twdtwRaster) - -#' @aliases bands -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "bands", "twdtwRaster", - definition = bands.twdtwRaster) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "names", "twdtwRaster", - definition = names.twdtwRaster) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "index", "twdtwRaster", - definition = index.twdtwRaster) - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod(f = "index", "twdtwTimeSeries", - definition = index.twdtwTimeSeries) - -#' @inheritParams twdtwMatches-class -#' @rdname twdtwMatches-class -#' @export -setMethod(f = "index", "twdtwMatches", - definition = index.twdtwMatches) - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod(f = "nrow", "twdtwTimeSeries", - definition = nrow.twdtwTimeSeries) - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod(f = "ncol", "twdtwTimeSeries", - definition = ncol.twdtwTimeSeries) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "length", signature = signature("twdtwRaster"), - definition = length.twdtwRaster) - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod(f = "length", signature = signature("twdtwTimeSeries"), - definition = length.twdtwTimeSeries) - -#' @inheritParams twdtwMatches-class -#' @rdname twdtwMatches-class -#' @export -setMethod(f = "length", signature = signature("twdtwMatches"), - definition = length.twdtwMatches) - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod("as.list", "twdtwTimeSeries", as.list.twdtwTimeSeries) - -#' @inheritParams twdtwMatches-class -#' @rdname twdtwMatches-class -#' @export -setMethod("as.list", "twdtwMatches", as.list.twdtwMatches) - -#' @inheritParams twdtwMatches-class -#' @rdname twdtwMatches-class -#' @export -setMethod("as.list", "twdtwRaster", as.list.twdtwRaster) - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod("as.data.frame", "twdtwTimeSeries", as.data.frame.twdtwTimeSeries) - -#' @inheritParams twdtwTimeSeries-class -#' @param i indices of the time series. -#' @rdname twdtwTimeSeries-class -#' @export -setMethod("[", "twdtwTimeSeries", function(x, i) { - if(missing(i)) i = 1:length(x) - if(any(is.na(i))) stop("NA index not permitted") - x@timeseries[i] -}) - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod("[[", "twdtwTimeSeries", function(x, i) { - if(any(is.na(i))) stop("NA index not permitted") - x@timeseries[[i, drop=FALSE]] -}) - -#' @inheritParams twdtwRaster-class -#' @param i indices of the time series. -#' @rdname twdtwRaster-class -#' @export -setMethod("[", "twdtwRaster", function(x, i) { - if(missing(i)) i = 2:nlayers(x) - if(length(i)>1) i = i[i>1] - if(any(i > nlayers(x))) - stop("subscript out of bounds") - if(any(is.na(i))) stop("NA index not permitted") - if(any("doy"==layers(x))) - return(new("twdtwRaster", timeseries=x@timeseries[i], timeline = x@timeline, doy = x@timeseries[[1]])) - new("twdtwRaster", timeseries=x@timeseries[i], timeline = x@timeline) -}) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod("[[", "twdtwRaster", function(x, i) { - if(any(is.na(i))) stop("NA index not permitted") - x@timeseries[[i]] -}) - -#' @inheritParams twdtwMatches-class -#' @param i indices of the time series. -#' @param j indices of the pattern. -#' @param drop if TRUE returns a data.frame, if FALSE returns a list. -#' Default is TRUE. -#' @rdname twdtwMatches-class -#' @export -setMethod("[", "twdtwMatches", function(x, i, j, drop=TRUE) { - if(length(x@alignments)<1) return(x@alignments) - if(missing(i)) i = 1:length(x@alignments) - # if(missing(j)) j = 2:length(x@patterns) - if(any(is.na(i))) stop("NA index not permitted") - if(is(i, "character")) i = match(i, names(x@timeseries@timeseries)) - res = x@alignments[i] - if(missing(j)) j = 1:length(res[[1]]) - if(is(j, "character")) j = match(j, names(x@patterns@timeseries)) - if(any(is.na(j))) stop("NA index not permitted") - res = lapply(res, function(x) x[j]) - res = res[sapply(res, length)>0] - if(!drop) return(res) - lapply(res, function(x){ - res = do.call("rbind", lapply(seq_along(x), function(jj){ - data.frame(Alig.N=seq_along(x[[jj]]$distance),from=x[[jj]]$from, to=x[[jj]]$to, distance=x[[jj]]$distance, label=x[[jj]]$label, row.names=NULL) - })) - res[order(res$from),] - }) -}) - -#' @inheritParams twdtwMatches-class -#' @rdname twdtwMatches-class -#' @export -setMethod("[[", c("twdtwMatches", "numeric"), function(x, i, j,drop=TRUE) { - if(any(is.na(i))) stop("NA index not permitted") - if(missing(j)) j = 1:length(x@alignments[[1]]) - x[i,j,drop=drop][[1]] -}) - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod("labels", signature = signature(object="twdtwTimeSeries"), - definition = function(object) as.character(object@labels)) - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod("levels", "twdtwTimeSeries", - definition = function(x) levels(factor(labels(x)))) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod("labels", signature = signature(object="twdtwRaster"), - definition = function(object) as.character(object@labels)) - -#' @inheritParams twdtwMatches-class -#' @rdname twdtwMatches-class -#' @export -setMethod("labels", - signature = signature(object="twdtwMatches"), - definition = function(object){ - list(timeseries = labels(object@timeseries), - patterns = labels(object@patterns)) - } -) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @param y Extent object, or any object from which an Extent object can be extracted. -#' @export -setMethod("crop", - signature = signature("twdtwRaster"), - definition = function(x, y, ...){ - x@timeseries = lapply(x@timeseries, crop, y=y, ...) - x - } -) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @param obj object of class twdtwRaster. -#' @export -setMethod("coordinates", - signature = signature("twdtwRaster"), - definition = function(obj, ...){ - coordinates(obj@timeseries[[1]], ...) - } -) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod("extent", - signature = signature("twdtwRaster"), - definition = function(x, y, ...){ - extent(x@timeseries[[1]]) - } -) - -# Show objects of class twdtwTimeSeries -show.twdtwTimeSeries = function(object){ - cat("An object of class \"twdtwTimeSeries\"\n") - cat("Slot \"timeseries\" length:",length(object),"\n") - cat("Slot \"labels\": ") - I = match(1:3, seq_along(labels(object))) - print(labels(object)[na.omit(I)]) - invisible(NULL) -} - -# Show objects of class twdtwMatches -show.twdtwMatches = function(object){ - cat("An object of class \"twdtwMatches\"\n") - cat("Number of time series:",length(object@timeseries),"\n") - cat("Number of alignments:",length(object),"\n") - cat("Patterns labels:",as.character(labels(object@patterns)),"\n") - invisible(NULL) -} - -# Show objects of class twdtwRaster -show.twdtwRaster = function(object){ - cat("An object of class \"twdtwRaster\"\n") - cat("Time series layers:",coverages(object),"\n") - cat("Time range:",paste(min(object@timeline)),"...",paste(max(object@timeline)),"\n") - cat("Dimensions:",dim(object),"(nlayers, nrow, ncol, length)\n") - cat("Resolution:",res(object)," (x, y)\n") - cat("Extent :",as.vector(extent(object)), "(xmin, xmax, ymin, ymax)\n") - cat("Coord.ref.:",projection(object@timeseries[[1]]),"\n") - invisible(NULL) -} - -# Show objects of class twdtwAssessment -show.twdtwAssessment = function(object){ - cat("An object of class \"twdtwAssessment\"\n") - cat("Number of classification intervals:",length(object@accuracyByPeriod),"\n") - cat("Accuracy metrics summary\n") - cat("\nOverall\n") - aux = object@accuracySummary$OverallAccuracy - names(aux) = gsub("ci", "ci*", names(aux)) - print(aux, digits=2) - cat("\nUser's\n") - aux = object@accuracySummary$UsersAccuracy - colnames(aux) = gsub("ci", "ci*", colnames(aux)) - print(aux, digits=2) - cat("\nProducer's\n") - aux = object@accuracySummary$ProducersAccuracy - colnames(aux) = gsub("ci", "ci*", colnames(aux)) - print(aux, digits=2) - cat("\nArea and uncertainty\n") - aux = object@accuracySummary$AreaUncertainty - colnames(aux) = gsub("ci", "ci*", colnames(aux)) - print(aux, digits=2) - cat("\n*",100*object@accuracySummary$conf.int,"% confidence interval\n") - invisible(NULL) -} - -# Show objects of class twdtwCrossValidation -show.twdtwCrossValidation = function(object){ - res = summary(object, conf.int=.95) - cat("An object of class \"twdtwCrossValidation\"\n") - cat("Number of data partitions:",length(object@partitions),"\n") - cat("Accuracy metrics using bootstrap simulation (CI .95)\n") - cat("\nOverall\n") - print(res$Overall, digits=2) - cat("\nUser's\n") - print(res$Users, digits=2) - cat("\nProducer's\n") - print(res$Producers, digits=2) - invisible(NULL) -} - -# Project raster which belongs to a twdtwRaster object -projecttwdtwRaster.twdtwRaster = function(x, to, ...){ - x@timeseries = lapply(x@timeseries, projectRaster, to, ...) - x -} - -summary.twdtwCrossValidation = function(object, conf.int=.95, ...){ - - ov = do.call("rbind", lapply(object@accuracy, function(x){ - data.frame(OV=x$OverallAccuracy, row.names = NULL) - })) - - uapa = do.call("rbind", lapply(object@accuracy, function(x){ - data.frame(label=names(x$UsersAccuracy), UA=x$UsersAccuracy, PA=x$ProducersAccuracy, row.names = NULL) - })) - - sd_ov = sd(ov[, c("OV")]) - sd_uapa = aggregate(uapa[, c("UA","PA")], list(uapa$label), sd) - l_names = unique(uapa$label) - names(l_names) = l_names - ic_ov = mean_cl_boot(x = ov[, c("OV")], conf.int = conf.int, ...) - names(ic_ov) = NULL - assess_ov = unlist(c(Accuracy=ic_ov[1], sd=sd_ov, CImin=ic_ov[2], CImax=ic_ov[3])) - ic_ua = t(sapply(l_names, function(i) mean_cl_boot(x = uapa$UA[uapa$label==i], conf.int = conf.int, ...))) - names(ic_ua) = NULL - assess_ua = data.frame(Accuracy=unlist(ic_ua[,1]), sd=sd_uapa[,"UA"], CImin=unlist(ic_ua[,2]), CImax=unlist(ic_ua[,3])) - ic_pa = t(sapply(l_names, function(i) mean_cl_boot(x = uapa$PA[uapa$label==i], conf.int = conf.int, ...))) - names(ic_pa) = NULL - assess_pa = data.frame(Accuracy=unlist(ic_pa[,1]), sd=sd_uapa[,"PA"], CImin=unlist(ic_pa[,2]), CImax=unlist(ic_pa[,3])) - list(Overall=assess_ov, Users=assess_ua, Producers=assess_pa) -} - -#' @inheritParams twdtwCrossValidation-class -#' @rdname twdtwCrossValidation-class -#' @export -setMethod(f = "show", "twdtwCrossValidation", - definition = show.twdtwCrossValidation) - -#' @inheritParams twdtwAssessment-class -#' @rdname twdtwAssessment-class -#' @export -setMethod(f = "show", "twdtwAssessment", - definition = show.twdtwAssessment) - -#' @inheritParams twdtwCrossValidation-class -#' @rdname twdtwCrossValidation-class -#' @export -setMethod(f = "summary", "twdtwCrossValidation", - definition = summary.twdtwCrossValidation) - -#' @inheritParams twdtwTimeSeries-class -#' @rdname twdtwTimeSeries-class -#' @export -setMethod(f = "show", "twdtwTimeSeries", - definition = show.twdtwTimeSeries) - -#' @inheritParams twdtwMatches-class -#' @rdname twdtwMatches-class -#' @export -setMethod(f = "show", "twdtwMatches", - definition = show.twdtwMatches) - -#' @inheritParams twdtwRaster-class -#' @rdname twdtwRaster-class -#' @export -setMethod(f = "show", "twdtwRaster", - definition = show.twdtwRaster) - -#' @aliases as.twdtwTimeSeries -#' @inheritParams twdtwTimeSeries-class -#' @describeIn twdtwTimeSeries convert list of data.frame to class twdtwTimeSeries. -#' @export -setMethod("as.twdtwTimeSeries", "ANY", - function(x) twdtwTimeSeries(lapply(x[], function(y) zoo(y[, names(y)!="date"], order.by = y$date)))) - -#' @aliases is.twdtwTimeSeries -#' @inheritParams twdtwTimeSeries-class -#' @describeIn twdtwTimeSeries Check if the object belongs to the class twdtwTimeSeries. -#' @export -setMethod("is.twdtwTimeSeries", "ANY", - function(x) is(x, "twdtwTimeSeries")) - -#' @aliases is.twdtwMatches -#' @inheritParams twdtwMatches-class -#' @describeIn twdtwMatches Check if the object belongs to the class twdtwMatches. -#' @export -setMethod("is.twdtwMatches", "ANY", - function(x) is(x, "twdtwMatches")) - -#' @aliases is.twdtwRaster -#' @inheritParams twdtwRaster-class -#' @describeIn twdtwRaster Check if the object belongs to the class twdtwRaster. -#' @export -setMethod("is.twdtwRaster", "ANY", - function(x) is(x, "twdtwRaster")) - -#' @aliases projecttwdtwRaster -#' @inheritParams twdtwRaster-class -#' @describeIn twdtwRaster project twdtwRaster object. -#' @param crs character or object of class 'CRS'. PROJ.4 description of -#' the coordinate reference system. For other arguments and more details see -#' \code{\link[raster]{projectRaster}}. -#' -#' @export -setMethod("projecttwdtwRaster", "twdtwRaster", - function(x, crs, ...) projecttwdtwRaster.twdtwRaster(x, crs, ...)) - - - - - - diff --git a/R/miscellaneous.R b/R/miscellaneous.R index ab90d65..eaa21f9 100644 --- a/R/miscellaneous.R +++ b/R/miscellaneous.R @@ -1,4 +1,3 @@ - #' @title Get dates from year and day of the year #' @author Victor Maus, \email{vwmaus1@@gmail.com} #' @@ -20,14 +19,8 @@ #' #' \insertRef{Maus:2016}{dtwSat} #' -#' @examples -#' year = c(2000, 2001) -#' doy = c(366, 365) -#' dates = getDatesFromDOY(year, doy) -#' dates -#' #' @export -getDatesFromDOY = function(year, doy){ +get_dates_from_doy = function(year, doy){ res = as.Date(paste(as.numeric(year), as.numeric(doy)), format="%Y %j", origin="1970-01-01") I = which(diff(res)<0)+1 res[I] = as.Date(paste0(as.numeric(format(res[I],"%Y"))+1, format(res[I], "-%m-%d"))) @@ -37,7 +30,6 @@ getDatesFromDOY = function(year, doy){ #' @title Shift dates -#' @name shiftDates #' @author Victor Maus, \email{vwmaus1@@gmail.com} #' #' @description This function shifts the dates of the time series to a @@ -48,9 +40,6 @@ getDatesFromDOY = function(year, doy){ #' #' @param year the base year to shift the time series to. #' -#' @seealso -#' \code{\link[dtwSat]{twdtwTimeSeries-class}} -#' #' @return An object of the same class as the input \code{object}. #' #' @references @@ -59,44 +48,7 @@ getDatesFromDOY = function(year, doy){ #' \insertRef{Maus:2016}{dtwSat} #' #' @export -setGeneric("shiftDates", function(object, year=NULL) standardGeneric("shiftDates")) - -#' @rdname shiftDates -#' @aliases shiftDates-twdtwTimeSeries -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' npatt = shiftDates(patt, year=2005) -#' index(patt) -#' index(npatt) -#' -#' @export -setMethod("shiftDates", "twdtwTimeSeries", - function(object, year) - do.call("twdtwTimeSeries", lapply(as.list(object), FUN=shiftDates.twdtwTimeSeries, year=year))) - -#' @rdname shiftDates -#' @aliases shiftDates-list -#' @export -setMethod("shiftDates", "list", - function(object, year) - shiftDates(twdtwTimeSeries(object), year=year)[]) - -setOldClass("zoo") -#' @rdname shiftDates -#' @aliases shiftDates-zoo -#' @export -setMethod("shiftDates", "zoo", - function(object, year) - shiftDates(twdtwTimeSeries(object), year=year)[[1]]) - - -shiftDates.twdtwTimeSeries = function(x, year){ +shift_dates = function(x, year){ labels = as.character(labels(x)) x = x[[1]] dates = index(x) @@ -105,95 +57,3 @@ shiftDates.twdtwTimeSeries = function(x, year){ d = as.numeric(dates) - shift_days new("twdtwTimeSeries", timeseries=zoo(data.frame(x), as.Date(d)), labels=labels) } - - -.adjustFactores = function(ref, pred, levels=NULL, labels=NULL){ - ref = as.character(ref) - pred = as.character(pred) - if(is.null(levels)) - levels = sort(unique(ref)) - if(is.null(labels)) - labels = levels - ref = factor(ref, levels, labels) - pred = factor(pred, levels, labels) - data = data.frame(Predicted=pred, Reference=ref) -} - -.adjustLabelID = function(y, labels, id.labels){ - if(!"label"%in%names(y)) y$label = paste0("ts",row.names(y)) - if(!is.null(id.labels)) y$label = as.character(y[[id.labels]]) - if(!is.null(id.labels) & !is.null(labels)){ - I = which(!is.na(match(as.character(y$label), as.character(labels)))) - if(length(I)<1) - stop("There are no matches between id.labels and labels") - } else if(!is.null(labels)) { - y$label = as.character(labels) - } - y -} - -.toSpatialPointsDataFrame = function(y, object, proj4string){ - if(is(y, "data.frame")){ - if(is.null(proj4string)){ - warning("Missing projection. Setting the same projection as the raster time series.", call. = FALSE) - proj4string = CRS(projection(object@timeseries[[1]])) - } - if(!is(proj4string, "CRS")) proj4string = try(CRS(proj4string)) - y = SpatialPointsDataFrame(y[,c("longitude","latitude")], y, proj4string = proj4string) - } - if(!(is(y, "SpatialPoints") | is(y, "SpatialPointsDataFrame"))) - stop("y is not SpatialPoints or SpatialPointsDataFrame") - row.names(y) = 1:nrow(y) - y -} - - -.getPredRefClasses = function(i, r_intervals, pred_classes, pred_distance, y, rlevels, rnames){ - i_leng = as.numeric(r_intervals$to[i] - r_intervals$from[i]) - from = as.Date(y$from) - to = as.Date(y$to) - # Select overlapping alignments - J = which(from <= r_intervals$to[i] & to >= r_intervals$from[i]) - # Adjust overlapping - from = sapply(from[J], function(x) ifelse(x < r_intervals$from[i], r_intervals$from[i], x)) - to = sapply(to[J], function(x) ifelse(x > r_intervals$to[i], r_intervals$to[i], x)) - # Compute overlapping proportion - if(length(to)<1) - return(NULL) - i_over = to - from - # print(i_leng) - # print(i_over) - prop_over = abs(i_over / i_leng) - # Select alignments - I = which(prop_over > .5) - # I = which((r_intervals$to[i] - as.Date(y$from) > 30) & (as.Date(y$to) - r_intervals$from[i] > 30) ) - if(length(J[I])<1) - return(NULL) - K = match(pred_classes[J[I],i], rlevels) - Predicted = factor(as.character(rnames[K]), levels = rnames, labels = rnames) - Reference = factor(as.character(y$label[J[I]]), levels = rnames, labels = rnames) - Distance = pred_distance[J[I],i] - data.frame(Sample.id = row.names(y)[J[I]], coordinates(y[J[I],]), Period=i, from=r_intervals$from[i], to=r_intervals$to[i], Predicted, Reference, Distance) -} - -.getAreaByClass = function(l, r, rlevels, rnames){ - r = raster(r, layer = l) - if(isLonLat(r)){ - warning("Computing the approximate surface area in km2 of cells in an unprojected (longitude/latitude) Raster object. See ?raster::area", call. = TRUE) - # r = projectRaster(from = r, crs = proj_str, method = 'ngb') - ra = area(r) - I = lapply(rlevels, function(i) r[]==i ) - out = sapply(I, function(i) sum(ra[i], na.rm = TRUE) ) - names(out) = rnames - } else { - npx = zonal(r, r, 'count') - I = match(npx[,'zone'], rlevels) - out = rep(0, length(rnames)) - names(out) = rnames - out[I] = npx[,'count'] * prod(res(r)) - names(out) = rnames - } - out -} - - diff --git a/R/plot.R b/R/plot.R deleted file mode 100644 index abf961b..0000000 --- a/R/plot.R +++ /dev/null @@ -1,231 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting twdtw* objects -#' @name plot -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Methods for plotting objects of class twdtw*. -#' -#' @param x An object of class twdtw*. -#' @param type A character for the plot type: ''paths'', ''matches'', -#' ''alignments'', ''classification'', ''cost'', ''patterns'', ''timeseries'', -#' ''maps'', ''area'', ''changes'', and ''distance''. -#' -#' @param ... additional arguments to pass to plotting functions. -#' \code{\link[dtwSat]{plotPaths}}, -#' \code{\link[dtwSat]{plotCostMatrix}}, -#' \code{\link[dtwSat]{plotAlignments}}, -#' \code{\link[dtwSat]{plotMatches}}, -#' \code{\link[dtwSat]{plotClassification}}, -#' \code{\link[dtwSat]{plotPatterns}}, -#' \code{\link[dtwSat]{plotTimeSeries}}, -#' \code{\link[dtwSat]{plotMaps}}, -#' \code{\link[dtwSat]{plotArea}}, or -#' \code{\link[dtwSat]{plotChanges}}. -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @details -#' \describe{ -#' \item{Plot types}{: -#' \cr\code{paths}: Method for plotting the minimum paths in the cost matrix of TWDTW. -#' \cr\code{matches}: Method for plotting the matching points from TWDTW analysis. -#' \cr\code{alignments}: Method for plotting the alignments and respective TWDTW dissimilarity measures. -#' \cr\code{classification}: Method for plotting the classification of each subinterval of the time series based on TWDTW analysis. -#' \cr\code{cost}: Method for plotting the internal matrices used during the TWDTW computation. -#' \cr\code{patterns}: Method for plotting the temporal patterns. -#' \cr\code{timeseries}: Method for plotting the temporal patterns. -#' } -#' } -#' -#' @export -NULL - -#' @aliases plot-twdtwAssessment -#' @inheritParams plot -#' @rdname plot -#' @export -setMethod("plot", - signature(x = "twdtwAssessment"), - function(x, type="area", ...){ - pt = pmatch(type, c("area","accuracy","map")) - switch(pt, - plotAdjustedArea(x, ...), - plotAccuracy(x, ...), - plotMapSamples(x, ...) - ) - } -) - -#' @aliases plot-twdtwTimeSeries -#' @inheritParams plot -#' @rdname plot -#' @export -setMethod("plot", - signature(x = "twdtwCrossValidation"), - function(x, type="crossvalidation", ...){ - pt = pmatch(type, c("crossvalidation")) - switch(pt, - plotAccuracy(x, ...) - ) - } -) - -#' @aliases plot-twdtwTimeSeries -#' @inheritParams plot -#' @rdname plot -#' @export -setMethod("plot", - signature(x = "twdtwTimeSeries"), - function(x, type="timeseries", ...){ - pt = pmatch(type,c("patterns","timeseries")) - switch(pt, - plotPatterns(x, ...), - plotTimeSeries(x, ...) - ) - } -) - - -#' @aliases plot-twdtwMatches -#' @inheritParams plot -#' @rdname plot -#' @export -setMethod("plot", - signature(x = "twdtwMatches"), - function(x, type="alignments", ...){ - pt = pmatch(type,c("paths","matches","alignments","classification","cost")) - switch(pt, - plotPaths(x, ...), - plotMatches(x, ...), - plotAlignments(x, ...), - plotClassification(x, ...), - plotCostMatrix(x, ...) - ) - } -) - - - -#' @aliases plot-twdtwRaster -#' @inheritParams plot -#' @rdname plot -#' @export -setMethod("plot", signature(x = "twdtwRaster"), function(x, type="maps", ...) .PlotRaster(x, type=type, ...)) - -.PlotRaster = function(x, type, time.levels=NULL, time.labels=NULL, class.levels=NULL, class.labels=NULL, class.colors=NULL, layers=NULL, perc=TRUE, ...){ - - if(type=="distance") { - - if( is.null(time.levels)) - time.levels = names(x) - - if(is(time.levels, "numeric")) - time.levels = names(x)[time.levels] - - if( is.null(time.labels)) - time.labels = format(as.Date(time.levels, "date.%Y.%m.%d"), "%Y") - - if(length(time.levels)!=length(time.labels)) - stop("time.levels and time.labels have different lengths") - - if(is.null(layers)) { - if(any(coverages(x)=="Distance")){ - layers = "Distance" - time.levels = time.levels - labels = time.labels - time.labels=NULL - } - else { - layers = coverages(x) - layers = layers[!layers%in%"doy"] - time.levels = time.levels[1] - time.labels = time.labels[1] - labels = layers - } - } else { - if(is(layers, "numeric")) layers = coverages(x)[layers] - time.levels = time.levels[1] - time.labels = time.labels[1] - labels = layers - } - - x = lapply(as.list(x)[layers], FUN=subset, subset=time.levels) - gp = .plotDistance(brick(x), layers, labels, time.labels) - - } else { - - if( is.null(time.levels)) - time.levels = seq_along(index(x)) - - if(is.null(time.labels)) - time.labels = format(index(x), "%Y") - - if(is(time.levels, "numeric")){ - time.levels = names(x)[time.levels] - time.labels = time.labels[time.levels] - } - - - if(length(time.levels)!=length(time.labels)) - stop("time.levels and time.labels have different lengths") - - # if(length(time.levels)>16){ - # time.levels = time.levels[1:16] - # time.labels = time.labels[1:16] - # } - - if( is.null(class.levels)) - class.levels = levels(x) - - if(length(class.levels)<1) - class.levels = sort(unique(as.numeric(x[["Class"]][]))) - - if( is.null(class.labels)) - class.labels = labels(x) - - if(length(class.labels)<1) - class.labels = as.character(class.levels) - - if( is.null(class.colors) ) - class.colors = brewer.pal(length(class.levels), "Set3") - - if( length(class.colors) # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting alignments -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting the alignments and TWDTW -#' dissimilarity measures. -#' -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwMatches}}. -#' @param timeseries.labels the label or index of the time series. -#' Default is 1. -#' @param patterns.labels a vector with labels of the patterns. If not -#' declared the function will plot the alignments for all patterns in \code{x}. -#' @param attr An \link[base]{integer} or \link[base]{character} vector -#' indicating the attribute for plotting. Default is 1. -#' @param threshold A number. The TWDTW dissimilarity threshold, \emph{i.e.} the -#' maximum TWDTW cost for consideration. Default is \code{Inf}. -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{plotPaths}}, -#' \code{\link[dtwSat]{plotCostMatrix}}, -#' \code{\link[dtwSat]{plotMatches}}, and -#' \code{\link[dtwSat]{plotClassification}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' log_fun = logisticWeight(-0.1, 100) -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) -#' -#' plotAlignments(mat1) -#' -#' plotAlignments(mat1, attr=c("evi","ndvi")) -#' -#' @export -plotAlignments = function(x, timeseries.labels=NULL, patterns.labels=NULL, attr=1, threshold=Inf){ - - x = subset(x, timeseries.labels[1], patterns.labels) - - ## Get data - ts = getTimeSeries(x)[[1]] - alignments = x[[1]] - - # Get time series - df.x = data.frame(ts[,attr,drop=FALSE]) - df.x$Time = as.Date(rownames(df.x)) - df.alignments = melt(df.x, id="Time") - df.alignments$distance = NA - df.alignments$variable = as.character(df.alignments$variable) - df.alignments$Variable = df.alignments$variable - df.alignments$Pattern = NA - df.alignments$group = df.alignments$variable - df.alignments$facets = 1 - df.alignments$facets = factor(df.alignments$facets, levels = c(1,2), labels = c("Time series","TWDTW dissimilarity measure")) - - # Get matching points - df.matches = list() - df.matches$Time = c(alignments$from, alignments$to) - df.matches$variable = rep(alignments$label, 2) - df.matches$value = rep(alignments$distance, 2) - df.matches$distance = df.matches$value - df.matches$Variable = NA - df.matches$Pattern = df.matches$variable - df.matches$group = as.character(rep(1:length(alignments$label), 2)) - df.matches$facets = 2 - df.matches = data.frame(df.matches, stringsAsFactors = FALSE) - df.matches$facets = factor(df.matches$facets, levels = c(1,2), labels = c("Time series","TWDTW dissimilarity measure")) - - I = which(df.matches$value>threshold) - if(length(I)>0) - df.matches = df.matches[-I,] - - df.all = rbind(df.alignments, df.matches) - - gp = ggplot(data=df.all) + - geom_line(data=df.alignments, aes_string(x='Time', y='value', group='group', linetype='Variable')) + - guides(linetype = guide_legend(title = "Bands")) + - facet_wrap(~facets, ncol = 1, scales = "free_y") + - geom_path(data=df.matches, aes_string(x='Time', y='distance', group='group', colour='Pattern')) + - geom_point(data=df.matches, aes_string(x='Time', y='distance', group='group', colour='Pattern')) + - ylab("Value") - gp -} - diff --git a/R/plotArea.R b/R/plotArea.R deleted file mode 100644 index 9b904ff..0000000 --- a/R/plotArea.R +++ /dev/null @@ -1,134 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting accumulated area -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting time series of accumulated area. -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwRaster}}. -#' @param time.levels A \link[base]{character} or \link[base]{numeric} -#' vector with the layers to plot. For plot type ''change'' the minimum length -#' is two. -#' @param time.labels A \link[base]{character} or \link[base]{numeric} -#' vector with the labels of the layers. It must have the same -#' length as time.levels. Default is NULL. -#' @param class.levels A \link[base]{character} or \link[base]{numeric} -#' vector with the levels of the raster values. Default is NULL. -#' @param class.labels A \link[base]{character} or \link[base]{numeric} -#' vector with the labels of the raster values. It must have the same -#' length as class.levels. Default is NULL. -#' @param class.colors a set of aesthetic values. It must have the same -#' length as class.levels. Default is NULL. See -#' \link[ggplot2]{scale_fill_manual} for details. -#' @param perc if TRUE shows the results in percent of area. Otherwise shows the -#' area in the map units or km2 for no project raster. Default is TRUE. -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwRaster-class}}, -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{plotMaps}}, -#' \code{\link[dtwSat]{plotChanges}}, and -#' \code{\link[dtwSat]{plotDistance}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' \dontrun{ -#' -#' # Create raster time series -#' 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) -#' -#' # Read field samples -#' field_samples = read.csv(system.file("lucc_MT/data/samples.csv", package="dtwSat")) -#' proj_str = scan(system.file("lucc_MT/data/samples_projection", -#' package="dtwSat"), what = "character") -#' -#' # Split samples for training (10%) and validation (90%) using stratified sampling -#' library(caret) -#' set.seed(1) -#' I = unlist(createDataPartition(field_samples$label, p = 0.1)) -#' training_samples = field_samples[I,] -#' validation_samples = field_samples[-I,] -#' -#' # Create temporal patterns -#' training_ts = getTimeSeries(rts, y = training_samples, proj4string = proj_str) -#' temporal_patterns = createPatterns(training_ts, freq = 8, formula = y ~ s(x)) -#' -#' # Run TWDTW analysis for raster time series -#' log_fun = weight.fun=logisticWeight(-0.1,50) -#' r_twdtw = twdtwApply(x=rts, y=temporal_patterns, weight.fun=log_fun, format="GTiff", -#' overwrite=TRUE) -#' -#' # Classify raster based on the TWDTW analysis -#' r_lucc = twdtwClassify(r_twdtw, format="GTiff", overwrite=TRUE) -#' -#' plotArea(r_lucc) -#' -#' plotArea(r_lucc, perc=FALSE) -#' -#' } -#' @export -plotArea = function(x, time.levels=NULL, time.labels=NULL, class.levels=NULL, class.labels=NULL, class.colors=NULL, perc=TRUE){ - plot(x, type="area", time.levels=time.levels, time.labels=time.labels, class.levels=class.levels, class.labels=class.labels, class.colors=class.colors, perc=perc) -} - -.plotArea = function(x, time.levels, time.labels, class.levels, class.labels, class.colors, perc){ - - df.area = do.call("rbind", lapply(time.levels, .getAreaByClass, x, class.levels, class.labels)) - df.area = data.frame(variable = as.numeric(time.labels), df.area, stringsAsFactors = FALSE) - names(class.colors) = names(df.area)[-1] - df.area = melt(df.area, "variable", value.name = "Freq", variable.name = "value") - df.area$Time = as.numeric(df.area$variable) - df.area$variable = factor(df.area$variable) - - if(perc) - df.area$Freq = df.area$Freq / (sum(df.area$Freq) / length(time.levels)) - - x.breaks = pretty_breaks()(range(df.area$Time)) - - gp = ggplot(data=df.area, aes_string(x="Time", y="Freq", fill="value")) + - geom_area(position = 'stack') + - scale_fill_manual(name="Legend", values = class.colors) + - scale_x_continuous(expand = c(0.01, 0), breaks = x.breaks) + - theme(legend.position = "bottom", - panel.background = element_blank()) + - ylab("Area") - - if(perc){ - gp = gp + scale_y_continuous(expand = c(0, 0), labels = percent) - } else { - gp = gp + scale_y_continuous(expand = c(0, 0)) - } - - gp - -} - - - diff --git a/R/plotChanges.R b/R/plotChanges.R deleted file mode 100644 index eb21d4f..0000000 --- a/R/plotChanges.R +++ /dev/null @@ -1,121 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting changes -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting changes over time. -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwRaster}}. -#' @param time.levels A \link[base]{character} or \link[base]{numeric} -#' vector with the layers to plot. For plot type ''change'' the minimum length -#' is two. -#' @param time.labels A \link[base]{character} or \link[base]{numeric} -#' vector with the labels of the layers. It must have the same -#' length as time.levels. Default is NULL. -#' @param class.levels A \link[base]{character} or \link[base]{numeric} -#' vector with the levels of the raster values. Default is NULL. -#' @param class.labels A \link[base]{character} or \link[base]{numeric} -#' vector with the labels of the raster values. It must have the same -#' length as class.levels. Default is NULL. -#' @param class.colors A set of aesthetic values. It must have the same -#' length as class.levels. Default is NULL. See -#' \link[ggplot2]{scale_fill_manual} for details. -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwRaster-class}}, -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{plotArea}}, -#' \code{\link[dtwSat]{plotMaps}}, and -#' \code{\link[dtwSat]{plotDistance}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @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") -#' -#' r_lucc = twdtwClassify(r_twdtw, format="GTiff", overwrite=TRUE) -#' -#' plotChanges(r_lucc) -#' -#' } -#' @export -plotChanges = function(x, time.levels=NULL, time.labels=NULL, class.levels=NULL, class.labels=NULL, class.colors=NULL){ - plot(x, type="changes", time.levels=time.levels, time.labels=time.labels, class.levels=class.levels, class.labels=class.labels, class.colors=class.colors) -} - -.plotChanges = function(x, time.levels, time.labels, class.levels, class.labels, class.colors){ - - if(length(time.levels)<2) - stop("The length of time.levels is shorter than two") - - df = do.call("rbind", lapply(seq_along(time.levels)[-1], function(l){ - from = raster::subset(x=x, subset=time.levels[l-1])[] - to = raster::subset(x=x, subset=time.levels[l] )[] - res = data.frame(from, to) - res = data.frame(xtabs(~ from + to, res) / nrow(res)) - res$layer = paste0(time.labels[l-1],"-",time.labels[l]) - res - })) - - df$from = factor(df$from, levels = class.levels, labels = class.labels) - df$to = factor(df$to, levels = class.levels, labels = class.labels) - df$from = factor(df$from) - df$to = factor(df$to) - I = df$from!=df$to - - # Plot change - gp = ggplot() + - geom_bar(data=df[I,], position = "stack", aes_string(x="to", y="Freq", fill="from"), stat="identity") + - geom_bar(data=df[I,], position = "stack", aes_string(x="from", y="-Freq", fill="to"), stat="identity") + - facet_wrap(~layer) + - scale_fill_manual(name = "Legend", values = class.colors) + - scale_y_continuous(labels = percent) + - xlab("") + - geom_hline(yintercept = 0) + - coord_flip() + - theme(legend.position = "bottom") + - ylab("Percentage of land changes") - - gp - - -} - - - diff --git a/R/plotClassification.R b/R/plotClassification.R deleted file mode 100644 index 61a6b37..0000000 --- a/R/plotClassification.R +++ /dev/null @@ -1,114 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting subintervals classification -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting the classification of each -#' subinterval of the time series based on TWDTW analysis. -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwMatches}}. -#' @param timeseries.labels The label or index of the time series. -#' Default is 1. -#' @param patterns.labels A vector with labels of the patterns. If not -#' declared the function will plot one alignment for each pattern. -#' -#' @param attr An \link[base]{integer} vector or \link[base]{character} vector -#' indicating the attribute for plotting. If not declared the function will plot -#' all attributes. -#' @param ... Additional arguments passed to \code{\link[dtwSat]{twdtwClassify}}. -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{twdtwClassify}}, -#' \code{\link[dtwSat]{plotAlignments}}, -#' \code{\link[dtwSat]{plotPaths}}, -#' \code{\link[dtwSat]{plotMatches}}, and -#' \code{\link[dtwSat]{plotCostMatrix}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' log_fun = logisticWeight(-0.1, 100) -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) -#' -#' # Classify interval -#' from = as.Date("2007-09-01") -#' to = as.Date("2013-09-01") -#' by = "6 month" -#' gp = plotClassification(x=mat1, from=from, to=to, by=by, overlap=.5) -#' gp -#' -#' -#' @export -plotClassification = function(x, timeseries.labels=NULL, patterns.labels=NULL, attr, ...){ - - if(length(timeseries.labels)>6) timeseries.labels = timeseries.labels[1:6] - x = subset(x, timeseries.labels, patterns.labels) - if(length(list(...))>0) x = twdtwClassify(x, ...) - - ## Get data - if(missing(attr)) attr = names(getTimeSeries(x,1)[[1]]) - df.x = do.call("rbind", lapply(as.list(x), function(xx){ - ts = getTimeSeries(xx)[[1]][,attr,drop=FALSE] - data.frame(Time=index(ts), ts, Series=labels(xx)$timeseries) - })) - df.x = melt(df.x, id.vars=c("Time","Series")) - - y.labels = pretty_breaks()(range(df.x$value, na.rm = TRUE)) - y.breaks = y.labels - - df.pol = do.call("rbind", lapply(as.list(x), function(xx){ - best_class = xx[[1]] - df.pol = do.call("rbind", lapply(1:nrow(best_class), function(i){ - data.frame( - Time = c(best_class$from[i], best_class$to[i], best_class$to[i], best_class$from[i]), - Group = rep(i, 4), - Class = rep(as.character(best_class$label[i]), 4), - value = rep(range(y.breaks, na.rm = TRUE), each=2)) - })) - df.pol$Group = factor(df.pol$Group) - df.pol$Class = factor(df.pol$Class) - df.pol$Series = rep(as.character(labels(xx)$timeseries), length(df.pol$Time)) - df.pol - })) - - I = min(df.pol$Time, na.rm = TRUE)-30 <= df.x$Time & - df.x$Time <= max(df.pol$Time, na.rm = TRUE)+30 - - df.x = df.x[I,,drop=FALSE] - - gp = ggplot() + - facet_wrap(~Series, scales = "free_x", ncol=1) + - geom_polygon(data=df.pol, aes_string(x='Time', y='value', group='Group', fill='Class'), alpha=.7) + - scale_fill_brewer(palette="Set3") + - geom_line(data=df.x, aes_string(x='Time', y='value', colour='variable')) + - scale_y_continuous(expand = c(0, 0), breaks=y.breaks, labels=y.labels) + - scale_x_date(breaks=waiver(), labels=waiver()) + - theme(legend.position = "bottom") + - guides(colour = guide_legend(title = "Bands")) + - ylab("Value") + - xlab("Time") - gp -} - diff --git a/R/plotCostMatrix.R b/R/plotCostMatrix.R deleted file mode 100644 index 7476b38..0000000 --- a/R/plotCostMatrix.R +++ /dev/null @@ -1,124 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting paths -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting low cost paths in the TWDTW -#' cost matrix. -#' -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwMatches}}. -#' @param timeseries.labels The label or index of the time series. -#' Default is 1. -#' @param patterns.labels A vector with labels of the patterns. If not -#' declared the function will plot one alignment for each pattern. -#' @param matrix.name A character. The name of the matrix to plot, -#' "costMatrix" for accumulated cost, "localMatrix" for local cost, -#' or "timeWeight" for time-weight. Default is "costMatrix". -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{plotAlignments}}, -#' \code{\link[dtwSat]{plotPaths}}, -#' \code{\link[dtwSat]{plotMatches}}, and -#' \code{\link[dtwSat]{plotClassification}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' log_fun = logisticWeight(-0.1, 100) -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) -#' -#' plotCostMatrix(mat1, matrix.name="costMatrix") -#' -#' plotCostMatrix(mat1, matrix.name="localMatrix") -#' -#' plotCostMatrix(mat1, matrix.name="timeWeight") -#' -#' @export -plotCostMatrix = function(x, timeseries.labels=NULL, patterns.labels=NULL, matrix.name="costMatrix"){ - - pt = pmatch(matrix.name,c("costMatrix", "localMatrix", "timeWeight")) - if(is.na(pt)) - stop("matrix.name is not costMatrix, localMatrix, or timeWeight") - - legend_name = c("Accumulated cost", "Local cost", "Time weight")[pt] - - x = subset(x, timeseries.labels[1], patterns.labels) - y = as.character(labels(x)$patterns) - ## Get data - internals = getInternals(x)[[1]] - if(any(sapply(internals, function(x) length(x$internals))<1)) - stop("Plot methods requires internals, set keep=TRUE on twdtwApply() call") - ts = getTimeSeries(x)[[1]] - patterns = getPatterns(x) - - # Get cost matrix - df.m = do.call("rbind", lapply(y, function(p){ - tx = index(ts) - ty = index(shiftDates(patterns[[p]], year=2005)) - m = internals[[p]]$internals[[matrix.name]] - res = melt(m) - names(res) = c("Var1","Var2","value") - res$Pattern = p - res$tx = tx - res$ty = ty - res - })) - - ## Set axis breaks and labels - x.labels = pretty_breaks()(range(df.m$tx, na.rm = TRUE)) - timeline = unique( c(df.m$tx, x.labels) ) - x.breaks = zoo( c(unique(df.m$Var2), rep(NA, length(x.labels))), order.by = timeline ) - x.breaks = na.approx(x.breaks, rule = 2) - x.axis = data.frame(x.breaks=x.breaks[x.labels], x.labels = names(x.labels)) - - fact = 0 - for(i in seq_along(y)[-1]) fact[i] = fact[i-1] + max(df.m$Var1[df.m$Pattern==y[i]]) - df.m$Var3 = df.m$Var1 + unlist(lapply(seq_along(y), function(i) rep(fact[i], length(which(df.m$Pattern==y[i])) ))) - - y.axis = do.call("rbind", lapply(y, function(p){ - df = df.m[df.m$Pattern==p,] - y.labels = pretty_breaks()(range(df$ty, na.rm = TRUE)) - timeline <- unique(merge(unique(df[,c("ty","Var3")]), data.frame(ty = y.labels[drop = FALSE]), by.x = "ty", by.y = "ty", all.x = TRUE, all.y = TRUE)) - y.breaks <- zoo(timeline$Var3, order.by = timeline$ty) - y.breaks = na.approx(y.breaks, rule = 2) - y.breaks = y.breaks[y.labels] - data.frame(y.breaks, y.labels=names(y.labels)) - })) - - # Plot - gp = ggplot(data=df.m, aes_string(y='Var3', x='Var2')) + - facet_wrap(~Pattern, scales = "free", ncol=1) + - geom_raster(aes_string(fill='value')) + - scale_fill_gradientn(name = legend_name, colours = gray.colors(100, start = 0.1, end = 1)) + - scale_x_continuous(expand = c(0, 0), breaks=x.axis$x.breaks, labels=x.axis$x.labels) + - scale_y_continuous(expand = c(0, 0), breaks=y.axis$y.breaks, labels=y.axis$y.labels) + - xlab("Time series") + - ylab("Pattern") - - gp - -} - diff --git a/R/plotDistance.R b/R/plotDistance.R deleted file mode 100644 index 0fe7136..0000000 --- a/R/plotDistance.R +++ /dev/null @@ -1,97 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting distance maps -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting TWDTW distance maps. -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwRaster}}. -#' @param time.levels A \link[base]{character} or \link[base]{numeric} -#' vector with the layers to plot. For plot type ''change'' the minimum length -#' is two. -#' @param time.labels A \link[base]{character} or \link[base]{numeric} -#' vector with the labels of the layers. It must have the same -#' length as time.levels. Default is NULL. -#' @param layers A \link[base]{character} or \link[base]{numeric} -#' vector with the layers/bands of the raster time series. -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwRaster-class}}, -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{plotArea}}, -#' \code{\link[dtwSat]{plotChanges}}, and -#' \code{\link[dtwSat]{plotDistance}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @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", mc.cores=3) -#' -#' plotDistance(r_twdtw) -#' -#' } -#' @export -plotDistance = function(x, time.levels=1, time.labels=1, layers=NULL){ - plot(x, type="distance", time.levels=time.levels, time.labels=time.labels, layers=layers) -} - -.plotDistance = function(x, layers, labels, time.label){ - - df.map = data.frame(coordinates(x), x[], stringsAsFactors=FALSE) - df.map = melt(df.map, id.vars = c("x", "y")) - df.map$variable = labels[match(as.character(df.map$variable), names(x))] - - gp = ggplot(data=df.map, aes_string(x="x", y="y")) + - geom_raster(aes_string(fill="value")) + - scale_fill_gradient(name="TWDTW distance", low="blue", high="red") + - facet_wrap(~variable) + - scale_y_continuous(expand = c(0, 0), breaks = NULL) + - scale_x_continuous(expand = c(0, 0), breaks = NULL) + - theme(legend.position = "bottom") + - coord_fixed(ratio = 1) + - xlab("") + - ylab("") + - #xlab("Longitude") + - #ylab("Latitude") + - ggtitle(time.label) - gp - -} - - diff --git a/R/plotMapSamples.R b/R/plotMapSamples.R deleted file mode 100644 index dbf5aee..0000000 --- a/R/plotMapSamples.R +++ /dev/null @@ -1,48 +0,0 @@ - -#' @title Plotting maps -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting maps and samples. -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwAssessment}}. -#' @param samples A character defining the samples to plot -#' "correct", "incorrect", "all". Default is "all". -#' @param ... Other arguments to pass to \code{\link[dtwSat]{twdtwRaster}} -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwAssessment}}, -#' \code{\link[dtwSat]{plotAccuracy}}, and -#' \code{\link[dtwSat]{plotAdjustedArea}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @example examples/test_twdtw_raster_analysis.R -#' @export -plotMapSamples = function(x, samples="all", ...){ - .plotMapSamples(x, samples, ...) -} - -.plotMapSamples = function(x, samples){ - - x.sp = switch(samples, - all = x@data, - correct = x@data[x@data$Predicted == x@data$Reference, ], - incorrect = x@data[x@data$Predicted != x@data$Reference, ]) - - gp = plot(x@map, type="maps") - - - df = data.frame(x.sp) - df$variable = gp$data[match(df$Period, gp$data$rast.layer),"variable"] - df$variable = as.numeric(format(as.Date(df$to), "%Y")) - - gp = gp + geom_point(shape = 1, data = df, aes_string(x = "longitude", y = "latitude")) + - scale_shape(solid = FALSE) - gp - -} diff --git a/R/plotMaps.R b/R/plotMaps.R deleted file mode 100644 index 9c69dc8..0000000 --- a/R/plotMaps.R +++ /dev/null @@ -1,103 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting maps -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting time series of maps. -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwRaster}}. -#' @param time.levels A \link[base]{character} or \link[base]{numeric} -#' vector with the layers to plot. For plot type ''change'' the minimum length -#' is two. -#' @param time.labels A \link[base]{character} or \link[base]{numeric} -#' vector with the labels of the layers. It must have the same -#' length as time.levels. Default is NULL. -#' @param class.levels A \link[base]{character} or \link[base]{numeric} -#' vector with the levels of the raster values. Default is NULL. -#' @param class.labels A \link[base]{character} or \link[base]{numeric} -#' vector with the labels of the raster values. It must have the same -#' length as class.levels. Default is NULL. -#' @param class.colors A set of aesthetic values. It must have the same -#' length as class.levels. Default is NULL. See -#' \link[ggplot2]{scale_fill_manual} for details. -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwRaster-class}}, -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{plotArea}}, -#' \code{\link[dtwSat]{plotChanges}}, and -#' \code{\link[dtwSat]{plotDistance}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @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", mc.cores=3) -#' -#' r_lucc = twdtwClassify(r_twdtw, format="GTiff", overwrite=TRUE) -#' -#' plotMaps(r_lucc) -#' -#' } -#' @export -plotMaps = function(x, time.levels=NULL, time.labels=NULL, class.levels=NULL, class.labels=NULL, class.colors=NULL){ - plot(x, type="maps", time.levels=time.levels, time.labels=time.labels, class.levels=class.levels, class.labels=class.labels, class.colors=class.colors) -} - -.plotMaps = function(x, time.levels, time.labels, class.levels, class.labels, class.colors){ - - df.map = data.frame(coordinates(x), x[], stringsAsFactors=FALSE) - df.map = melt(df.map, id.vars = c("x", "y")) - df.map$value = factor(df.map$value, levels = class.levels, labels = class.labels) - df.map$rast.layer = seq_along(time.levels)[match(as.character(df.map$variable), time.levels)] - df.map$rast.level = time.levels[match(as.character(df.map$variable), time.levels)] - df.map$variable = time.labels[match(as.character(df.map$variable), time.levels)] - - gp = ggplot(data=df.map, aes_string(x="x", y="y")) + - geom_raster(aes_string(fill="value")) + - scale_fill_manual(name="Legend", values = class.colors) + - facet_wrap(~variable) + - scale_y_continuous(expand = c(0, 0), breaks = NULL) + - scale_x_continuous(expand = c(0, 0), breaks = NULL) + - theme(legend.position = "bottom") + - coord_fixed(ratio = 1) + - xlab("") + - ylab("") - gp - -} diff --git a/R/plotMatches.R b/R/plotMatches.R deleted file mode 100644 index 11a6825..0000000 --- a/R/plotMatches.R +++ /dev/null @@ -1,150 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting matching points -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting the matching points from -#' TWDTW analysis. -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwMatches}}. -#' @param timeseries.labels The label or index of the time series. -#' Default is 1. -#' @param patterns.labels A vector with labels of the patterns. If not -#' declared the function will plot one alignment for each pattern. -#' @param k A positive integer. The index of the last alignment to include in -#' the plot. If not declared the function will plot the best match for -#' each pattern. -#' @param attr An \link[base]{integer} or \link[base]{character} vector -#' indicating the attribute for plotting. Default is 1. -#' @param shift A number that shifts the pattern position in the \code{x} -#' direction. Default is 0.5. -#' @param show.dist Show the distance for each alignment. Default is FALSE. -#' @docType methods -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{plotPaths}}, -#' \code{\link[dtwSat]{plotCostMatrix}}, -#' \code{\link[dtwSat]{plotAlignments}}, and -#' \code{\link[dtwSat]{plotClassification}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' log_fun = logisticWeight(-0.1, 100) -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) -#' -#' plotMatches(mat1) -#' -#' plotMatches(mat1, patterns.labels="Soybean", k=4) -#' -#' plotMatches(mat1, patterns.labels=c("Soybean","Maize"), k=4) -#' -#' plotMatches(mat1, patterns.labels=c("Soybean","Cotton"), k=c(3,1)) -#' -#' @export -plotMatches = function(x, timeseries.labels=1, patterns.labels=NULL, k=1, attr=1, shift=0.5, show.dist=FALSE){ - - x = subset(x, timeseries.labels[1], patterns.labels) - ## Get data - internals = getInternals(x)[[1]] - if(any(sapply(internals, function(x) length(x$internals))<1)) - stop("Plot methods requires internals, set keep=TRUE on twdtwApply() call") - matching = getMatches(x)[[1]] - alignments = getAlignments(x)[[1]] - ts = getTimeSeries(x)[[1]] - patterns = getPatterns(x) - - y = as.character(labels(x)$patterns) - if(length(k)==1){ - y = rep(y, each=k) - k = unlist(lapply(table(y), function(i) seq(from=1, to=i) )) - } - if(length(y)!=length(k)) - stop("If length of k greater than 1, then patterns.labels must have the same length as k.") - - xx = ts[,attr,drop=FALSE] - tx = index(xx) - - y.labels = pretty_breaks()(range(xx, na.rm = TRUE)) - y.breaks = y.labels - - # Get time series - df.x = data.frame(Time=tx, xx) - - # Build matching points data.frame - df.list = lapply(seq_along(y), function(i){ - p = y[i] - yy = patterns[[p]][,attr,drop=FALSE] - ty = index(yy) - - if(k[i]>alignments[[p]]$K){ - warning("Alignment index out of bounds", call. = TRUE) - return(NULL) - } - - map = data.frame(matching[[p]]$matching[[k[i]]]) - delay = tx[map$index2[1]]-ty[1] - if(delay>0) - delay = delay + diff(range(ty, na.rm = TRUE))*shift - if(delay<0) - delay = delay - diff(range(ty, na.rm = TRUE))*shift - - df.pt = data.frame(Time=ty[map$index1]+delay, yy[map$index1,,drop=FALSE]+max(xx, na.rm = TRUE)) - df.match.pt = df.pt - df.match.pt$alig = paste(1:nrow(map),p,k[i],sep="_") - df.match.x = df.x[map$index2,] - df.match.x$alig = paste(1:nrow(map),p,k[i],sep="_") - df.match = rbind(df.match.pt, df.match.x) - df.pt$Matches = paste(p,k[i]) - df.dist = data.frame(Time=max(ty[map$index1]+delay)+diff(range(df.pt$Time))/3, - max(df.pt[,names(yy)]),Dist=alignments[[p]]$distance[k[i]]) - names(df.dist) = c("Time", names(yy), "Dist") - list(match=df.match, pt=df.pt, dist=df.dist) - }) - - df.pt = do.call("rbind", lapply(df.list, function(df) df$pt)) - df.match = do.call("rbind", lapply(df.list, function(df) df$match)) - - attr_names = names(df.x)[2] - gp = ggplot(data=df.x, aes_string(x='Time', y=eval(attr_names))) + - geom_line() + - geom_line(data=df.pt, aes_string(x='Time', y=eval(attr_names), - group='Matches', colour='Matches')) + - geom_line(data=df.match, linetype = 2, colour = "grey", - aes_string(x='Time', y=eval(attr_names), group='alig')) + - scale_y_continuous(breaks=y.breaks, labels=y.labels) + - scale_x_date(breaks=waiver(), labels=waiver()) + - ylab(attr_names) - - if(show.dist){ - df.dist = do.call("rbind", lapply(df.list, function(df) df$dist)) - df.dist$Dist = paste("Distance:",round(df.dist$Dist,2)) - gp = gp + geom_text(data=df.dist, mapping = aes_string(x='Time', y=eval(attr_names), label='Dist')) - } - - gp -} - - diff --git a/R/plotPaths.R b/R/plotPaths.R deleted file mode 100644 index 00c3052..0000000 --- a/R/plotPaths.R +++ /dev/null @@ -1,129 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting paths -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting low cost paths in the TWDTW -#' cost matrix. -#' -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwMatches}}. -#' @param timeseries.labels The label or index of the time series. -#' Default is 1. -#' @param patterns.labels A vector with labels of the patterns. If not -#' declared the function will plot one alignment for each pattern. -#' @param k A positive integer. The index of the last alignment to include in -#' the plot. If not declared the function will plot all low cost paths. -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{plotAlignments}}, -#' \code{\link[dtwSat]{plotCostMatrix}}, -#' \code{\link[dtwSat]{plotMatches}}, and -#' \code{\link[dtwSat]{plotClassification}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' log_fun = logisticWeight(-0.1, 100) -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) -#' -#' plotPaths(mat1) -#' -#' plotPaths(mat1, patterns.labels="Soybean", k=1:2) -#' -#' plotPaths(mat1, patterns.labels=c("Maize","Cotton"), k=2) -#' -#' @export -plotPaths = function(x, timeseries.labels=NULL, patterns.labels=NULL, k=NULL){ - - x = subset(x, timeseries.labels[1], patterns.labels, k) - y = as.character(labels(x)$patterns) - ## Get data - internals = getInternals(x)[[1]] - if(any(sapply(internals, function(x) length(x$internals))<1)) - stop("Plot methods requires internals, set keep=TRUE on twdtwApply() call") - matching = getMatches(x)[[1]] - ts = getTimeSeries(x)[[1]] - patterns = getPatterns(x) - - # Get cost matrix - df.m = do.call("rbind", lapply(y, function(p){ - tx = index(ts) - ty = index(shiftDates(patterns[[p]], year=2005)) - m = internals[[p]]$internals$costMatrix - res = melt(m) - names(res) = c("Var1","Var2","value") - res$Pattern = p - res$tx = tx - res$ty = ty - res - })) - - # Get minimun cost paths - df.path = do.call("rbind", lapply(y, function(p){ - res = do.call("rbind", lapply(seq_along(matching[[p]]$matching), function(i) - data.frame(matching[[p]]$matching[[i]], alignment=i) - )) - res$Pattern = p - res - })) - - ## Set axis breaks and labels - x.labels = pretty_breaks()(range(df.m$tx, na.rm = TRUE)) - timeline = unique( c(df.m$tx, x.labels) ) - x.breaks = zoo( c(unique(df.m$Var2), rep(NA, length(x.labels))), timeline ) - x.breaks = na.approx(x.breaks, rule = 2) - x.axis = data.frame(x.breaks=x.breaks[x.labels], x.labels = names(x.labels)) - - fact = 0 - for(i in seq_along(y)[-1]) fact[i] = fact[i-1] + max(df.m$Var1[df.m$Pattern==y[i]]) - df.m$Var3 = df.m$Var1 + unlist(lapply(seq_along(y), function(i) rep(fact[i], length(which(df.m$Pattern==y[i])) ))) - df.path$Var3 = df.path$index1 + unlist(lapply(seq_along(y), function(i) rep(fact[i], length(which(df.path$Pattern==y[i])) ))) - - y.axis = do.call("rbind", lapply(y, function(p){ - df = df.m[df.m$Pattern==p,] - y.labels = pretty_breaks()(range(df$ty, na.rm = TRUE)) - timeline <- unique(merge(unique(df[,c("ty","Var3")]), data.frame(ty = y.labels[drop = FALSE]), by.x = "ty", by.y = "ty", all.x = TRUE, all.y = TRUE)) - y.breaks <- zoo(timeline$Var3, order.by = timeline$ty) - y.breaks = na.approx(y.breaks, rule = 2) - y.breaks = y.breaks[y.labels] - data.frame(y.breaks, y.labels=names(y.labels)) - })) - - # Plot - gp = ggplot(data=df.m, aes_string(y='Var3', x='Var2')) + - facet_wrap(~Pattern, scales = "free", ncol=1) + - geom_raster(aes_string(fill='value')) + - scale_fill_gradientn(name = 'Warping cost', colours = terrain.colors(100)) + - geom_path(data=df.path, aes_string(y='Var3', x='index2', group='alignment')) + - scale_x_continuous(expand = c(0, 0), breaks=x.axis$x.breaks, labels=x.axis$x.labels) + - scale_y_continuous(expand = c(0, 0), breaks=y.axis$y.breaks, labels=y.axis$y.labels) + - xlab("Time series") + - ylab("Pattern") - - gp - -} - diff --git a/R/plotTimeSeries.R b/R/plotTimeSeries.R deleted file mode 100644 index f8f05cf..0000000 --- a/R/plotTimeSeries.R +++ /dev/null @@ -1,82 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @title Plotting time series -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Method for plotting the temporal patterns. -#' -#' @param x An object of class \code{\link[dtwSat]{twdtwTimeSeries}}, -#' \code{\link[zoo]{zoo}}, or list of class \code{\link[zoo]{zoo}}. -#' @param labels A vector with labels of the time series. If missing, all -#' elements in the list will be plotted (up to a maximum of 16). -#' @param attr An \link[base]{integer} vector or \link[base]{character} vector -#' indicating the attribute for plotting. If not declared the function will plot -#' all attributes. -#' -#' @return A \link[ggplot2]{ggplot} object. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwTimeSeries-class}} and -#' \code{\link[dtwSat]{plotPatterns}} -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' plotTimeSeries(ts) -#' plotTimeSeries(ts, attr="evi") -#' -#' @export -plotTimeSeries = function(x, labels=NULL, attr){ - - if(is(x, "twdtwMatches")) x = subset(x@timeseries, labels) - if(is(x, "twdtwTimeSeries")) x = subset(x, labels) - if(is.null(labels)) labels = labels(x) - new_labels = labels(x) - labels_tabel = table(new_labels) - if(any(labels_tabel>1)) - for(p in names(labels_tabel)){ - i = p==labels(x) - new_labels[i] = paste(new_labels[i], 1:labels_tabel[p]) - } - x = twdtwTimeSeries(x@timeseries, labels=new_labels) - labels = new_labels - if(length(labels)>16) labels = labels[1:16] - - # Build data.frame - if(missing(attr)) attr = names(x[[1]]) - df.p = do.call("rbind", lapply(as.list(x), function(xx){ - ts = xx[[1]][,attr,drop=FALSE] - data.frame(Time=index(ts), ts, Series=labels(xx)[1]) - })) - df.p = melt(df.p, id.vars=c("Time","Series")) - - # Plot time series - gp = ggplot(df.p, aes_string(x="Time", y="value", colour="variable") ) + - geom_line() + - theme(legend.position = "bottom") + - facet_wrap(~Series, scales = "free_x", ncol=1) + - guides(colour = guide_legend(title = "Bands")) + - ylab("Value") - - gp - -} - - diff --git a/R/plotPatterns.R b/R/plot_patterns.R similarity index 60% rename from R/plotPatterns.R rename to R/plot_patterns.R index 5bb6bd6..5c8860d 100644 --- a/R/plotPatterns.R +++ b/R/plot_patterns.R @@ -1,18 +1,3 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - #' @title Plotting temporal patterns #' @author Victor Maus, \email{vwmaus1@@gmail.com} #' @@ -39,16 +24,9 @@ #' #' \insertRef{Maus:2016}{dtwSat} #' -#' @examples -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' plotPatterns(patt) -#' plotPatterns(patt, attr="evi") -#' #' @export -plotPatterns = function(x, labels=NULL, attr, year=2005){ +plot_patterns = function(x, labels=NULL, attr, year=2005){ - if(is(x, "twdtwMatches")) x = x@patterns - if(is(x, "twdtwTimeSeries")) x = subset(x, labels) x = twdtwTimeSeries(x, labels) labels = labels(x) diff --git a/R/resampleTimeSeries.R b/R/resampleTimeSeries.R deleted file mode 100644 index d310a9f..0000000 --- a/R/resampleTimeSeries.R +++ /dev/null @@ -1,64 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-02-22 # -# # -############################################################### - - -#' @title Resample time series -#' @name resampleTimeSeries -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Resample time series in the object to have the same length. -#' -#' @inheritParams twdtwTimeSeries-class -#' @param length An integer. The number of samples to resample the time series to. -#' If not declared the length is set to the length of the longest time series. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwTimeSeries-class}}, and -#' \code{\link[dtwSat]{twdtwApply}} -#' -#' @return An object of class \code{\link[dtwSat]{twdtwTimeSeries}} whose -#' time series have the same number of samples (points). -#' -#' @export -setGeneric("resampleTimeSeries", function(object, length=NULL) standardGeneric("resampleTimeSeries")) - -#' @rdname resampleTimeSeries -#' @aliases resampleTimeSeries-twdtwMatches -#' @examples -#' # Resampling time series from objects of class twdtwTimeSeries -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' npatt = resampleTimeSeries(patt, length=46) -#' nrow(patt) -#' nrow(npatt) -#' -#' @export -setMethod("resampleTimeSeries", "twdtwTimeSeries", - function(object, length) { - if(is.null(length)) length = max(nrow(object), na.rm=TRUE) - twdtwTimeSeries(lapply(object[], resampleTimeSeries.twdtwTimeSeries, length=length), labels=labels(object)) - }) - -resampleTimeSeries.twdtwTimeSeries = function(x, length){ - #labels = as.character(labels(x)) - dates = index(x) - freq = trunc(as.numeric(diff(range(dates)))/(length-1)) - timeline = seq(min(dates, na.rm = TRUE), max(dates, na.rm = TRUE), by=freq) - zoo(data.frame(na.spline(x, xout = timeline)), timeline) -} - - - - - - diff --git a/R/subset.R b/R/subset.R deleted file mode 100644 index f834e33..0000000 --- a/R/subset.R +++ /dev/null @@ -1,171 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-02-18 # -# # -############################################################### - -#' @title Subset time series -#' @name subset -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Get subsets from objects of class twdtw*. -#' -#' @inheritParams get -#' @param x An objects of class twdtw*. -#' -#' @param k A positive integer. The index of the last alignment to include in -#' the subset. -#' -#' @param e An extent object, or any object from which an Extent object can -#' be extracted. See \link[raster]{crop} for details. -#' -#' @param layers A vector with the names of the \code{twdtwRaster} object to include in -#' the subset. -#' -#' @param labels A character vector with time series labels. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwRaster-class}}, -#' \code{\link[dtwSat]{twdtwTimeSeries-class}}, and -#' \code{\link[dtwSat]{twdtwMatches-class}} -#' -#' @return An object of class twdtw*. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' # Getting time series from objects of class twdtwTimeSeries -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' ts = subset(ts, 2) -#' ts -#' # Getting time series from objects of class twdtwTimeSeries -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' mat = twdtwApply(x=ts, y=patt, weight.fun=logisticWeight(-0.1,100), -#' keep=TRUE, legacy=TRUE) -#' mat = subset(mat, k=4) -#' -#' ## This example creates a twdtwRaster object and extracts time series from it. -#' -#' # Creating objects of class twdtwRaster with evi and ndvi time series -#' evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) -#' ndvi = brick(system.file("lucc_MT/data/ndvi.tif", package="dtwSat")) -#' timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") -#' rts = twdtwRaster(evi, ndvi, timeline=timeline) -#' -#' rts_evi = subset(rts, layers="evi") -#' -#' field_samples = read.csv(system.file("lucc_MT/data/samples.csv", package="dtwSat")) -#' prj_string = scan(system.file("lucc_MT/data/samples_projection", package="dtwSat"), -#' what = "character") -#' -#' # Extract time series -#' ts_evi = getTimeSeries(rts_evi, y = field_samples, proj4string = prj_string) -#' -#' # Subset all labels = "Forest" -#' ts_forest = subset(ts_evi, labels="Forest") -#' -NULL - -#' @aliases subset-twdtwTimeSeries -#' @inheritParams subset -#' @rdname subset -#' @export -setMethod("subset", "twdtwTimeSeries", function(x, labels=NULL) - subset.twdtwTimeSeries(x=x, labels=labels)) - - -subset.twdtwTimeSeries = function(x, labels){ - if(is.null(labels)) labels = labels(x) - if(is.numeric(labels)) return(twdtwTimeSeries(x@timeseries[labels], labels=x@labels[labels])) - I = which(!is.na(match(x@labels, labels))) - if(length(I)<1) return(new("twdtwTimeSeries")) - twdtwTimeSeries(x@timeseries[I], labels=x@labels[I]) -} - - -#' @aliases subset-twdtwMatches -#' @inheritParams subset -#' @rdname subset -#' @export -setMethod("subset", "twdtwMatches", function(x, timeseries.labels=NULL, patterns.labels=NULL, k=NULL) - subset.twdtwMatches(x=x, timeseries.labels=timeseries.labels, patterns.labels=patterns.labels, k=k) ) - - -subset.twdtwMatches = function(x, timeseries.labels, patterns.labels, k){ - if(is.null(timeseries.labels)) timeseries.labels = as.character(labels(x@timeseries)) - if(is.null(patterns.labels)) patterns.labels = as.character(labels(x@patterns)) - if(is.null(k)) k = 1:length(x) - k = unique(k) - I = timeseries.labels - J = patterns.labels - if(is.character(I)) I = which(!is.na(match(x@timeseries@labels, timeseries.labels))) - if(is.character(J)) J = which(!is.na(match(x@patterns@labels, patterns.labels))) - timeseries = subset(x@timeseries, labels=I) - patterns = subset(x@patterns, labels=J) - names(J) = labels(patterns) - alignments = lapply(I, function(i){ - out = lapply(J, function(j){ - res = x@alignments[[i]][[j]] - k = k[ k<=res$K ] - res$K = length(k) - res$from = res$from[k] - res$to = res$to[k] - res$distance = res$distance[k] - if(length(k)<1) res$label = numeric(0) - if(length(res$matching)>length(k)) res$matching = res$matching[k] - res - }) - # names(out) = patterns.labels - out - }) - twdtwMatches(timeseries=timeseries, patterns=patterns, alignments=alignments) -} - -#' @aliases subset-twdtwRaster -#' @inheritParams subset -#' @rdname subset -#' @export -setMethod("subset", "twdtwRaster", function(x, e=NULL, layers=NULL) - subset.twdtwRaster(x=x, e=e, layers=layers) ) - -subset.twdtwRaster = function(x, e, layers){ - if(is.null(layers)) - layers = names(x) - if(is.null(e)) - e = extent(x) - res = x - res@layers = layers - res@timeseries = res@timeseries[layers] - res@timeseries = lapply(res@timeseries, crop, y=e) - res -} - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/R/twdtw.R b/R/twdtw.R deleted file mode 100644 index daa97f4..0000000 --- a/R/twdtw.R +++ /dev/null @@ -1,164 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-02-22 # -# # -############################################################### - -.twdtw = function(x, y, weight.fun, dist.method, step.matrix, - n, span, min.length, keep){ - labels = as.character(labels(y)) - names(labels) = labels - timeseries = x[[1]] - # Remove possible NA values - timeseries = timeseries[!apply(is.na(timeseries), 1, all),,drop=FALSE] - - fun = function(l){ - pattern = y[[l]] - # Adjust columns by name if possible - #pattern = pattern[,!is.na(match(names(pattern), names(timeseries)))] - #timeseries = timeseries[,!is.na(match(names(timeseries), names(pattern)))] - - # Get day of the year - ty = index(pattern) - tx = index(timeseries) - doyy = as.numeric(format(index(pattern), "%j")) - doyx = as.numeric(format(index(timeseries), "%j")) - - - # Compute local cost matrix - phi = dist(pattern, timeseries, method=dist.method) - # Time cost matrix - psi = .g(dist(doyy, doyx, method=dist.method)) - # Weighted local cost matrix - cm = weight.fun(phi, psi) - # Compute cost matris - # xm = na.omit(cbind(doyx, as.matrix(timeseries))) - # ym = na.omit(cbind(doyy, as.matrix(pattern))) - # internals = .computecost_fast(xm, ym, step.matrix) - internals = .computecost(cm, step.matrix) - internals$timeWeight = matrix(psi, nrow = nrow(psi)) - internals$localMatrix = matrix(cm, nrow = nrow(cm)) - - # Find low cost candidates - d = internals$costMatrix[internals$N,1:internals$M] - a = internals$startingMatrix[internals$N,1:internals$M] - if(is.null(span)){ - candidates = data.frame(a, d) - candidates = candidates[ candidates$d==ave(candidates$d, candidates$a, FUN=min), ] - candidates$b = as.numeric(row.names(candidates)) - } - else { - b = .findMin(d, tx, span = span) - candidates = data.frame(a[b], d[b], b) - } - - # Order maches by similarity - I = order(candidates$d) - if(length(I)<1) return(NULL) - - # Select alignments - if(is.null(n)) n = length(I) - if(length(I) > n) I = I[1:n] - - # Remove overfit - I = I[diff(range(ty))*min.length <= tx[candidates$b[I]] - tx[candidates$a[I]]] - - alignments = initAlignments() - if(length(I)<1) return(alignments) - - alignments$label = labels[l] - alignments$from = tx[candidates$a[I]] # This is a vector of Dates - alignments$to = tx[candidates$b[I]] # This is a vector of Dates - alignments$distance = candidates$d[I] # This is a numeric vector - alignments$K = length(I) # This is an integer - alignments$matching = list() # This is a list of data.frames with the matching points - alignments$internals = list() # These is a list variables used in the TWDTW computation - if(alignments$K<1) alignments$label = numeric(0) - - if(keep){ - # Trace low cost paths (k-th paths) - alignments$matching = .tracepath(dm=internals$directionMatrix, step.matrix=step.matrix, jmin=candidates$b[I]) - alignments$internals = internals - } - alignments - } - - res = NULL - - if(length(timeseries)>3) - res = try(lapply(seq_along(labels), FUN=fun)) - - if(is(res, "try-error") | is.null(res)) - res = lapply(labels, function(l) list(label = numeric(0), from = numeric(0), to = numeric(0), distance = numeric(0), K = numeric(0), matching = list(), internals = list())) - - names(res) = labels - res -} - -initAlignments = function(...){ - list( - label = numeric(0), - from = numeric(0), - to = numeric(0), - distance = numeric(0), - K = 0, - matching = list(), - internals = list() - ) -} - -.findMin = function(x, timeline, span){ - NonNA = which(!is.na(x)) - dx = diff(x[NonNA]) - index_min = NonNA[which(dx[-length(dx)] < 0 & dx[-1] >= 0)] + 1 - if(tail(dx,1) < 0) - index_min = c(index_min,length(x)) - order_min = index_min[order(x[index_min])] - min_out = array() - for(i in seq_along(index_min)){ - min_out[i] = order_min[i] - lower_bound = timeline[order_min[i]] - span - upper_bound = timeline[order_min[i]] + span - in_span = lower_bound <= timeline[order_min] & timeline[order_min] <= upper_bound - order_min[in_span] = NA - } - res = min_out[!is.na(min_out)] - res -} - -.removeConcurrent = function(I, startPoints, endPoints, d){ - res = !(I | duplicated(startPoints, fromLast = TRUE)) - J = unlist(lapply(unique(startPoints[!res]), function(i){ - J = which(startPoints==i) - min_j = rep(FALSE, length(J)) - min_j[which.min(d[endPoints[J]])] = TRUE - min_j - })) - res[!res] = J - res -} - -# @useDynLib dtwSat g -.g = function(phi, step.matrix){ - - if(!is.loaded("g", PACKAGE = "dtwSat", type = "Fortran")) - stop("Fortran lib is not loaded") - - n = nrow(phi) - m = ncol(phi) - res = .Fortran(g, - TM = matrix(as.double(phi), n, m), - N = as.integer(n), - M = as.integer(m), - PC = as.double(366)) - res$TM -} - diff --git a/R/twdtwApply.R b/R/twdtwApply.R deleted file mode 100644 index b27e4ae..0000000 --- a/R/twdtwApply.R +++ /dev/null @@ -1,513 +0,0 @@ -#' @include methods.R -#' @title Apply TWDTW analysis -#' @name twdtwApply -#' @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 \insertCite{Maus:2019}{dtwSat}. -#' -#' @inheritParams twdtwClassify -#' -#' @param x An object of class twdtw*. This is the target time series. -#' Usually, it is a set of unclassified time series. -#' -#' @param y An object of class \link[dtwSat]{twdtwTimeSeries}. -#' The temporal patterns. -#' -#' @param ... Arguments to pass to \code{\link[raster]{writeRaster}} and -#' \code{\link[raster]{pbCreate}} -#' -#' @param resample Resample the patterns to have the same length. Default is TRUE. -#' See \link[dtwSat]{resampleTimeSeries} for details. -#' -#' @param length An integer. Length of patterns used with \code{patterns.length}. -#' If not declared the length of the output patterns will be the length of -#' the longest pattern. -#' -#' @param weight.fun A function. Any function that receives two matrices and -#' performs a computation on them, returning a single matrix with the same -#' dimensions. The first matrix is the DTW local cost matrix and the -#' second a matrix of the time differences in days. The function should return a -#' matrix of DTW local cost weighted by the time differences. If not declared -#' the time-weight is zero. In this case the function runs the standard version -#' of the dynamic time warping. See details. -#' -#' @param dist.method A character. Method to derive the local cost matrix. -#' Default is ''Euclidean'' see \code{\link[proxy]{dist}} in package -#' \pkg{proxy}. -#' -#' @param step.matrix See \code{\link[dtw]{stepPattern}} in package \pkg{dtw} -#' \insertCite{Giorgino:2009}{dtwSat}. -#' -#' @param n An integer. The maximun number of matches to perform. -#' NULL will return all matches. -#' -#' @param keep Preserves the cost matrix, inputs, and other internal structures. -#' Default is FALSE. For plot methods use \code{keep=TRUE}. -#' -#' @param span A number. Span between two matches, \emph{i.e.} the minimum -#' interval between two matches; for details see \insertCite{Muller:2007}{dtwSat}. -#' If not declared it removes all overlapping matches of the same pattern. To include -#' overlapping matches of the same pattern use \code{span=0}. -#' -#' @param min.length A number between 0 an 1. This argument removes overfittings. -#' Minimum length after warping. Percentage of the original pattern length. Default is 0.5, -#' meaning that the matching cannot be shorter than half of the pattern length. -#' -#' @param filepath A character. The path at which to save the raster with results. If not provided the -#' function saves in the current work directory. -#' -#' @param minrows Integer. Minimum number of rows in each block -#' -#' @param progress character. 'text' or 'window'. -#' -#' @param legacy logical. If FALSE, runs a faster new TWDTW implementation. Default FLASE -#' -#' @param alpha Numeric. The steepness of TWDTW logistic weight. -#' -#' @param beta Numeric. The midpoint of TWDTW logistic weight. -#' -#' @references -#' \insertAllCited{} -#' -#' @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 for analyzing time series with phenological cycles -#' of vegetation that are usually bound to seasons. In previous studies by -#' \insertCite{Maus:2016}{dtwSat} the logistic weight had better results than the -#' linear for land cover classification. -#' See \insertCite{Maus:2016,Maus:2019}{dtwSat} for details about the method. -#' -#' @return An object of class twdtw*. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{twdtwTimeSeries-class}}, -#' \code{\link[dtwSat]{twdtwRaster-class}}, -#' \code{\link[dtwSat]{getTimeSeries}}, and -#' \code{\link[dtwSat]{createPatterns}} -#' -#' @export -setGeneric(name = "twdtwApply", - def = function(x, y, resample=TRUE, length=NULL, weight.fun=function(phi, psi) phi, - dist.method="Euclidean", step.matrix = symmetric1, n=NULL, - span=NULL, min.length=0, ...) standardGeneric("twdtwApply")) - -#' @rdname twdtwApply -#' @aliases twdtwApply-twdtwTimeSeries -#' @examples -#' # Applying TWDTW analysis to objects of class twdtwTimeSeries -#' log_fun = logisticWeight(-0.1, 100) -#' ts = twdtwTimeSeries(MOD13Q1.ts.list) -#' patt = twdtwTimeSeries(MOD13Q1.patterns.list) -#' mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) -#' mat1 -#' -#' \dontrun{ -#' # Parallel processin -#' require(parallel) -#' mat_list = mclapply(as.list(ts), mc.cores=2, FUN=twdtwApply, y=patt, weight.fun=log_fun) -#' mat2 = twdtwMatches(alignments=mat_list) -#' } -#' @export -setMethod(f = "twdtwApply", "twdtwTimeSeries", - def = function(x, y, resample, length, weight.fun, dist.method, step.matrix, n, span, min.length, legacy=FALSE, keep=FALSE, ...){ - if(!is(y, "twdtwTimeSeries")) - stop("y is not of class twdtwTimeSeries") - 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(resample) - y = resampleTimeSeries(object=y, length=length) - if(legacy){ - twdtwApply.twdtwTimeSeries(x, y, weight.fun, dist.method, step.matrix, n, span, min.length, keep) - } else { - twdtwApply.twdtwTimeSeries.fast(x, y, ...) - } - - }) - -twdtwApply.twdtwTimeSeries.fast = function(x, y, ...){ - yy = lapply(y@timeseries, function(ts)cbind(data.frame(date = index(ts)), as.data.frame(ts))) - xm = lapply(x@timeseries, function(ts)twdtwReduceTime(cbind(data.frame(date = index(ts)), as.data.frame(ts)), keep = FALSE, y = yy, ...)) - lb = as.numeric(labels(y@labels)) - lv = levels(y) - names(lb) = lv - list(x = x, y = y, aligs = lapply(xm, function(al) lapply(lb, function(i){ - bm = list(label = numeric(), - from = numeric(), - to = numeric(), - distance = numeric(), - K = 0, - matching = list(), - internals = list()) - if(!any(al$label == i)){ - return(bm) - } - bm$label = lv[i] - bm$from = al$from[al$label == i] - bm$to = al$to[al$label == i] - bm$distance = al$distance[al$label == i] - bm$K = length(bm$distance) - return(bm) - }))) -} - -twdtwApply.twdtwTimeSeries = function(x, y, weight.fun, dist.method, step.matrix, n, span, min.length, keep){ - res = lapply(as.list(x), FUN = .twdtw, y, weight.fun, dist.method, step.matrix, n, span, min.length, keep) - new("twdtwMatches", timeseries=x, patterns=y, alignments=res) -} - -#' @rdname twdtwApply -#' @aliases twdtwApply-twdtwRaster -#' @example examples/test_twdtw_raster_analysis.R -#' @export -setMethod(f = "twdtwApply", "twdtwRaster", - def = function(x, y, resample, length, weight.fun, dist.method, step.matrix, n, span, min.length, - breaks=NULL, from=NULL, to=NULL, by=NULL, overlap=0.5, filepath="", fill=NULL, - legacy=FALSE, progress = "text", minrows=1, alpha = -0.1, beta = 50, ...){ - 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(to0) datasets = lapply(datasets, function(x) x[-k] ) - - # Build multi-band zoo object - zoo(data.frame(datasets[-idoy]), order.by = datasets$doy) -} - -# Match and set a list of arguments to a function -.setFunArgs = function(fun, ..., args = list(...)){ - base_formals = formals(fun) - base_formals_names = names(base_formals) - given_formals = args[names(args) %in% base_formals_names] - missing_formals_names = setdiff(base_formals_names, names(args)) - new_formals = c(base_formals[missing_formals_names], given_formals) - new_formals = new_formals[base_formals_names] - formals(fun) = new_formals - fun -} diff --git a/R/twdtwAssess.R b/R/twdtwAssess.R deleted file mode 100644 index 8799427..0000000 --- a/R/twdtwAssess.R +++ /dev/null @@ -1,359 +0,0 @@ - -setGeneric("twdtwAssess", - def = function(object, ...) standardGeneric("twdtwAssess") -) - -#' @title Assess TWDTW classification -#' @name twdtwAssess -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Performs an accuracy assessment -#' of the classified maps. The function returns Overall Accuracy, -#' User's Accuracy, Produce's Accuracy, error matrix (confusion matrix), -#' and estimated area according to \insertCite{Olofsson:2013,Olofsson:2014;textual}{dtwSat}. -#' The function returns the metrics for each time interval and a summary considering all -#' classified intervals. -#' -#' @param object An object of class \code{\link[dtwSat]{twdtwRaster}} resulting from -#' the classification, i.e. \code{\link[dtwSat]{twdtwClassify}}. -#' The argument can also receive an error matrix (confusion matrix) using the classes -#' \code{\link[base]{data.frame}} or \code{\link[base]{table}}. In this case the user -#' must provide the area for each class to the argument \code{area}. -#' -#' @param area A numeric vector with the area for each class if the argument \code{object} -#' is an error matrix (confusion matrix). If \code{object} is \code{\link[dtwSat]{twdtwMatches}} -#' area can be either a vector with the area of each classified object, or a single number -#' if the objects are single pixels. - -#' @param y A \code{\link[base]{data.frame}} whose attributes are: longitude, -#' latitude, the start ''from'' and the end ''to'' of the time interval -#' for each sample. This can also be a \code{\link[sp]{SpatialPointsDataFrame}} -#' whose attributes are the start ''from'' and the end ''to'' of the time interval. -#' If missing ''from'' and/or ''to'', they are set to the time range of the -#' \code{object}. -#' -#' @param id.labels A numeric or character with an column name from \code{y} to -#' be used as samples labels. Optional. -#' -#' @param labels Character vector with time series labels. For signature -#' \code{\link[dtwSat]{twdtwRaster}} this argument can be used to set the -#' labels for each sample in \code{y}, or it can be combined with \code{id.labels} -#' to select samples with a specific label. -#' -#' @param proj4string Projection string, see \code{\link[sp]{CRS-class}}. Used -#' if \code{y} is a \code{\link[base]{data.frame}}. -#' -#' @param conf.int Specifies the confidence level (0-1). -#' -#' @param rm.nosample If sum of columns and sum of rows of the error matrix are zero -#' then remove class. Default is TRUE. -#' -#' @param start_date A date. Required if there is only one map to be assessed. Usually this is the -#' first date of the timeline from satellite images. -#' -#' @references -#' \insertAllCited{} -#' -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @seealso \code{\link[dtwSat]{twdtwClassify}}, -#' \code{\link[dtwSat]{twdtwAssessment}}, and -#' \code{\link[dtwSat]{twdtwXtable}}. -#' -NULL - -#' @aliases twdtwAssess-twdtwRaster -#' @inheritParams twdtwAssess -#' @rdname twdtwAssess -#' @example examples/test_twdtw_raster_analysis.R -#' @export -setMethod(f = "twdtwAssess", signature = "twdtwRaster", - definition = function(object, y, labels=NULL, id.labels=NULL, proj4string=NULL, conf.int=.95, rm.nosample=FALSE, start_date=NULL) - twdtwAssess.twdtwRaster(object, y, labels, id.labels, proj4string, conf.int, rm.nosample, start_date)) - -#' @aliases twdtwAssess-data.frame -#' @inheritParams twdtwAssess -#' @rdname twdtwAssess -#' @export -setMethod(f = "twdtwAssess", signature = "data.frame", - definition = function(object, area, conf.int=.95, rm.nosample=TRUE) - twdtwAssess.table(object, area, conf.int, rm.nosample)) - -#' @aliases twdtwAssess-table -#' @inheritParams twdtwAssess -#' @rdname twdtwAssess -#' @export -setMethod(f = "twdtwAssess", signature = "table", - definition = function(object, area, conf.int=.95, rm.nosample=TRUE) - twdtwAssess(as.data.frame.matrix(object), area, conf.int, rm.nosample)) - -#' @aliases twdtwAssess-matrix -#' @inheritParams twdtwAssess -#' @rdname twdtwAssess -#' -#' @examples -#' -#' # Total mapped area by class. Data from [1] -#' area = c(A = 22353, B = 1122543, C = 610228) -#' -#' # Error matrix, columns (Reference) rows (Map) -#' x = -#' rbind( -#' c( 97, 0, 3), -#' c( 3, 279, 18), -#' c( 2, 1, 97) -#' ) -#' -#' table_assess = twdtwAssess(x, area, conf.int = .95) -#' -#' table_assess -#' -#' plot(table_assess, type="area", perc=FALSE) -#' -#' plot(table_assess, type="accuracy") -#' -#' @export -setMethod(f = "twdtwAssess", signature = "matrix", - definition = function(object, area, conf.int=.95, rm.nosample=TRUE) - twdtwAssess(as.data.frame.matrix(object), area, conf.int, rm.nosample)) - -#' @aliases twdtwAssess-twdtwMatches -#' @inheritParams twdtwAssess -#' @rdname twdtwAssess -#' @example examples/test_twdtw_raster_analysis.R -#' @export -setMethod(f = "twdtwAssess", signature = "twdtwMatches", - definition = function(object, area, conf.int=.95, rm.nosample=TRUE) - twdtwAssess.twdtwTimeSeries(object, area, conf.int, rm.nosample)) - -twdtwAssess.twdtwTimeSeries = function(object, area, conf.int, rm.nosample){ - - df = do.call("rbind", lapply(object[], function(xx) xx[which.min(xx$distance),]) ) - - ref = labels(object)$timeseries - - pred = as.character(df$label) - - data = data.frame(.adjustFactores(ref, pred, levels=NULL, labels=NULL), df[,!names(df)%in%"labels"]) - - error_matrix = table(Predicted=data$Predicted, Reference=data$Reference) - - if(length(area)==1) - a = rep(area, length(object@timeseries)) - - a = aggregate(x = a, by = list(pred), FUN = sum) - - area = a$x - - names(area) = a$Group.1 - - res = .twdtwAssess(error_matrix, area, conf.int, rm.nosample) - - new("twdtwAssessment", accuracySummary=res) -} - -twdtwAssess.table = function(object, area, conf.int, rm.nosample){ - - if(ncol(object)!=nrow(object)) - stop("object has have the same number of rows and columns") - - if(nrow(object)!=length(area)) - stop("area must have length equal to the number of rows in object") - - accuracy = .twdtwAssess(object, area, conf.int, rm.nosample) - - new("twdtwAssessment", accuracySummary=accuracy, accuracyByPeriod=accuracy) -} - -twdtwAssess.twdtwRaster = function(object, y, labels, id.labels, proj4string, conf.int, rm.nosample, start_date){ - - if(rm.nosample) - warning("The argument rm.nosample is obsolete and will be removed in the next package release") - - # Check control points - y = .adjustLabelID(y, labels, id.labels) - if(!"from"%in%names(y) || !"to"%in%names(y)) - stop("Argument 'y' must contain columns called 'to' and 'from' to locate start and end dates") - y = .toSpatialPointsDataFrame(y, object, proj4string) - - # Get classified raster - x = object@timeseries$Class - x_twdtw = object@timeseries$Distance - - # Reproject points to raster projection - y = spTransform(y, CRS(projection(object@timeseries[[1]]))) - - # Remove samples outside raster bbox - n_s <- length(y) - y <- intersect(y, x) - if(n_s > length(y)){ - warning(cat(n_s - length(y), "samples out of bounds removed")) - } - if(length(y) < 1){ - stop(cat(n_s - length(y), "samples out of bounds removed. There are no samples intersecting the study area")) - } - - # Get time intervals - timeline = index(object) - if(length(timeline) < 2){ - if(is.null(start_date)){ - stop("The classification assessment requires matching time intervals. - If there is only one map please provide the starting date of the map interval - using the argument 'start_date'") - } - timeline = c(as.Date(start_date), timeline) - } else { - timeline = c(timeline[1] - diff(timeline[1:2]) - 1, timeline) - } - - r_intervals = data.frame(from=timeline[-length(timeline)], to=timeline[-1]) - - # Get land use/cover classes - rnames = labels(object) - rlevels = levels(object) - - # Compute mapped area of each class by classification interval - a_by_interval = lapply(1:nlayers(x), FUN = .getAreaByClass, x, rlevels, rnames) - - # Compute total mapped area by class - area_by_class = do.call("rbind", a_by_interval) - area_by_class = colSums(area_by_class) - - # Get classified and predicted land cover/use classes for each control point - pred_classes = extract(x, y) - pred_distance = extract(x_twdtw, y) - samples_by_period = lapply(1:nrow(r_intervals), FUN = .getPredRefClasses, r_intervals, pred_classes, pred_distance, y, rlevels, rnames) - samples_all = do.call("rbind", samples_by_period) - - # Compute error matrix - error_matrix_by_period = lapply(1:nrow(r_intervals), function(i) table(samples_by_period[[i]][,c("Predicted","Reference")])) - error_matrix_summary = table(samples_all[,c("Predicted","Reference")]) - - # Compute accuracy assessment - accuracy_by_period = lapply(seq_along(error_matrix_by_period), function(i) - .twdtwAssess(x = error_matrix_by_period[[i]], a_by_interval[[i]], conf.int=conf.int, rm.nosample=FALSE)) - names(accuracy_by_period) = index(object) - accuracy_summary = .twdtwAssess(error_matrix_summary, area_by_class, conf.int=conf.int, rm.nosample=FALSE) - - sp.data = SpatialPointsDataFrame(coords = samples_all[,c("longitude", "latitude")], - data = samples_all[,!names(samples_all)%in%c("longitude", "latitude")], - proj4string = CRS(projection(object@timeseries[[1]]))) - - new("twdtwAssessment", accuracySummary = accuracy_summary, - accuracyByPeriod = accuracy_by_period, - data = sp.data, - map = object) - -} - -.twdtwAssess = function(x, mapped_area, conf.int, rm.nosample){ - - if(nrow(x)<1) - return(NULL) - - mult = qnorm(1-(1-conf.int)/2, mean = 0, sd = 1) - - cnames = names(mapped_area) - rownames(x) = cnames - names(x) = cnames - - total_map = rowSums(x) - total_ref = colSums(x) - total_area = sum(mapped_area) - total_samples = sum(total_ref) - - if(rm.nosample){ - I = total_ref>0 | total_map>0 - x = x[I,I] - cnames = cnames[I] - total_map = total_map[I] - total_ref = total_ref[I] - mapped_area = mapped_area[I] - total_area = sum(mapped_area) - total_samples = sum(total_ref) - } - - # Weight - w = mapped_area / total_area - - # Error matrix - error_matrix = cbind(x, Total=total_map, Area=mapped_area, w=w) - error_matrix = rbind(error_matrix, Total = colSums(error_matrix)) - - # Proportions - y = t(apply(error_matrix[!rownames(error_matrix)%in%"Total",], 1, function(x) (x[cnames] / x["Total"]) * x["w"])) - y[total_map==0,] = 0 - total_prop_map = rowSums(y, na.rm = TRUE) - total_prop_ref = colSums(y, na.rm = TRUE) - - # Proportions matrix - prop_matrix = cbind(y, Total = total_prop_map, Area = mapped_area, w = w) - prop_matrix = rbind(prop_matrix, Total = colSums(prop_matrix, na.rm = TRUE)) - - # Accuracy - UA = as.numeric(diag(as.matrix(prop_matrix[cnames,cnames])) / prop_matrix[cnames,"Total"]) - UA[total_map==0] = 1 - names(UA) = cnames - - PA = as.numeric(diag(as.matrix(prop_matrix[cnames,cnames])) / prop_matrix["Total",cnames]) - PA[total_ref==0] = 1 - names(PA) = cnames - OA = sum(diag(as.matrix(prop_matrix[cnames,cnames])), na.rm = TRUE) - - temp = w^2*UA*(1-UA)/(total_map-1) - - VO = sum(temp, na.rm = TRUE) - SO = sqrt(VO) - OCI = SO * mult - - VU = UA*(1-UA)/(total_map-1) - SU = sqrt(VU) - UCI = SU * mult - - fun1 = function(x, xt, Area){ - sum(Area*x/xt, na.rm = TRUE) - } - - fun2 = function(i, x, xt, Area, PA){ - x = as.numeric(x[,i]) - x = x[-i] - xt = xt[-i] - Area = Area[-i] - PA = PA[i] - PA^2*sum(Area^2*x/xt*(1-x/xt)/(xt-1), na.rm = TRUE) - } - - Nj = apply(x, 2, fun1, total_map, mapped_area) - expr1 = mapped_area^2*(1-PA)^2*UA*(1-UA)/(total_map-1) - expr2 = sapply(1:nrow(x), fun2, x=x, xt=total_map, Area=mapped_area, PA=PA) - VP = (1/sapply(Nj, function(x) ifelse(x==0, 1, x))^2)*(expr1+expr2) - SP = sapply(VP, function(x) ifelse(x==0, 0, sqrt(x))) - PCI = SP * mult - - # Compute adjusted area - estimated_area = prop_matrix["Total",cnames] * prop_matrix["Total","Area"] - sd_error = apply(prop_matrix[cnames,cnames], 2, function(x) sqrt(sum( (prop_matrix[cnames,"w"]*x[cnames]-x[cnames]^2)/(error_matrix[cnames,"Total"]-1) )) ) - sd_error_estimated_area = sd_error * prop_matrix["Total","Area"] - CI_estimated_area = sd_error_estimated_area * mult - - res = list(OverallAccuracy = c(Accuracy=OA, Var=VO, sd=SO, ci=OCI), - UsersAccuracy = cbind(Accuracy=UA, Var=VU, sd=SU, ci=UCI), - ProducersAccuracy = cbind(Accuracy=PA, Var=VP, sd=SP, ci=PCI), - AreaUncertainty = cbind(Mapped=c(prop_matrix[cnames,"Area"]), - Adjusted=c(estimated_area), - ci=c(CI_estimated_area)), - ErrorMatrix = error_matrix, - ProportionMatrix = prop_matrix, - conf.int = conf.int - ) - - res - -} - - - - - diff --git a/R/twdtwClassify.R b/R/twdtwClassify.R deleted file mode 100644 index 7c47619..0000000 --- a/R/twdtwClassify.R +++ /dev/null @@ -1,281 +0,0 @@ -############################################################### -# # -# (c) Victor Maus # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2016-01-16 # -# # -############################################################### - - -#' @include methods.R -#' @title Classify time series -#' @name twdtwClassify -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description This function classifies the intervals of a time series -#' based on the TWDTW results. -#' -#' @inheritParams twdtwReduceTime -#' -#' @param x An object of class twdtw*. This is the target time series. -#' Usually, it is a set of unclassified time series. -#' -#' @param from A character or \code{\link[base]{Dates}} object in the format "yyyy-mm-dd". -#' -#' @param to A \code{\link[base]{character}} or \code{\link[base]{Dates}} object in the format "yyyy-mm-dd". -#' -#' @param by A \code{\link[base]{character}} with the interval size, \emph{e.g.} "6 month". -#' -#' @param breaks A vector of class \code{\link[base]{Dates}}. This replaces the arguments \code{from}, -#' \code{to}, and \code{by}. -#' -#' @param overlap A number between 0 and 1. The minimum overlapping -#' between one match and the interval of classification. Default is 0.5, -#' \emph{i.e.} an overlap minimum of 50\%. -#' -#' @param patterns.labels a vector with labels of the patterns. -#' -#' @param thresholds A numeric vector the same length as \code{patterns.labels}. -#' The TWDTW dissimilarity thresholds, i.e. the maximum TWDTW cost for consideration -#' in the classification. Default is \code{Inf} for all \code{patterns.labels}. -#' -#' @param fill A character to fill the classification gaps. -#' For signature \code{twdtwTimeSeries} the default is \code{fill="unclassified"}, -#' for signature \code{twdtwRaster} the default is \code{fill="unclassified"}. -#' -#' @param filepath A character. The path at which to save the raster with results. -#' If not provided the function saves in the same directory as the input time series raster. -#' -#' @param ... Arguments to pass to specific methods for each twdtw* class -#' and other arguments to pass to \code{\link[raster]{writeRaster}} and -#' \code{\link[raster]{pbCreate}}. If \code{x} of -#' \code{\link[dtwSat]{twdtwTimeSeries-class}} additional arguments passed to -#' \code{\link[dtwSat]{twdtwApply}}. -#' -#' @return An object of class twdtw*. -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwApply}}, -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{twdtwTimeSeries-class}}, and -#' \code{\link[dtwSat]{twdtwRaster-class}}, -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @export -setGeneric(name = "twdtwClassify", - def = function(x, ...) standardGeneric("twdtwClassify")) - - -#' @rdname twdtwClassify -#' @aliases twdtwClassify-data.frame -#' @example examples/test_twdtw_raster_analysis.R -#' @export -setMethod(f = "twdtwClassify", "data.frame", - def = function(x, y, step.matrix=symmetric1, breaks=NULL, from=NULL, to=NULL, by=NULL, - overlap=0.5,fill=length(y),alpha=-0.1,beta=50,time.window=FALSE, keep=FALSE, ...){ - twdtwReduceTime(x=x, y=y, step.matrix=step.matrix, breaks=breaks, from=from, to=to, by=by, - overlap=overlap,fill=fill,alpha=alpha,beta=beta,time.window=time.window,keep=keep, ...) - }) - -#' @rdname twdtwClassify -#' @aliases twdtwClassify-list -#' @example examples/test_twdtw_raster_analysis.R -#' @export -setMethod(f = "twdtwClassify", "list", - def = function(x, y, step.matrix=symmetric1, breaks=NULL, from=NULL, to=NULL, by=NULL, - overlap=0.5,fill=length(y),alpha=-0.1,beta=50,time.window=FALSE, keep=FALSE, ...){ - lapply(x, FUN = twdtwReduceTime, y=y, step.matrix=step.matrix, breaks=breaks, from=from, to=to, by=by, - overlap=overlap,fill=fill,alpha=alpha,beta=beta,time.window=time.window,keep=keep, ...) - }) - -#' @rdname twdtwClassify -#' @aliases twdtwClassify-twdtwTimeSeries -#' @example examples/test_twdtw_raster_analysis.R -#' @export -setMethod("twdtwClassify", "twdtwTimeSeries", - function(x, patterns.labels=NULL, from=NULL, to=NULL, by=NULL, breaks=NULL, - overlap=.5, thresholds=Inf, fill="unclassified", ...){ - xm = twdtwApply(x = x, from = from, to = to, by = by, breaks = breaks, ...) - if(is(xm, "twdtwMatches")){ - x = xm - if(is.null(patterns.labels)) patterns.labels = labels(x@patterns) - 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 { - # These automatic breaks needs to be improved - y = x@patterns - 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]] - cycles = c(18,12,6,4,3,2) - by = cycles[which.min(abs(by-cycles))] - from = patt_range[[min_range]][1] - to = from - month(to) = month(to) + by - dates = as.Date(unlist(index(x@timeseries))) - year(from) = year(min(dates)) - year(to) = year(max(dates)) - breaks = seq(from, to, paste(by,"month")) - } - breaks = as.Date(breaks) - twdtwClassify.twdtwMatches(x, patterns.labels=patterns.labels, breaks=breaks, - overlap=overlap, thresholds=thresholds, fill=fill) - } else { - new("twdtwMatches", timeseries=xm$x, patterns=xm$y, alignments=xm$aligs) - } - }) - -#' @rdname twdtwClassify -#' @aliases twdtwClassify-twdtwTimeSeries -#' @example examples/test_twdtw_raster_analysis.R -#' @export -setMethod("twdtwClassify", "twdtwMatches", - function(x, patterns.labels=NULL, from=NULL, to=NULL, by=NULL, breaks=NULL, - overlap=.5, thresholds=Inf, fill="unclassified"){ - if(is.null(patterns.labels)) patterns.labels = labels(x@patterns) - 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 { - # These automatic breaks needs to be improved - y = x@patterns - 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]] - cycles = c(18,12,6,4,3,2) - by = cycles[which.min(abs(by-cycles))] - from = patt_range[[min_range]][1] - to = from - month(to) = month(to) + by - dates = as.Date(unlist(index(x@timeseries))) - year(from) = year(min(dates)) - year(to) = year(max(dates)) - breaks = seq(from, to, paste(by,"month")) - } - breaks = as.Date(breaks) - twdtwClassify.twdtwMatches(x, patterns.labels=patterns.labels, breaks=breaks, - overlap=overlap, thresholds=thresholds, fill=fill) - }) - -#' @rdname twdtwClassify -#' @aliases twdtwClassify-twdtwRaster -#' @example examples/test_twdtw_raster_analysis.R -setMethod("twdtwClassify", "twdtwRaster", - function(x, patterns.labels=NULL, thresholds=Inf, fill=255, filepath="", ...){ - if(is.null(patterns.labels)) patterns.labels = coverages(x) - patterns.labels = patterns.labels[!patterns.labels%in%"doy"] - twdtwClassify.twdtwRaster(x, patterns.labels=patterns.labels, thresholds=thresholds, fill=fill, filepath=filepath, ...) - }) - -twdtwClassify.twdtwRaster = function(x, patterns.labels, thresholds, fill, filepath, ...){ - - if(thresholds == Inf) { - thresholds = 9999 - } - - levels = c(seq_along(patterns.labels), fill) - labels = c(patterns.labels, "unclassified") - - # Create output raster objects - class_b <- brick(x@timeseries[[1]], nl = length(index(x)), values = FALSE) - distance_b <- brick(x@timeseries[[1]], nl = length(index(x)), values = FALSE) - class_vv <- matrix(class_b, ncol = nlayers(class_b)) - distance_vv <- matrix(distance_b, ncol = nlayers(distance_b)) - names(class_b) = paste0("date.",index(x)) - names(distance_b) = paste0("date.",index(x)) - - filepath <- trim(filepath) - filename <- NULL - if (filepath != "") { - dir.create(path = filepath, showWarnings = TRUE, recursive = TRUE) - filename <- paste0(filepath, "/", c("Class", "Distance"), ".grd") - names(filename) <- c("Class", "Distance") - } else if (!canProcessInMemory(class_b, n = length(x@timeseries) + 2)) { - filename <- c(rasterTmpFile("Class"), rasterTmpFile("Distance")) - } - - if (!is.null(filename)) { - class_b <- writeStart(class_b, filename = filename[1], ...) - distance_b <- writeStart(distance_b, filename = filename[2], ...) - } - - bs <- blockSize(x@timeseries[[1]]) - bs$array_rows <- cumsum(c(1, bs$nrows * class_b@ncols)) - pb <- pbCreate(bs$n, ...) - - for(k in 1:bs$n){ - - v <- lapply(x@timeseries[patterns.labels], getValues, row = bs$row[k], nrows = bs$nrows[k]) - rows <- seq(from = bs$array_rows[k], by = 1, length.out = bs$nrows[k]*class_b@ncols) - - for(i in seq_along(index(x))) { - - r <- sapply(v, function(vv) vv[, i]) - d <- apply(r, 1, min) - dc <- apply(r, 1, which.min) - dc[which(d[]>=thresholds)] = fill - class_vv[rows, i] <- dc - distance_vv[rows, i] <- d - } - - if (!is.null(filename)) { - writeValues(class_b, class_vv[rows, ], bs$row[k]) - writeValues(distance_b, distance_vv[rows, ], bs$row[k]) - } - - pbStep(pb, k) - - } - - if (!is.null(filename)) { - class_b <- writeStop(class_b) - distance_b <- writeStop(distance_b) - } else { - class_b <- setValues(class_b, values = class_vv) - distance_b <- setValues(distance_b, values = distance_vv) - } - - pbClose(pb) - - twdtwRaster(Class = class_b, Distance = distance_b, ..., timeline = index(x), - labels = labels, levels = levels, filepath = filepath) - -} - -twdtwClassify.twdtwMatches = function(x, patterns.labels, breaks, overlap, thresholds, fill){ - levels = as.character(patterns.labels) - names(levels) = levels - m = length(levels) - n = length(breaks)-1 - aligs = lapply(as.list(x), FUN=.bestIntervals, m=m, n=n, levels=levels, breaks=breaks, overlap=overlap) - twdtwMatches(x@timeseries, patterns=x@patterns, alignments=aligs) -} - -.bestIntervals = function(x, m, n, levels, breaks, overlap) -{ - best_matches = .bestmatches(x, m, n, levels, breaks, overlap)$IM - IL = best_matches[,1] - I = unique(best_matches[,1]) - I = I[I>0] - names(I) = levels[I] - aligs = lapply(levels, initAlignments) - aligs[names(I)] = lapply(I, function(i) subset(x, timeseries.labels = 1, patterns.labels = i, k = best_matches[IL==i,3])@alignments[[1]][[1]] ) - new("twdtwMatches", x@timeseries, x@patterns, alignments=list(aligs)) -} diff --git a/R/twdtwCrossValidate.R b/R/twdtwCrossValidate.R deleted file mode 100644 index bb91e93..0000000 --- a/R/twdtwCrossValidate.R +++ /dev/null @@ -1,117 +0,0 @@ - -setGeneric("twdtwCrossValidate", - def = function(object, ...) standardGeneric("twdtwCrossValidate") -) - -#' @title Cross Validate temporal patterns -#' @name twdtwCrossValidate -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Splits the set of time series into training and validation and -#' computes accuracy metrics. The function uses stratified sampling and a simple -#' random sampling for each stratum. For each data partition this function -#' performs a TWDTW analysis and returns the Overall Accuracy, User's Accuracy, -#' Produce's Accuracy, error matrix (confusion matrix), and a \code{\link[base]{data.frame}} -#' with the classification (Predicted), the reference classes (Reference), -#' and the results of the TWDTW analysis. -#' -#' @param object An object of class \code{\link[dtwSat]{twdtwTimeSeries}}. -#' -#' @param times Number of partitions to create. -#' -#' @param p The percentage of data that goes to training. -#' See \code{\link[caret]{createDataPartition}} for details. -#' -#' @param ... Other arguments to be passed to \code{\link[dtwSat]{createPatterns}} and -#' to \code{\link[dtwSat]{twdtwApply}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' \dontrun{ -#' # Data folder -#' data_folder = system.file("lucc_MT/data", package = "dtwSat") -#' -#' # Read dates -#' dates = scan(paste(data_folder,"timeline", sep = "/"), what = "dates") -#' -#' # Read raster time series -#' evi = brick(paste(data_folder,"evi.tif", sep = "/")) -#' raster_timeseries = twdtwRaster(evi, timeline = dates) -#' -#' # Read field samples -#' field_samples = read.csv(paste(data_folder,"samples.csv", sep = "/")) -#' table(field_samples[["label"]]) -#' -#' # Read field samples projection -#' proj_str = scan(paste(data_folder,"samples_projection", sep = "/"), -#' what = "character") -#' -#' # Get sample time series from raster time series -#' field_samples_ts = getTimeSeries(raster_timeseries, -#' y = field_samples, proj4string = proj_str) -#' field_samples_ts -#' -#' # Run cross validation -#' set.seed(1) -#' # Define TWDTW weight function -#' log_fun = logisticWeight(alpha=-0.1, beta=50) -#' cross_validation = twdtwCrossValidate(field_samples_ts, times=3, p=0.1, -#' freq = 8, formula = y ~ s(x, bs="cc"), weight.fun = log_fun) -#' cross_validation -#' -#' summary(cross_validation) -#' -#' plot(cross_validation) -#' -#' twdtwXtable(cross_validation) -#' -#' twdtwXtable(cross_validation, show.overall=FALSE) -#' -#' } -NULL - -#' @aliases twdtwCrossValidate-twdtwTimeSeries -#' @inheritParams twdtwCrossValidate -#' @rdname twdtwCrossValidate -#' @export -setMethod(f = "twdtwCrossValidate", signature = "twdtwTimeSeries", - definition = function(object, times, p, ...) twdtwCrossValidate.twdtwTimeSeries(object, times, p, ...)) - -twdtwCrossValidate.twdtwTimeSeries = function(object, times, p, ...){ - - partitions = createDataPartition(y = labels(object), times, p, list = TRUE) - - res = lapply(partitions, function(I){ - training_ts = subset(object, I) - validation_ts = subset(object, -I) - patt = createPatterns(training_ts, ...) - twdtw_res = twdtwApply(x = validation_ts, y = patt, n=1, ...) - df = do.call("rbind", lapply(twdtw_res[], function(xx) { - i = which.min(xx$distance) - if(length(i)<1) - return(data.frame(Alig.N=NA, from=NA, to=NA, distance=NA, label = "Unclassified")) - xx[i,] - })) - ref = labels(twdtw_res)$timeseries - pred = df$label - data = data.frame(.adjustFactores(ref, pred, levels=NULL, labels=NULL), df[,!names(df)%in%"labels"]) - error.matrix = table(Predicted=data$Predicted, Reference=data$Reference) - UA = diag(error.matrix) / rowSums(error.matrix) - PA = diag(error.matrix) / colSums(error.matrix) - O = sum(diag(error.matrix)) / sum(rowSums(error.matrix)) - list(OverallAccuracy=O, UsersAccuracy=UA, ProducersAccuracy=PA, ErrorMatrix=error.matrix, data=data) - }) - - new("twdtwCrossValidation", partitions=partitions, accuracy=res) - -} - - - - - - diff --git a/R/twdtwDist.R b/R/twdtwDist.R deleted file mode 100644 index 187c399..0000000 --- a/R/twdtwDist.R +++ /dev/null @@ -1,11 +0,0 @@ - -.twdtwDist = function (x, y, ...) { - d = do.call("rbind", lapply(x, function (xx) { - sapply(y, function (yy) { - res = twdtwApply(twdtwTimeSeries(xx), twdtwTimeSeries(yy), n=1, ...) - res[[1]]$distance[1] - }) - })) - as.matrix(d) -} - diff --git a/R/twdtwXtable.R b/R/twdtwXtable.R deleted file mode 100644 index fb1c98f..0000000 --- a/R/twdtwXtable.R +++ /dev/null @@ -1,302 +0,0 @@ -setGeneric("twdtwXtable", - def = function(object, ...) standardGeneric("twdtwXtable") -) - -#' @title LaTeX table from accuracy metrics -#' @name twdtwXtable -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description Creates LaTeX table from accuracy metrics -#' -#' @inheritParams twdtwAssessment-class -#' -#' @param table.type Table type, 'accuracy' for User's and Producer's Accuracy, -#' 'errormatrix' for error matrix, and 'area' for area and uncertainty. -#' Default is 'accuracy'. -#' -#' @param time.labels A character or numeric for the time period or NULL to -#' include all classified periods. Default is NULL. -#' -#' @param category.name A character vector defining the class names. If NULL -#' the class names in the object \code{x} are used. Default is NULL. -#' -#' @param category.type A character defining the categories type "numeric" -#' or "letter", if NULL the class names are used. Default is NULL. -#' -#' @param show.prop If TRUE shows the estimated proportion of area. -#' Used with \code{table.type='accuracy'}. Default is TRUE. -#' -#' @param show.overall If TRUE shows the overall accuracy of the cross-validation. -#' Default is TRUE. -#' -#' @param rotate.col Rotate class column names in latex table. Default is FALSE. -#' -#' @param caption The table caption. -#' -#' @param digits Number of digits to show. -#' -#' @param conf.int Specifies the confidence level (0-1). -#' -#' @param show.footnote Show confidence interval in the footnote. -#' -#' @param ... Other arguments to pass to \code{\link[xtable]{print.xtable}}. -#' -#' @seealso \code{\link[dtwSat]{twdtwAssess}} and -#' \code{\link[dtwSat]{twdtwAssessment}}. -#' -#' @references -#' \insertRef{Maus:2019}{dtwSat} -#' -#' \insertRef{Maus:2016}{dtwSat} -#' -#' @examples -#' \dontrun{ -#' -#' # Create raster time series -#' 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) -#' -#' # Read field samples -#' field_samples = read.csv(system.file("lucc_MT/data/samples.csv", package="dtwSat")) -#' proj_str = scan(system.file("lucc_MT/data/samples_projection", -#' package="dtwSat"), what = "character") -#' -#' # Split samples for training (10%) and validation (90%) using stratified sampling -#' library(caret) -#' set.seed(1) -#' I = unlist(createDataPartition(field_samples$label, p = 0.1)) -#' training_samples = field_samples[I,] -#' validation_samples = field_samples[-I,] -#' -#' # Create temporal patterns -#' training_ts = getTimeSeries(rts, y = training_samples, proj4string = proj_str) -#' temporal_patterns = createPatterns(training_ts, freq = 8, formula = y ~ s(x)) -#' -#' # Run TWDTW analysis for raster time series -#' log_fun = weight.fun=logisticWeight(-0.1,50) -#' r_twdtw = twdtwApply(x=rts, y=temporal_patterns, weight.fun=log_fun, format="GTiff", -#' overwrite=TRUE) -#' -#' # Classify raster based on the TWDTW analysis -#' r_lucc = twdtwClassify(r_twdtw, format="GTiff", overwrite=TRUE) -#' plot(r_lucc) -#' -#' # Assess classification -#' twdtw_assess = twdtwAssess(object = r_lucc, y = validation_samples, -#' proj4string = proj_str, conf.int=.95) -#' twdtw_assess -#' -#' # Create latex tables -#' twdtwXtable(twdtw_assess, table.type="errormatrix", rotate.col=TRUE, -#' caption="Error matrix", digits=2, comment=FALSE) -#' twdtwXtable(twdtw_assess, table.type="accuracy", category.type="letter", -#' caption="Accuracy metrics.") -#' twdtwXtable(twdtw_assess, table.type="area", category.type="letter", -#' digits = 0, caption="Area and uncertainty") -#' -#' } -NULL - -#' @aliases twdtwXtable-twdtwAssessment -#' @inheritParams twdtwXtable -#' @rdname twdtwXtable -#' @export -setMethod("twdtwXtable", - signature = signature(object = "twdtwAssessment"), - definition = function(object, table.type="accuracy", show.prop=TRUE, category.name=NULL, - category.type=NULL, rotate.col=FALSE, time.labels=NULL, - caption = NULL, digits = 2, show.footnote=TRUE, ...){ - y = object@accuracySummary - if(!is.null(time.labels)) - y = object@accuracyByPeriod[[time.labels]] - if(is.null(y)) - stop("time.labels out of bounds", call. = TRUE) - n = nrow(object@accuracySummary$ProportionMatrix) - 1 - if(is.null(category.name)) - category.name = rownames(object@accuracySummary$ProportionMatrix)[-(n+1)] - if(!is.null(category.type)) - category.name = switch(pmatch(category.type,c("numeric","letter")), - as.character(seq(1:n)), - LETTERS[1:n] - ) - category.colname = category.name - if(rotate.col) - category.colname = paste0("\\rotatebox[origin=l]{90}{",category.colname,"}") - pt = pmatch(table.type,c("accuracy","matrix","area","errormatrix")) - switch(pt, - .xtable.accuracy(x=y, category.name, category.colname, show.prop, caption, digits, show.footnote, ...), - .xtable.matrix(x=y, category.name, category.colname, caption, digits, ...), - .xtable.area(x=y, category.name, caption, digits, show.footnote, ...), - .xtable.matrix(x=y, category.name, category.colname, caption, digits, ...) - ) - } -) - -#' @aliases twdtwXtable-twdtwCrossValidation -#' @inheritParams twdtwXtable -#' @rdname twdtwXtable -#' @export -setMethod("twdtwXtable", - signature = signature(object = "twdtwCrossValidation"), - definition = function(object, conf.int=.95, show.overall=TRUE, - category.name=NULL, category.type=NULL, caption = NULL, digits = 2, show.footnote=TRUE, ...){ - y = summary(object, conf.int = conf.int) - n = nrow(y$Users) - if(is.null(category.name)) - category.name = rownames(y$Users) - if(!is.null(category.type)) - category.name = switch(pmatch(category.type,c("numeric","letter")), - as.character(seq(1:n)), - LETTERS[1:n] - ) - .xtable.crossvalidation(x=y, category.name, show.overall, conf.int, caption, digits, show.footnote, ...) - } -) - -.xtable.crossvalidation = function(x, category.name, show.overall, conf.int, caption, digits, show.footnote, ...){ - - ua = sprintf(paste0("%.",digits,"f"), round(x$Users[["Accuracy"]],digits)) - ua_sd = sprintf(paste0("(%.",digits,"f)"), round(x$Users[["sd"]],digits)) - ua_ci = sprintf(paste0("[%.",digits,"f-%.",digits,"f]"), round(x$Users[["CImin"]],digits), round(x$Users[["CImax"]],digits)) - - pa = sprintf(paste0("%.",digits,"f"), round(x$Producers[["Accuracy"]],digits)) - pa_sd = sprintf(paste0("(%.",digits,"f)"), round(x$Producers[["sd"]],digits)) - pa_ci = sprintf(paste0("[%.",digits,"f-%.",digits,"f]"), round(x$Producers[["CImin"]],digits), round(x$Producers[["CImax"]],digits)) - - tbl = data.frame(ua, ua_sd, ua_ci, pa, pa_sd, pa_ci) - table_columns = " & \\multicolumn{3}{c}{User's} & \\multicolumn{3}{c}{Producer's}" - n = 2 - - if(show.overall){ - oa = sprintf(paste0("%.",digits,"f"), round(x$Overall[["Accuracy"]],digits)) - oa_sd = sprintf(paste0("(%.",digits,"f)"), round(x$Overall[["sd"]],digits)) - oa_ci = sprintf(paste0("[%.",digits,"f-%.",digits,"f]"), round(x$Overall[["CImin"]],digits), round(x$Overall[["CImax"]],digits)) - - tbl$oa = "" - tbl$oa_sd = "" - tbl$oa_ci = "" - - tbl$oa[1] = oa - tbl$oa_sd[1] = oa_sd - tbl$oa_ci[1] = oa_ci - - table_columns = paste0(table_columns, " & \\multicolumn{3}{c}{Overall}") - n = 3 - } - - comment = list() - comment$pos = list() - comment$pos[[1]] = c(0) - comment$pos[[2]] = c(nrow(tbl)) - comment$command = c(paste0(table_columns, "\\\\\n", - "\\multicolumn{1}{c}{Class}", paste(rep(" & \\multicolumn{1}{c}{$\\mu$} & \\multicolumn{1}{c}{$\\sigma$} & \\multicolumn{1}{c}{ci*}", n),collapse = ""),"\\\\\n"), - paste("\\hline \n", ifelse(show.footnote, paste0("\\multicolumn{",ncol(tbl)+1,"}{l}{* ",conf.int*100,"\\% confidence interval.}\n"), ""), sep = "")) - - rownames(tbl) = category.name - - tbl = xtable(tbl, caption) - - print.xtable(tbl, add.to.row = comment, include.rownames=TRUE, include.colnames = FALSE, - hline.after = c(-1, 0), sanitize.text.function = function(x) x, ...) - -} - - -.xtable.accuracy = function(x, category.name, category.colname, show.prop, caption, digits, show.footnote, ...){ - - ua = sprintf(paste0("%.",digits,"f$\\pm$%.",digits,"f"), round(x$UsersAccuracy[,"Accuracy"],digits), round(x$UsersAccuracy[,"ci"], digits)) - pa = sprintf(paste0("%.",digits,"f$\\pm$%.",digits,"f"), round(x$ProducersAccuracy[,"Accuracy"],digits), round(x$ProducersAccuracy[,"ci"], digits)) - oa = c(sprintf(paste0("%.",digits,"f$\\pm$%.",digits,"f"), round(x$OverallAccuracy["Accuracy"],digits), round(x$OverallAccuracy["ci"], digits)), rep("", length(pa)-1)) - - prop = data.frame(ua, pa, oa) - names(prop) = c("User's*", "Producers's*", "Overall*") - - if(show.prop){ - prop = data.frame(`User's*` = "", `Producers's*` = "", `Overall*` = "") - prop = as.data.frame.matrix(x$ProportionMatrix) - prop = data.frame(apply(prop[,!names(prop)%in%c("Area","w")], 1, FUN = sprintf, fmt=paste0(paste0("%.",digits,"f"))), stringsAsFactors = FALSE) - rownames(prop) = names(prop) - prop$`User's*` = "" - prop$`Producers's*` = "" - prop$`Overall*` = "" - names(prop)[1:length(category.name)] = category.colname - prop$`User's*`[1:length(ua)] = ua - prop$`Producers's*`[1:length(pa)] = pa - prop$`Overall*`[1:length(oa)] = oa - } - - rownames(prop)[1:length(category.name)] = category.name - tbl = xtable(prop, caption) - - comment = list() - comment$pos = list() - comment$pos[[1]] = c(0) - comment$pos[[2]] = c(nrow(tbl)) - if(show.prop){ - comment$command = c(paste0("&\\multicolumn{",length(category.name),"}{c}{Reference class}&&&&\\\\\n", - paste(c("\\multicolumn{1}{c}{Map class}",names(tbl)), collapse = " & "),"\\\\\n"), - paste("\\hline \n", ifelse(show.footnote, paste0("\\multicolumn{",ncol(tbl),"}{l}{* ",x$conf.int*100,"\\% confidence interval.}\n"), ""), sep = "")) - } else { - comment$command = c(paste0(paste(c("\\multicolumn{1}{c}{Class}",names(tbl)), collapse = " & "),"\\\\\n"), - paste("\\hline \n", ifelse(show.footnote, paste0("\\multicolumn{",ncol(tbl),"}{l}{* ",x$conf.int*100,"\\% confidence interval.}\n"), ""), sep = "")) - } - - - print.xtable(tbl, add.to.row = comment, include.rownames=TRUE, include.colnames = FALSE, - hline.after = c(-1, 0), sanitize.text.function = function(x) x, ...) -} - -.xtable.matrix = function(x, category.name, category.colname, caption, digits, ...){ - m = as.data.frame.matrix(x$ErrorMatrix) - # names(m)[ncol(m)] = "Estimation weight" - names(m)[1:length(category.name)] = category.colname - rownames(m)[1:length(category.name)] = category.name - - tbl = xtable(m, caption, digits = c(rep(0, ncol(m)-1), digits, 3)) - - comment = list() - comment$pos = list() - comment$pos[[1]] = c(0) - comment$command = c(paste0("&\\multicolumn{",length(category.name),"}{c}{Reference class}&&\\\\\n", - paste(c("\\multicolumn{1}{c}{Map class}",names(tbl)), collapse = " & "),"\\\\\n")) - - print.xtable(tbl, add.to.row = comment, include.rownames=TRUE, include.colnames = FALSE, - hline.after = c(-1, 0, nrow(tbl)), sanitize.text.function = function(x) x, ...) - -} - -.xtable.area = function(x, category.name, caption, digits, show.footnote, ...){ - - a = x$AreaUncertainty - a = data.frame(a) - - mp = sprintf(paste0("%.",digits,"f"), round(unlist(a$Mapped),digits)) - ad = sprintf(paste0("%.",digits,"f"), round(unlist(a$Adjusted),digits)) - ci = sprintf(paste0("$\\pm$%.",digits,"f"), round(unlist(a$ci),digits)) - - tbl = data.frame(mp, ad, ci) - rownames(tbl) = category.name - names(tbl) = c("Mapped area", "Adjusted area", "Margin of error*") - tbl = xtable(tbl, caption) - - comment = list() - comment$pos = list() - comment$pos[[1]] = c(0) - comment$pos[[2]] = c(nrow(tbl)) - comment$command = c(paste0(paste(c("\\multicolumn{1}{c}{Class}",names(tbl)), collapse = " & "), "\\\\\n"), - paste("\\hline \n", ifelse(show.footnote, paste0("\\multicolumn{",ncol(tbl),"}{l}{* ",x$conf.int*100,"\\% confidence interval.}\n"), ""), sep = "")) - - print.xtable(tbl, add.to.row = comment, include.rownames=TRUE, include.colnames = FALSE, - hline.after = c(-1, 0), sanitize.text.function = function(x) x, ...) - -} - - - diff --git a/R/twdtw_reduce_time.R b/R/twdtw_reduce_time.R deleted file mode 100644 index db1fbe7..0000000 --- a/R/twdtw_reduce_time.R +++ /dev/null @@ -1,263 +0,0 @@ -#' @include methods.R -#' @title Faster version of TWDTW apply -#' @name twdtwReduceTime -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' @rdname twdtwReduceTime -#' -#' @description This function is a faster implementation of -#' \link[dtwSat]{twdtwApply} that is in average 4x faster. The time weight function -#' is coded in Fortran. It does not keep any intermediate data. -#' It performs a multidimensional TWDTW analysis -#' \insertCite{Maus:2019}{dtwSat} and retrieves only the best matches between -#' the unclassified time series and the patterns for each defined time interval. -#' -#' @inheritParams twdtwApply -#' @inheritParams twdtwClassify -#' -#' @param x a data.frame with the target time series. Usually, it is an -#' unclassified time series. It must contain two or more columns, one column -#' called \code{date} with dates in the format "YYYY-MM-DD". The other columns -#' can have any names (e.g., red, blue, nir, evi, ndvi) as long as they match -#' the column names in the temporal patterns \code{y}. -#' -#' @param y a list of data.frame objects similar to \code{x}. -#' The temporal patterns used to classify the time series in \code{x}. -#' -#' @param time.window logical. TRUE will constrain the TWDTW computation to the -#' value of the parameter \code{beta} defined in the logistic weight function. -#' Default is FALSE. -#' -#' @param fill An integer to fill the classification gaps. -#' -#' @examples -#' \dontrun{ -#' -#' library(dtwSat) -#' from = "2009-09-01" -#' to = "2017-09-01" -#' by = "12 month" -#' -#' # S4 objects for original implementation -#' tw_patt = readRDS(system.file("lucc_MT/patterns/patt.rds", package = "dtwSat")) -#' tw_ts = twdtwTimeSeries(MOD13Q1.ts) -#' -#' # Table from csv for faster version -#' mn_patt <- lapply(dir(system.file("lucc_MT/patterns", package = "dtwSat"), -#' pattern = ".csv$", full.names = TRUE), read.csv, stringsAsFactors = FALSE) -#' mn_ts <- read.csv(system.file("reduce_time/ts_MODIS13Q1.csv", package = "dtwSat"), -#' stringsAsFactors = FALSE) -#' -#' # Benchtmark -#' rbenchmark::benchmark( -#' legacy_twdtw = twdtwClassify(twdtwApply(x = tw_ts, y = tw_patt, weight.fun = log_fun), -#' from = from, to = to, by = by)[[1]], -#' fast_twdtw = twdtwReduceTime(x = mn_ts, y = mn_patt, from = from, to = to, by = by) -#' ) -#' } -#' -#' @export -twdtwReduceTime = function(x, - y, - alpha = -0.1, - beta = 50, - time.window = FALSE, - dist.method = "Euclidean", - step.matrix = symmetric1, - from = NULL, - to = NULL, - by = NULL, - breaks = NULL, - overlap = .5, - fill = length(y) + 1, - keep = FALSE, ...){ - - # Split time series from dates - px <- x[,names(x)!="date",drop=FALSE] - tx <- as.Date(x$date) - - # Compute TWDTW alignments for all patterns - twdtw_data <- lapply(seq_along(y), function(l){ - - # Split pattern time series from dates - py <- y[[l]][,names(y[[l]])!="date",drop=FALSE] - ty <- as.Date(y[[l]]$date) - - # Match bands and remove bands that are not in both time series - names(py) <- tolower(names(py)) - names(px) <- tolower(names(px)) - px <- px[,names(py),drop=FALSE] - py <- py[,names(px),drop=FALSE] - - # Get day of the year for pattern and time series - doyy <- as.numeric(format(ty, "%j")) - doyx <- as.numeric(format(tx, "%j")) - - # Compute accumulated DTW cost matrix - xm = na.omit(cbind(doyx, as.matrix(px))) - ym = na.omit(cbind(doyy, as.matrix(py))) - internals = .fast_twdtw(xm, ym, alpha, beta, step.matrix, time.window) - - # Find all low cost candidates - b <- internals$JB[internals$JB!=0] - a <- internals$VM[-1,][internals$N,b] - d <- internals$CM[-1,][internals$N,b] - # View(internals$VM[-1,]) - # CM <- internals$CM[-1,]; CM[CM>10000] <- NA; CM |> t() |> image() - candidates <- matrix(c(a, d, b, b, rep(l, length(b))), ncol = 5, byrow = F) - - # Order matches by minimum TWDTW distance - I <- order(candidates[,3]) - if(length(I)<1) return(NULL) - - # Build alignments table table - candidates[,4] <- I - - if(!keep){ - internals = NULL - } else { - internals$tsDates <- tx - internals$patternDates <- ty - } - - return(list(candidates = candidates, internals = internals)) - - }) - - aligs <- do.call("rbind", lapply(twdtw_data, function(x) x$candidates)) - il <- order(aligs[,1], aligs[,2]) - - # Create classification intervals - # if(is.null(breaks)){ - # breaks <- seq(as.Date(from), as.Date(to), by = by) - # } - 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(y, function(yy) range(yy$date)) - 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(x$date)[1]) - year(to) = year(range(x$date)[2]) - if(to # -# Institute for Geoinformatics (IFGI) # -# University of Muenster (WWU), Germany # -# # -# Earth System Science Center (CCST) # -# National Institute for Space Research (INPE), Brazil # -# # -# # -# R Package dtwSat - 2015-09-01 # -# # -############################################################### - -.onAttach = function(lib, pkg){ - packageStartupMessage( - sprintf("Loaded dtwSat v%s. See ?dtwSat for help; citation(\"dtwSat\") for use in publications.\n", - utils::packageDescription("dtwSat")$Version) ) - - ## Register TWDTW as a distance function into package proxy - is_there <- c("TWDTW","twdtw") %in% proxy::pr_DB$get_entry_names() - sapply(c("TWDTW","twdtw")[is_there], proxy::pr_DB$delete_entry) - - proxy::pr_DB$set_entry(FUN = .twdtwDist, - names = c("TWDTW","twdtw"), - loop = FALSE, - type = "metric", - description = "Time-Weighted Dynamic Time Warping", - reference = "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, 9 (8), pp. 3729--3739. ." ) -} - -#' @import zoo -#' @import raster -#' @import ggplot2 -#' @import methods -#' @import rgdal -#' @importFrom foreach foreach %dopar% -#' @importFrom proxy dist pr_DB -#' @importFrom reshape2 melt -#' @importFrom scales pretty_breaks date_format percent -#' @importFrom grDevices terrain.colors gray.colors -#' @importFrom plyr alply -#' @importFrom sp Polygon Polygons SpatialPoints SpatialPolygons SpatialPointsDataFrame over CRS spTransform coordinates bbox +#' @import twdtw +#' @import stars #' @importFrom mgcv gam predict.gam -#' @importFrom RColorBrewer brewer.pal -#' @importFrom stats xtabs ave window na.omit sd qnorm -#' @importFrom lubridate month month<- day day<- year year<- -#' @importFrom caret createDataPartition -#' @importFrom xtable xtable print.xtable -#' @importFrom utils packageDescription flush.console globalVariables -#' @importFrom Rdpack reprompt -#' @importFrom data.table rbindlist -#' @useDynLib dtwSat, .registration = TRUE #' NULL - -if(getRversion() >= "2.15.1") utils::globalVariables("tsidopar") - -### Import and export functions from other packages - -#' @importFrom dtw symmetric1 -#' @export -dtw::symmetric1 - -#' @importFrom dtw symmetric2 -#' @export -dtw::symmetric2 - -#' @importFrom dtw asymmetric -#' @export -dtw::asymmetric - -#' @importFrom dtw rabinerJuangStepPattern -#' @export -dtw::rabinerJuangStepPattern diff --git a/README.Rmd b/README.Rmd deleted file mode 100644 index a15fd28..0000000 --- a/README.Rmd +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "dtwSat" -author: "Victor Maus" -date: "`r Sys.Date()`" -output: - md_document: - variant: markdown_github -bibliography: ./inst/REFERENCES.bib ---- - -```{r, echo=FALSE} -knitr::opts_chunk$set( - warning = FALSE, - message = FALSE, - error = FALSE, - cache = FALSE, - results = "hide" -) -``` - -dtwSat -===== - -[![Build Status](https://travis-ci.org/vwmaus/dtwSat.png?branch=master)](https://travis-ci.org/vwmaus/dtwSat) [![License](http://img.shields.io/badge/license-GPL%20%28%3E=%202%29-brightgreen.svg?style=flat)](http://www.gnu.org/licenses/gpl-2.0.html) [![CRAN](http://www.r-pkg.org/badges/version/dtwSat)](http://cran.r-project.org/package=dtwSat) [![month](http://cranlogs.r-pkg.org/badges/dtwSat)](http://www.r-pkg.org/pkg/dtwSat) [![total](http://cranlogs.r-pkg.org/badges/grand-total/dtwSat)](http://www.r-pkg.org/pkg/dtwSat) - -### Time-Weighted Dynamic Time Warping for satellite image time series analysis - -The \proglang{R} package *dtwSat* provides an implementation of the Time-Weighted Dynamic Time Warping (TWDTW) method for land cover mapping using multi-band satellite image time series [@Maus:2016; @Maus:2019]. *dtwSat* provides full cycle of land cover classification using image time series, ranging from selecting temporal patterns to visualizing, and assessing the results. - -## Installing - -Install either from CRAN - -```{r, eval = FALSE} -install.packages("dtwSat") -``` - -or install the development versions from GitHub - -```{r, eval = FALSE} -library(devtools) -devtools::install_github("vwmaus/dtwSat") -``` - -## References - diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 2f7efbe..0000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-minimal \ No newline at end of file diff --git a/figure/plot-MOD13Q1.ts-ts-1.png b/figure/plot-MOD13Q1.ts-ts-1.png deleted file mode 100644 index 9a49f829fe47080108deaf43ad4db9dc0d62e33d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77723 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 diff --git a/figure/plot-area-uncertainty-1.png b/figure/plot-area-uncertainty-1.png deleted file mode 100644 index a6031996906510103ceb6502be31742a3ecc023c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12498 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 diff --git a/figure/plot-changes-1.png b/figure/plot-changes-1.png deleted file mode 100644 index 73c2c02f9c0c2e5df7b6d694cc5fef41f3767dac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24077 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

tfbs3)^ztiXqo{b5Y+mmF7k6H-Iax7sUT;> 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 diff --git a/figure/plot-group-1.png b/figure/plot-group-1.png deleted file mode 100644 index 6ac7fb9818e24d114101c7a587cf17c525784637..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90036 zcmb5Vbx>RH6Fz!Eio2B*cP|7f?ogmWaVr|2xD|H@Mcblzc0u>b(TeWNI+2>>Wk0064SKtX;p z^6~8^@&ogO;yX70!0Y_)4eE6+eh&b&z#BPfZSU^~Ek1D!w;tQq4^%$1ps4^)FCDck zzGc2iK5>$QwYM(aIr*EK9OF5i3SIIC;T3fxNhC&wgd}Xj0w2wK4U!$-nXr*0H5wcn z`QIg|F&io>D*R58ieOz<6139a79# z-{9!WAf-e7E2R2=kI!NJ|9&PVV}Yivqhp23eNRtMi>ZoC$A|d;eiHIGT5!et@pgM( zVC(#L)PIW){YPeKDBU{k{(maB-c47nG`d-vnXL_)KK@8N)5^M=Vu%$x^J}~I+jPCn zPELx0?l4m8%XCPe4e^coA6U@%ZGO{}IQ^vNf8>^B5fvR16S&2fm70+uzEi-&h$Hgf z!iBsgZu`|Fu9w`hp8jnoVD4gK9wvkm5EJ1+EQZReTJLHl?`xAR1FmYb0*?Jw{l++y z6d`y-_?&cWw5e%ncXzXGBf?J|WUVLmZCCb^7qXJ>|GR{|4;0S1;MGUFeNORyfze)*)S=JCWeJksfBhhS!A4!my&^1EL(;%a!f?(0*OSWP!AN&LZb zZ;QTIUpLdj+j5Q5lQQGG6UhGE&0?tKU!WffU8v^5@EccJnpDjJVVb5qT$p!qH2AKv z*=%%DH0wAxakSpC*M+=+h4=3NcA)$=v;%C@8yVB(EK}> zOmFqr&z_A(stWsHh6&u3;D2R_P37QV)y4Cb2ER2&7?_2byZZPzSZ-#Mok?}(-?g^g z?fpGFljdfm%Xu>T6}(X^wrWRvlaF`|`|#+ZU&sO{3+e}lIUyjsP*4i`?b zt7tA{h=}gK%(JEz=!i7|aBnUkG2x3E2N8G%Yw;R1_X#8_ROqxS^4Jr$zO!?1$wbZU zm4|uFw{^Ln{mdF4EVY0}1g=N_1hNk^2uNtOMh0U-@kg zNLR7a<;14UR<6x)o>Bse!nDY!u0X~*$AQxBam%ptxwCb{`veO zKO}@bZqB+xOf+O<+MpCnEkDB*Vzr-&p0N!w3Rfrnwk zERGWgp*?sHzJp0)49~e*JAeN6y(+Iev%VUZ92=o)y*j8MmVBIB{a0bge!J`5Mh3fo zTo*l#s;rDDudosnh%C9f>{p9g_1(GIbcF%)t1 zm8Zyox2X6Zq2Cr(93nsf^=Gi*+(R@^FW2vy-_;NpTfnaA=YAT3h)3n)x}YCoEsv~p z3M(!CyQgjsCLJ|`tKK&SWP&Wrf>u^l;;vS1uDOX+sRkyQ&7PMR9Nc~d>&i5DAKGR= zK%Y(g_M{?n`jhG=B;qz!<^%H%_(Yk-kO^kX!{r?Ut4n_c+jmQoLkAZcBMK5{9v5*# zFUmbqc+&w!(in`eZAa%=_D)W=+=l%%(fV-6dDp6co{)&^?oxvBVFZCv$xM?T_Wnyg zLFe~p=~aP$9#$5gRElD5i=J524Hx<5{_QVyTvG;KFAr{K?p%{kgvkW@uiw%<)GR~` zs%8H6Is1zY4#}$yY(cf}M#BETGK}M2ikJ+w2(?G?%({A?8lT^JVBn&h&yd87s4H=F zFUo(>_RKl9-=VrbV40^77`*Etzppu#9UgeC571h=AS4Gfi@emh4x(!24$*B9LaRPr zGKz<7%Tl(^M1I=#Z?FJH+zcq^Y&by(0h~$4dDTU2#D71myI}>(czbU{ZHIZ)CS6XT z{J&N8u6XAO3DiqSt{beYSsu42MxU%Dxhg!>7Mx-{P21QKs#3_1FYa`s;3(gV5bM6%jXSkgOQ$L@ zRKE4!Y}=oFtCjQ9rLtHcJV&xrodz=R$BbS4|S9 z$hz6l1>xsv=3M_2!Vmj45W~3eqkJK#S(;Huc^0EaS*+DoG*p@7YS3X5Km6;cZod&eQ#5&ILYu+;ro)1bQmkv@>R1EYzV*A=ZcY**%%X$rEu zX;Xzd4$-v01)bqUVy-FwPPBx0>{)r>sZZgyNONn;!l=ycC= zjdfxF7WWOL$iBBgC;zgL)8*I|R;#SM-Fn+FOC5OA9UI6mDN*xbxAo<&_|+E0=ko%s zqR6>tup9lK#+IWLepvRVh9+XZ$Q^5~42EnZecn{5pC`t$uyD=_+M5f*-taoQ@L+nd ztb=1K-yk|~jwN3Qu0II9YT#?Ma2j$*e3&jMBYVWnQ7MtDoDvim-0C5x7S(KMB$s(l zHy~bVDKP8$2giAp*OcP!F&By5pN-ifbYE~5*yzvV@!Ta3`n^ZU>*=*^&sSAYO8gr@ zmwX1>y(md7U}{#t+m~w3H}JndEJ!E{btG=YL+I;((PXBldfy#YIZ;a{Ezd!W4G&j& zHM{9~3cowrApj#0FD^+Qmq&`x$+f2WD$4=@?tk2WxRB@A_YV@~vytAW^v>=mN6jV` zQXOc<^|BN4y=1hglr>aQHqp=jq(7Q6X7uZ^S>52a5-n@L~rhree`q8OE#!r1Ug z4`3l}E>Qceq-=+g6DNy9bCqg}9w)#W`;!-zHjylG7Vj<*bhnv&*YNf6#}CXe7E@n* zY^>ZJ|Mo0Tlc{DtZF|}&_2)B~w$W}9Jg;hwh|4Xn188mMHk>q-(kb@eyAaU?ki@=B zk-Qafs=Rc4x=!kXzv{+H0u@hbybUEiXu|xFOJM$Fd7-^u)OJRid)Xjy8q!gd7cI^1 zaeWdW7Q(uFD2U(UVzxP!^RG(?V4uN#8+`PydV0q%T6}mWv&HXk-_)Um>Wj-WRN$L? z;pL--#a z+Em(>!|mqZAi5eMRGB`>M-vsx;kGA3l8EU}RUCb-lpr$r6*UShEbQ=5n~jU<=naO8 zyQQVO<7EMUQ2y6>51tm6y9<3T!5^Ncb*ZVpYQ^fCd^ZpBrk}c*%TJ9*X|>-5L{&ZN z?93VUJyvvaJP+HzT3k6#b(Xx;W=a=6&uBYdHNT7KCxyNux*xj~e9FRF6>7P~k%D;X z5Xl_Sd?RprNPW(PV67!3D{K(1E}&#>U&92dU)*v_DCTz{HSGhvEVV_}LTNG~lt6|E z7CcN8*SP-N?3y-Is6LG^v3z)V+OaLbT|?-qqrmH~1@6~hgH6VsI&@}UmySnj?<)$b z4@-M|hO0Ml;A@Jj-=xlJdHtcSbl>dX!mdK0^YY(o_3=qQS5#gqVrJvE^JQd64aW~% z7dbbNh4aqZ*t*l;-+-gJ71>w7ZY}R@`&WEnTX*bRJ)Z8j7PjYFH2e)SCq=8fYt2i1 z$a0E=L9fIGH|v>HcMQ7KJqYN(75`-wy{Y>p&*Dc;oD5Ike$ECq88@MLq~;CY2lh=_ zy($x7w;l(~wa6uCG@8RjOAk4Bd~(XcMha$CoO8vWVoM*Fc=lHT`&LgglVn(=H)eV0 z^)A=bdRh0~<0Z8$)VD=(SdC(vctF8dR`Vc?P?tUN>SBzcx1$`)D$cTzvu;AX@0x=t zGdl3wdVl+qa^tMxy8IVeQ{_#mzqBb19v=9&Y7>e?}y;Oja!^tS{ zwkl}k&0ERan$@2Nr8*1|JvG1Ee_>}Qi^Sx{Zm&SwPM_AEe4m^86j(P?Y5LoK_XRV5 zL}^e+*<^dRV~jCwG)lK&E>>BEp7(b*;a7EN2b4608I6;g14mYO;)+q998TYUwK;+3 z-<_JJbZHnS)Re{->Y(~oz^`MXL`!8?RxyYZQffL*{_Dw%Ht)(B*Dk2n@O zO+LyIwwO~(-P6edW#VLRKDI~a#j&9 zh=M(B=l?ag@jMMC56^P{>0_i8cHrW&C>EPtAr8%Nhrfw$IN;pKpM1I z8nuuv>*49Swmzmnm>Tz4LrW`8?k^gAj({HMto{61Vw1MToG?^-;kgSimbfDB`u^&! zF0i~vEk(U^9bgZm;0`?8{jLYb zU;@uai#FS$Jv9LlNj!K(IG{3HH^fW;^u@N}9|xu6I|4!?;PkbOMdKr%NKD2kTWz|} zw9di|OR5Ze%sRW$X^16*h>5~R5Ex#hmg;I_@*+)N#vHNkqSOG2yr4u{uJjb)AW2Y3 zAuRte=>lb{-QQ2wdi(GYx!4=S))Qky&Ro?-$Q8P9XrtL!mf%d4Rz&jcrzCattS6!V zORwi-xa~_5WB<-RY4uIo0uM$&8L zV%s<C$EH+=$qiMSsG zIxftBaG$yd|3d^mm4d-@V4;D3u5UqP+E)!v-Pbl!ij zx-r6BIg_;(f~4Zs>DsY?%@GvfEeCsjcc3l=quCCzm-g=}ZhYx89i!ylZrP6JDgAJ3z$Pa%-hkyX1~i|CiGZhT^{|+s?@})&+Dz^n`&^j%adU zqLuLR&DtmH$ADFh)LwnMLhwUI_iN_qiwX(P7e`Doc6dNyomlUd{I1d`0y|$A0tcvG zZVBm~Oc_{T2dAMi1Ot2G(26i3QYYt4#4pBgmH3YagiKkSM}*@bK;|Te&-?y)Yhccz z;Grb4RQ_nRQAn=9J49^cBx>kM5E{e4NdX)i;?C^YIayRa)A#U6T$3-f67zuyjj z{e?BLo&=CFB(J{ZVI3}>tRkR?Yn`8(`&taGwte}aD7G+if(jQQRG7jTca>+o23QR} zR!3*$n1&7^Q26g{AqoE;|3i;|!-mGK&TUAJMNGbm$APq~I`I$h8RA!>cFCAaDSgZ% zYh#HfGWWb>N9^f~cnn~5-rDQk*QEFX37RusgamM$?GQN1pg#dnm`Q8ouQxD$BT!B? z3#fSfT&`S8QoagF2tb?N1BA}vbEckG7oiLAp}`S*(ij>q0NTr0N>^VAT@`1O)^N#( z7@uAk*z#tUJ?aYpExNPMpp61}3!8w&o+6+$IiC0>dDMm1BxSfeGzW9uC9P}QC1R3cU{g0s;cI;9PQ zRp6#rTTEGmdmRVAAWZ;+;Sq&qr+2Km+BXaKK)CPHdS;vyV%@{U_C4a4I11b_)Aju| z-^<}kBM0;nU3ag9*wcg{#Mn@IoB~ zc0WP}|Kp{cmk$!4RjW{)<6vor>_&97J(TRyYjNk_GISrbK2MVc$DdTzmk}CUMDI@3 z%<<3d4gvJ9%6NJcE6knKxPph0>@_@c4c<~_DME!w7tbrYE@B4MqKF+eyUjObL-5ID1d0h>(KufHD+MJ4 zoFbH59Q{A(^USC!X-126pYu?snEP*@tfl46~r3@wpzT5^#!@7r-wA*=y4cL_ep; zlcfUWuDiis4nHb}kXjr=pu(=1x|M>uAs~GdBZ%p+@V6C;Src=d{LeCxp(1`_f|gqI zAq4c}XrW!91fcI}5dwc*byS>NPs1^pTAz3*Q{i#?^9N@Y=+B8GQ*nVmQw5U@L^y>x<{D|yW^aQM)pWndX$Zhr4ep=|y?OTATBA!O3!qMc@iZ9-GB=X`z zYH$KKnxgi9DYi-ULvHrZXaUGMva-f((nQr!)n;<_d(^EL#`w$v|!wq7ta;zaUz z5-1H$B%%;3?L~lUJI3%nY8vsqOA11jPxvFC&1RR-7X4Su{kz#-cSAIf2Q`Fn-)5zs z%#a%5n*rX?Txc~N5wO|uka}-2>kV5FcKH6z#9Ko(;P+8~@V2AM+hLP7&%?C{zvkc6 z<}#>K8esx5k<6An{RKM`p*DM85O%`i&L+*OQSG%=AzEiSe88W1h+2Z-zIW-OAdN~S zO`1cgQy$KFl9o7TW5!j#$WLjb>YBGIv=kI84c!Mq7(5Mveg5a67r_%?{Dbt>e_Qjl z)*H*Qjlf_ zQzlC@#<0!y7Wg#+?03EFC3!aj1byR`or5Alh`pg!~1v}_(Qh0Fa;YeP1r}EQ^53;G` z=}!D-Zjr;<4h*;y?MYzMX{d*_=YynB#U;)*iQq7YpH2-be*r{#)v}ZPYNzhg=kyb?_asnarxv}8ATAkW=BOVAlhmaiQPmlVc)y_@mGL!ja1z%y9J;j~$l^l=Zz@=7`PNu3?$h=9 zkM&J#-+y3_dp6b4o7ADD%l)$6n9KKOErKu+URXF!(dEbs3+6+f;kt`vqi`N*)T?Do zi@UD!zW3;yV4VQ7eo+1(jQ@6-}#`3&VJrUrTIIeGxG5G}z+> z_OKUfK-f%F%3hu-Lu;6q9gEA9qnSo?mI>bS_&6!sKHrp3r3y6r9l}goFABIHF4Ueb zERe1y+IB8V#%1JvP}2(x4GoFiAJi^#4{dtd{Z^2dKNBanBlR>ka_FEGWLUg6>!}C5 zMtw=@(_NK6IW9|=x2w)tkho`w&te^r_qG2SZu=Wu|BOD@KjKIEs@XTH8@-$bOP$^3 zqBL1Ng>}>f_(N>Tpl7d4zZ*B&6LO3Rcm_Qm5w2IYBqLcker&GnUYR?Yv~61}GEa6k z3`J#bu@|3_6&OvMc8=J+7C5r=F>|?En1*_jhZ4xJ7A${fYdR)d(ED(#1SS8IY2};otteF?sR&Y`ZMJ3{<+cY0>vh%P$1KpIgl~w|78pWZv=L z{r+cgh5LVI0TzqAcAO{rRot^NJo3u{f^?>d-BZE9Vxj4b7Jrd1u8>Lx82<|1p^xwO zxj1WBy`$eEVQB&SN@srp%WB}gBcNAl^ls^Msv?_*yLE+!bJg)R;5hSQ{tW_>hLUY# za~pi9C)1DyPDtv$r_EC%TUU;s+foky@XbfXkHzLYLCyCOC|gB#Z)#3p=eK9->EJw9 zEklcVtg;u+bn%t!y*5a(qA{TWf2n!pez08ekk~jUZvF3HaqQ0(X3_b5h&K@=8h&~_ zU`64s56dCCn&cIoq_JFaPkXYL=E4yc?0!K>eCQ}WkcQSM>2TB|?J8sni%uGtF`ni{ zC(8IF1Pn!kA#?ot_&9Uu5+}h8E57@)K@YQ|8KT=hE9uUyxA$#N_x~lTrxX0A6TQGq zy-^MSLe9j)Id>?%XT zap{ufLRrlM#pf?&F%eQfEfJhOFplNJ7V`0?Z&)?m*!Z!lSt2n~xjBTnJO-a9Vj??7 zfH5}rSG+Gt@^e-dnpN`6&Vvto$3qBmE#FB#olCYo9H;VGk9-#f|M{<7eJv_Uz{mza z)~>KmLL)HfISt^z=!(ILzxMyGH1#&`6Z+MUlv`PcID7p+IVvAF(Fi}IgPy?F}vvYjWi_?8tV<3)JjqBHd z`u7S-5&mZP!^87!zqg>NG|lz8fM8eX$psG~(a{6b}c3b{t7+44%yp$V9Ot z-e0`|!Y!ltI@vGLRJ6#ON^{hmC%A0{O;MC(9rHgylV(r{ewRTYWAR$raarkI}DdV%BYnfTPRU9 zq&(i}bM*(W-Teqvf7ivyXffzF&5Y5XIH+(u>{Jk7WSDtcH>rYxw4#*-fwS@3;>hkgti?;j zcM_nYX%gLIFSy-2g}QxMTI}mGj9mluZ;Wl@!;z^C=?Kl!+TqJ3C9rzsk$ z_bR%Z1+)hzKZbz^b~#tD2>f*dTiFfK-+^?<&(W6#RZ zQDY?u<^Cn7o8N{`UTyr*wCNeDzZ$a1Ju7_8akulXYg}Di?50F!oIvx@r3@+4!lNOeoX`BI54C)lKi%<(v>U z7Kb`@14gfz4l~e`xSq48s^l?-%A*Z^#->Bz^`j0I_(K1@r{@QFH<*yl?6?!0r%EDo zFaxh!eVd2pW<%MC@~`z`M1nPv8&-SxBRIObigbpHTH>~3Vf(`oNZlyq$BsjJ6lN1H zUB_06VuEOhH^+bOq5sRAgZsjh>HL+NGBW^?$*wqm?#5jd!9#idBONCE5aPiu$2anK~s2hT`n| zY*Epc=)CCR>K*0=m`aOHmE+pv#@mSO>r${ip0F6mt!-B*ie`ox;binLwo*`B_^EYa zn_vLqMM?}UBzIk6VLT8C#eg}9og%`)^tukIC8XUT;F6yZ2z7KuZ>Dd{X{Z}Ym7$Yw zj}PiU(a2cXRVKkCd=nDWc|D}+8ZLc&+Bb8*L z+384K6&2E`Ju3rIexES`DtSUMCSuOm8wR9O@D1)8N4xLhe*%^D7QYJjB{okfQUs(N z*o1(-(#SmPS#=Ja3WW1_h3+%%(s&koQEAAQt#u_2?sMahEgeuy!qmh%VM+2~&3Ub` zK6?CeFSK%fhuj>~VDaVLmyw>&i-TTX<*e_p@-Wv5d)FkZlYg-%t$&B!)4~ZDAMO37 zUvQ_Cd6t(#)jT=@>%ng@9A9m`OEw6LP<_nnDdHJSV0<=~8e_o`I%n+GcgqusWe@f; zL()Rx2F_Dg@ueMNvbpbuL?v%Zqgsnp0r-RyeiWo%*}2alK)n1aMlk8)Yx2-3_5ZX? zJ7h-z1NO11lmkka>hjL$!KC4DWgJ;C{N2UPEX8x22+QN1j)bz3|H`p!? zFr5L~Hwwd`{Y<}NiiXp=VU26=G`;&Q%VwzH9|;?#JJ)u`P&plP6vT zCx1=)W=!+zyc`vI!i-N3_purkz8=z&a~-Du*B9g*55cKW3HC!#OSE@{b}!qNsWIMg zqESs;?ICQKv87OrUqJKtcVVn2SA+O(VJ%bB`sJXIXLLq*FurSfvxoKgNlBu6{+>zA zd#R$jpKNGRp*_+v2j3_ z9;;2yzhxyS6K~9^q*R6d%<|vFa^-ThGz~nV4k~YBtI99z-dqD*U6n3Ft}WB7gD-LF zUhTePiLoPf^JiK8W<`F7amWQ^f4ixV=x(2KiG1*ZaV9X+E^vEY7B;z&($~9F{t9>! zGV4j!z&O3yl&sUznv9Ty-19pX6|i@j=QC_Lc9=k*0G|bTjt~i3&9wCB*)^vbIcygG z4y3^vPiTN{E2Cps1YMWAgsJK*N8|jKGOycnTtX1-XiWUE^Y>vOI(*?ya?_-E_1b#RA63#d=ELzRO-Q*5>Gn9sb7iUwz| z@ghxK?obv{kv|dU@8d<|OU_ALQ}~1D+y>|TC*NxEhJJb~2r8!vA#>GZF>S1|W-$fA zg@BZUqpwY`OZ6Q{g6O}}qKMQJn&XPp&2ff8L@E#QmqG;?61UK#(vf|&DSh^X5h8mn z$$k5*6xr+en9dX%6}_Eph})9;!z*iwp2>L7{t#G}ws~qyA+FH{_mPoUs@}bF4D4R*5 zMG=;fWe7D<47hkxrdyJrABATV`(s)}*?-AK9Hh88Q#kn;B*oXiDaiBN%vPZ5O4Wdh z*w|Kg!4E&)QVg9S$|SRJ)WEc*r5(BLRM2GIO04wj0eE8p{dALwEVnE0lT>n5*@uO~ zZvw2JmHC363Z3{zC2_>OvMfFVN(Sh(@WL(|@TR-9-E#dx3BEN;y>C@jCnjv-0tRXF z5nslj@;u<|VUtJz;;_7VD3dGYm%#A0BMJ#;Jm5bAF13t;qFL28=4wyzs#c1RiWC- z%c=iT96BJ5*h$>24$ao1$Ab?=r-L|9m65Tv)Ip`BId1Is64@Nh9*pepl^;C42A}v; z>ha!HNV7MKLCMQ)>?s*dGLhN#T@-;!_#5FSfoE-Qg^c6!j$s6O>|0l2P;}ruK8|ct zX-+IIUFE?G$!FQiulY45BAl?`uhd0iY|@x!fdx_*AaSu&6l~R$Fb)RjQfLGP(e}v~ zUX1fA3ngKE8CqZn#gJ+w4^(*Y2hYFdxHBG#T{~jd9y-Ymq33~#s#jE;mDXESW-^~4 z-oF4alL(^|tZlP64O`9;GP4yF`7&~Nx|8&b-$Xz%wz9G%m%FyIeRI$qAsdgh%_MYY zK>$`Ip^4DNQ$bQ;=g1kFg7_Paq?+24edvskw}5UWL|438T4^zq2yR7wKM<^;w|k`O zF<%D)e`vedpbf+T*bKu_2j>^zZOZ}$}An3v1x9+N_@uA6c(P|xDZ1~uQbRW6OH?toYStL#sX2A z;eUOF$R(iPeT^~B@tkBMc#%L5E%FzI?J-ap6?c721-37qY3cwt=I#Fs3x{F_^f#YJH!5;)RplCTeZ|V5pyM%!L zTbwy5*PDUn9Hvg~@8%zUfMRyKi7~#}6OF?Rf-PpPQkD&6Bs!JQeSZCVM5tmxs`#Q` z9*hRF@bzUCt5(cpX?TAzO<+#J-i4giQo-*cG|5r#&mV_k;%Jb%x#9nMekhMg%V;LYne4kvaFg@vJ91-KuqwG86b9naFpK0=PJ`UG)XOmQ8(?3|tw9Gm-w} zL55~b^vg+6TI8q)*0k@{LLEY*CWH@1Ie5$tk5hlSyewLa_kCjX#;1DcFtEP32jXct^3wbf%159KxZWUiSG zCGE3zB)|U5h!}8~0gWT|OSoL8s0(P5_-si+x?jPa&F=9rvd#|unp~i;=o3#~qtP|? zK8FUMtfkH|LCGAyf4=7j6~0`jHZ-$qb7gK*PHS@&W01n1*>-l?)J#K*;+RN4F-KxxF_ zS_F@aDS_ABYZ*_g1}*P;hjBmS*%;*YkeUi>54t4o^B2(mdhzNyah71667uRw`_Sk& z->`-kZcuC#x`JC0FThOe(0Fut`WFu?)N`eB(!s)+g+GW1rR5ln_kY9*ubzf^y!(w|rNqzA0n z3>(I}qU09;#2xEy_ZqNd)`31hFW_rIgZsMWM?WN7xBz0m-`o&;;P)q5S5-9J5nbn| z&kE$$X@nA30dt#b1Gj!x0mcFPW4Yn{gB<9D$pm zaVyj{fwTeATB`gT9WDw&+s$gn#veE;bi(pkBDv=RCDM`%Kuc~-k_Xe4&ClaYop39v zSi~Ev)0u;lLjI*;zrwXf(x+JBdy*X2lI9j$J-CC{&eSh@brjQLmP4%AUMlm>g${8@ z7zV`LtIxlaEtqIepXvC_1duM4E+Z)rT&W*#mhHBUL?bkQ&;5c=my~qsRd#VjA!$@6 zPt_%@e}I&t;!jmkqe=hY^X*ZAi=weahQz3=$;OF|alSaI+6hb`ATHspwrA^&%@KK6|xP^3lJ3M`dCKwqq&^9gMb z_-T0f+x9mxlXcy_lV*%5ntB$v>?(etjI_z?<10e?rh>1Af zCm&P>i$6C`IS@f;94X&V;v7Hf}^ERqBvhJ}@1(mCf0+3PM zpDCG`C2Z4%jREuvcA>v6%@wr9H|0pH^tHbWUYSTwp;=aOMb_<1X%N{XmPmMd$iMUJ zv*K)PCfaH*&wa(kv{cun9Rg=_WQ+(*lJ7)Ef@4q-?)--DKR|;SxsuHYrS?Ujz><=( z24iNkDdF4q4g+h4(}t@D-X+bRHin-fEvi$RJO-~G(tBg1p99&S!WW^jeOQzGaZa5a4M)Lkd7>|F8i~6E)~o za9{lLpQlbc$8F7x_F&rf?BvJ;X(s*{hS$Lay$ZWjcURMvg$98qy&4LvI(?a*8uY z0MBNz<>^v6Wq0(imOblleVXYsmxU>_c`bZ!K!N^VCde&hd&{&x0@tX}aWL;;WuNgFlrZrq zoHT5Hhwxdbu471TGGKFo|d!{Rld_JRIQ1w9){iMj59#F}Q(jR_`HJA#+&%>t;pN>hvoYtE=2Yonz9wkYc^_(|6Oc0K5B zd*93C=)%n|=#ey$D;r!p<+&NF$inq4~MBN!_8 z_s>rz`mvHN5j>e5v|ry-l{6+lOYHq!48$0p&R-;;*BGcyA)v=}gBl!jgxb7)vGr<( zmqJFS*AuNUi#wi3V77EZ7tdk;DqDpTVBfjWI=DjUCS{h9I8z0!w+YCT&8#k5uTc8^ z60f#NE3oLNZ7cc+)*&^25f55SCg36Y!1;18ex0AsbG=3Krg^1rT<`IYY~WUvhz99x zW7<4H$3A1YbA5LUdj}3AX)Hg+R6a%)6G!0LR6BV3z+n7kVUlIyvvRl8f;Y7h+=&ZtUMr62*_Oy)2GY*py>%^ zrB1;ltw|xV9Jsndc;Y}Pf%~hZdRpJ)sKDI{Ny-cnzniI8O{;Ca)w$~wZPnli}nr-ih9;TcA6ZOn* z3^#@JSx#+1ruwZF79PN?1ldua{)+$z-oM(t+FH08^svabCBUt99)z$M|=gEjB~(m8-cE`lx2jtYWWU30czb#xh~5cpY>Lp0ErZ#EcI+Yj|a7IYwj*@art zfM*+-x-vzO>d{Z^Iia23il??j8#kj>#D2SM7d&uLNO|xMBJ$g*-N9SWL~BIZu?xe{ z>vi}oz8ilE=-?#>sccKKa6L;X9f8Lef1Y=m{v1e=A%O{hg+&;wB$B}HQ6Rd=E`F z9Z>2)fhiUp5?scB41M>XJSNX4v1veY8Da^h0dA{)Za3-?1Z9}N6PY^Aku&c%F_{_I^UOF;tqAUXyNm1X>;KDSC?n;JA?<))S-a z@XmlO3L5JCy5b%#4YZC>F!l0EQ0qe3ygtZL%CXC32ra17Rbo-rw__?*1FQ?SvUhfZ zzM5<+L(4Zk>kN|Aw!I20G`Is^Ap;VVKiRB{EiZKT?F}_a7EclMrtfyKD8C$tqW9Es z&Mucnjb@UW<@_Ra>z)g-L2d`D4YdupryyG?Om*6opmE-uNM{<%P|j5@mph|nSG!>; zL`oB{TjANThLy7TzFrwTH8VnJ5ZG`Uk5JaCK;Pbbhn}qI=)ucqK0N0a`(r6sBu#O_ zm<6x&+ov+H#qIGxe9=|2;06~^sL@NIl*yemv(?W`Scb)rQn zajblg@bZJ@X>GICiF~48po|v@f_i7;rfi}EU6lmp*!V+W*ui|0tg!6zZn!Bc6r4$HF*RyyY28QyAW!-jNJj?_>aqGy0m&X=YS zUu0Q=-Y?QATH?JM@ea(IhV|4$EP!R1LWlD?QNkN2(Vi35?ZxHFO z8%~~Q@t1fwDV>BR=jb8m3-Ea}AbT(P1*(p~u*j{`C!wEOrt@|OE)LUBk6%$rs65pA zBL_u%G5UUV;nX_vafWUhM|IBbTz6{Z^BD zPQh`n7V?@t2HGEt3n25VCx}1?7|NuNS=Jc>Xe$VToesEg;A>ZtS^SSjlW<$F_&$FN znmmMZa9r@=o6)d2RcXSS##s4Ccupnr*OE$^H`={@J3f!E9o6i;%%1KUdc-@-k-U~* z35b9m3sZ^*6aM4Ig>g|aLT}I znP^Gy1)_MSD`k(LJ1>&`fIC!?3PCWv8}-Kq*M-+N>8X-@zTuuUXSrJ*UnSoNxT4KR z_A;bu0AO(tY?$1WO)kU93O!;s^x6uR-p@_Pewc2oIG7d4ORz5Zzi7J3ps4;fdY4=} zr5jO7TDn0%QbHPCy1RR6q&o!Z5UHgbmk6R2y4(ZUV{P*Rpnk;7Pm{A_7BCY3WiDb9*+J#4R)}M)ep@!+GvgzxTN)jsH z{V7sF2fFq6S6_pGRAgoypc#F(r=+0KIHLoy`Ne7RatyF=m)b`3H-T_nUo~*YnSUyP z3Py&23VszKbn8{c%L57G!o^m+%zvV79u57h$4J+QNWt3yu49)R&LMw%$HYY750#Au*S$CS z75W+rFsCs{C_=HUvGNOMZ*@%L)j=&l)cE(iDRdqr_jcd8mI(9oko@}i*bLc7^ZTr^<*pOvM<&cB`EO4^d16v7Q@NJNNBrBt~cxK5`3w4Pg~{ry)H zgXU5irgkFNU;YrCEg5bryR5UQ6NCacTjAx(2E=-_s`_v%d_2-^N+O)9I$i|cUNK=2G5YXHZ<|NAH5zVJ!`i3$jyslBVWaB#`wlPb7u5w^ybJKAqd$QopkPt~|0a98c3a=0X)2 zk_-9gi8d4QrWWMO~bnH%BwXDST z1PE!pauF{V2+fiEQvy##G=bRu@iummt~nPa-X@F3!v+U>ACEDG z&?w!)Gfq`PA-l=dJ6}^iDpfv07_4vl&Ik?Tul#JkBUjWgkn>7R4|}A(kp!>r0C%xA zyrP{6Mzi45r&-Fr5q;Xo{$T+db;e|*GzeY-6o_C-7wcZUt}ZF*ajtnkw(#$xy8o{6 zV}HW-`LO^+VUdQ53L2)AA36+Q2oh%+0u;Cv{r=JDA6ke zvY3do&uaJ!R%%r0JXF3As<@7r;W6y&_?bv5;Q1KT^5r;H@%g@UONY?Q;Sju95J~^` zH%n@KN0+9Z$S5P^XxZ-`(o8*ti2`LRnjghRM$y*%LxL`&pb&CCCWM7O<#!3ir#zP! z`H|-w8yz?Ft*WWA-FiQ{%(~29p+jGRp%8~JmeYaLg9~ixfrkS))lv zs7u1_<)i6m3UQz`tue4*u31y!VVJN{nELHdZSZ?~dbvr@iRkoIZE!%gL3Vnwy{F!L ze!n0@_E=2ZKR$lG6{P3OZeU&&b00|iQ148l_7!xwkj0D|V@hG`+jMmyOL(hBjHD6s z3tM7SX{y|i(zm!pFjw58yso5bTtp^e%iFY`>tVLV8H2Ugu7rFTYnS|!Da23r3dN~T zx66^{(?+4UL%UlaFkXE7h-S<0h>8nPv`of7G-nLTtHm^e)>ui*l_s6-5Gp*4Z)y1I zCv2>yOFCynj(8ZL>ATLGvhk}J=E?F##MgIWyBZlNU-Y7ILmu`pj_y#t9d=Rb)lK3( zmqg7e2)AJ);iGCa$QCc z#!m=AU%%*`Aw3VG#7B!weP1UJ9>7c%2598oe#|GOS~rL`x{uRorUej9c)}==`B{nd zV;8Gl?CqRrYpu!CZbexH5R)*3+qEQdo!XeXw=97kJ7j8iy$%dfHR7={7EO^ueqlNk z4VuO5>C$OYxNbv5b~!=Jv}yY6?KwzL0_g6F{!IUxJ9n`_6PhH%S(&P$1==A<@5m`n`ldi%v32I?) z&;foFfG^qSjw#YBB6fW!ldz3-MlsKz)!v#(rsCa)T1x#g5KPIyggPap+7@V?3W}XF z3U!T4DdPPh>=yR!b73=TdMUXJk*WaRKyR=KOTYN|>ix=f_pZe8ZU0NjN#6;>`$B@i zKYGEJdQWQvk85k(uJHv^I^Jmkhg^Ot(V6j!b&U-Ao~$@TPzcsgebM8zl8@DbB%^#r zwVD9hj!cnGR>-#IRya73o~SN8q-h7t1+5H5)>F#?DDsC5$` zAdvcZvazv&DRtB1d=u#$y{Y?e{QO@CreR!W>PwBWu_H_IT=!D!m`!bH9nlgyK`nD> z-w^${>NB_I`?f^;7S_2v>45e^T55eAv$&9P0OFNdNBzRYG0jpzxm;&A;`iN09;4|> zXNvQ94{1KDX3d)_fltLdEBO@Wx$Z)p0)B^#@w{5M?_C=l!)}j$924&dFJ605n6G{b z51yR}HXQv3qX}~ziRZJL8XxYT^b&fBQGs=WmbHSPnIC=p>${5fk7Me-szxdsF6UA1^V0WHGR>BaE-2!MW;fsX65gdn*pKjYT(OHPXXD>mOaMT)`1^p zofCh_7JzMsx4R8>F>~F^tU#>aI(~lt#ya9jY_^-)J{sfE36dc8ca=%83x?pf#YGSo(=F{RbPgQ7dfz;D*eVvAy);Qo5+4M(iEiQic*x8xPM=%Rtd!{^Z0q##Pfh zOEc)&FpoCjAULw^w%g->)MoAJdAZFUe7l(_b%Z*H3=&1jGooNP^260t-aoCB=a-f8 zsneUTQ~F)_49|M$>9fCCzTIt$Jdt<$&X~e00^}IveGPS1V%yGjH^YFc35{-f2>hbr*#kiU)I~!BkeuVRP%5?TjZtusf>vF~JH&ER!9nB&WM> zUTu=0?+3|)dnot^`sH8mHqI~-yy8zQGY{Ikm-fYHV4gAzGj0t0=yir!F7{gzZ9V?0 z)Vjv@u`(VD=)~^*xEh20f$RH>t#!W9v27+#~;uC?j4H3)}H>)NbozYy3@ z&%jR%#>(Rj%)3$Os(1W7f~UVo3C!HFU?$fH5u)3CT#=JJ@eB0J?!qrg`?5B5e$%57xaim- zaW=&KpH`hjL;Un^wk0!lUv`%%{xn*m3TDO7FU?WMKoc%YV%nn%tCe;jD8?n=QRH-t#j9*Q_nB_a;B;^#;g z)kq_M8cNSA-#yAU`xWUE7f|hjH~Kt*3eT-Z`&I-Wq-x_>@|-Ep8O6n}#{cc&jKs&E zfw31O2_nB~iHPL4!ifwuu0Ld54mXEJ%Rgvlef#1&|Nd6rc<;qbK)X9T({L{sYA0AO z{Pg=@nVXuj@FF2!cgpnB2^v+xil)x(%7i?;lYyxp7og%qgQye?Z2f&XCZa!Z9bCBF zdV4_d#qaU@8!Yt7C}HDwqgTZV8!3AU>i28r@6Az+qeRiogl28`Ond+INSg5g5p z@Ho()&KhM#s(F29o@pgn`_IN1k@Qk6XH(_$cjnfwIf(BT2!4C%V7<5AmKzI3CZ;gH z&PwTxn+)gMj41k`oB!PPkm~tf;RJfWKZUFJU90{-I6k;OJzPKaa{rSp)e>>vLG*mw z{w8-zr%wpiCIoq~-3GmG$zAsi$=b#(R_LjU5vkbQA`J5wSBVhH*EPx?)p(dt`V?*! z-RhD=DNQxFw6K=d26MMJZXql({`0t>Q0jyqC}cK(%jnKPM|D&tXi4^pj0uy$ON!tH z;vlvR`G&VnjdspHQ^gF~{5P~snB5F6nZ&EuC_{y6;GbyD)dPkCei|EJ`!IPV<7tXm z1`l19r3P9PKhVnmv@_&B0>hMO>9rF-NmnRPG@|IQ9#jlQfxE%Q@zKCt3Yv)03nuH-}LLldyuXFJvj+ly+|pI*)NBhCRF{C1A4jVcm3Du zu5>`Zxvl_`!`ZXWroI%XVhr}qN?OPQDR;AJDhs@f5z@!n1*qg>IUA?cB!&)bFZ$7e zwtMuP+z1NB3H*Y;HdfLWhwwK-r~ioE4O)cfT_IE2PJ}$Ozl_t6yV{a^KiZw@@H!@m zWk~@-mv9<2G{6|mZj0m?mh0Y2#(s-0Q_=ZZkc&iQM(P(mn*~M!&)*JVCy0SMi{&|c z48l@;#tjgr-dw*TXg425q!^$~DDe)f0@-EK?RMHjL}R7tr5)km7Vg!L2JQY^cWm!~ z1T3P{HnE|qdR4__?usTp7#G{!d7DVFFfjIR$HAL5b%nLmVW=D%!amxGi`nqnbNlJ1 zUU&YDO^`dIQraBgj_eRXG(u{AwyKM`4%E^uIor*zC{Xqp)^Vjri9QX*gpGyx(tV%n z3Z_AMXc*|a)VlnrK-6mD!9P@YkbQ*N@P`7yw>vYGA(J)^=UlIi{Y?6b?am9rfg?bO z;zCr%_9D8Pc?a84IFdnG_h)wRIuAA~A#Lj7ANhh`FeO_PxkbA+dTI<{EFEUMb}S(o z%h&#vg2;@){F4$*6^=q#`>EPgul0+;Ks~Sw_&My76fJxjEn(GV3K#bguLua zNH#mXeRQsw7L-N(?nXU8C6eZJh)1l6SkXQy8z)cl$C;-#B`y51D1*8;bD9X9hI$zn zlFwvD7onIJB17#w$?<-v5gt6Wz|V{_mryz`;Pzuqu2}GqG!I4lzAC$cRTLk& zqxs6ul8puBFzP`sY9lL*(XtRLYl{X8GglV z7pQFrWB43lz!=8QxmZ3zJ(oDgcgy~#4Y>U~HqnBl)#lM@W zXn$sHhMOmu*W8e0zc{TMfs0D;7?rQ=OgFpZX3-{vq#J?al;kt!!;*wMQ)=hh#s|ik zUx%(eKFzqJ_&=y3cQO>falA)G)IKvL@G~to8@fOO1U8=ZQ0pEA^!Q_Mb5B~aPa z=zIvLHy`x8E${<_XxF;Im={K@uDJaHMyuN-DT_S!n|wd+XARTGisD2{X#fxZ*O)B% zLDgv$L&s7Sz(}r^{HnRsfcM=)|33DwPjI=xcwyjEUo#ctx@{PY)sI-$zWldnb~(!O z2F^Sm&0ZAi^p}HCLB^{D6bGI$IObioVtmZOCVMaQ%(d^}H5_M(Sv@R@dP3q8d%>YY7)Zxn8qznHN(dN4(JF<|58nAZ`d0 zSM2|@RbSk5d?8{y?t_$dQtqBPukAH5rcImmWVgz87KGlR&`n>d!o1IOxBD&vxTzOF zYi3q2o6&HlUIbuRY46k@y_g_n2+qcL2xA$H@9&9k(t=wySY5wSX?H$ToM&S{lOZL@Zpw*)nMcTcWy~sWMlRpF~@@ax$MxOYM!jtUC z&_yd_dX&5OsYbAIh(izeZv8Y=0MaOCejW|?7R0sK;6}u&<(pxvOIh>lieyDPdYQXj zCm_|gM(jDh(IIY#32)8cKes(AFZo9dM#%{NTH=e%5Y2JrMA`FvK2WDBtwPIi`yuD;>?3kYz-DY(dwmFI~EHNdgRS=fOS;18$is3PcNcTjLW5 zoys4#3*zngt3p~?V=e7c;OI+Zu^XoEa4i4?*->M|I5!6s%%X@~cLNA;A0&8G zfq!DkYSDRt* zylITtfD{BygvDeT0g<+VR)$t61T5U`jvsoc(JT0x?D~0GAO^;m+#ntgU3>?11`WT% z8L=5ft<~iS`mg5$gv0xZ{mFKOj9M>hhg~2)ESDh$Ab7pqB^&@h%jv|2ZUDv61=Yk% zvq0och^O2)pU3`@nS5mVAY{GrqbeA+*)IoQ1*YK>0qFFVM#kSi* zN_~XEGSO+0l7}_%wx0Vs3w?2Lnw-Vpr|&J zFp-pf6!_Ccr{5GS=j@E*CrL&R$6kbF#$9^PtMOt&HNL)hCXi#mhOuV()z}3_%#;Yi zr9+Pe$qz=p9q+<7CBjLD(keE{JtHF?pc*5>`LwN_Nf^=4W_PwjV)YAr9_b2@E%08x zU>nYr5Db# zQe5*)LJ;TbO|^VukSQ8@a@yS;!?`BY5I=x~Pdn5RC_LdWoA#|-3e-dA!xJ*ayN=)Tb-sM;AK+=;~GN%+hh zO;{4auWdt*3YpREs|8soT0s(qbJMTHlU%G>>8KVkn47=@zRj5-dkoJ95|W~a;=Wgu zc2}-8Mz^Er@0`#tQp0`~I#qlRXO;is5Tm5#Fs#~*Dd-Atq-&tCK4+>|nk=yxVvh0z zqWk_1FpzDOg_L&TR*}HNRRge+S=NW}&_?hm+|zCy{1Ly=OH1c}h|T8R9z<`-{!EA> z+i(|v9*)4Xs%0}k;+CD@K#fY@NPfYBaG&|sXFu3;Yoi)$UTSR?>(mOV@B&#T8!U0W zEa!=M4-p_sk_}!sh9$(eVoO*`Qq@m`)?qy4wK4g$_n;{5O!AqMu)Q!e6D)7huhS*r zO^bi4iT#y#{b58@(TcO~`~%t~3b~9aP|O4O9F%RuhnB?+ zeFC{dKKS)jYIAv8L)dv2uHmx!LPbxR)M&k*JrEfBm?}a+`&Xs+Rd3IC?lPs$rJnKG z=zpzAl-c&Oa_|-aQ5sD1gYE=ub*OW0wrRw?bTG5smrvt;v+v zo8cIEI)mw&Lkg}c1$CLNxfKQ=B)0jE5bGvv`9i}B^PdgnOFC0H4Fzw;4_6O|=;+RA zRCf_$brT7gBPNhu_&g!2PBb}lxM@js7K3Dl%E<;7w2HTxafJ?hN7Z{O0!#k86}J&!I?7Z)nSo`zBwHR zn2OpT^`mD%u&<~TX(6}KP0v9P1G7bjYfr^zMw|W+5KkyrIa{G1&i1U18bUWB)H$_q zFg*Ks6dQakRbz64*eOK`k;m@$gvG z&-}j@pqj{nlGjQH44tPM^3|w)6{V$D`ZX-O2v7*;7^nv8uK!bhXO^X!Bw6!b<`-us zh^JxNG#R&Ndcn!SPm5sddom4c6qq4?bCVx?ho6UorQtQOtZ9Ly1^V97U|HiS_A>zj zhpZGWW3H%@vX#{E&z>q>kuK%wth`qz6ZyR8u~kA)%hF=f66Z^}@$@ykou3D&HG#9l zbN_;_JcsvT!c-CZsYN9=XCgd`Rx!j(P#y!vnV2oYVq_tZnE~D4m+;;q|%6aHQ8(_P`KeM9CUEn2kxF4BiQ!i^gD2s)hzx9FTP+oESb zIC4#}|^ZefM`P&EX{tRW7 z-Ft8HLgM`WAPl(L5&C}HR2z7hsv&v1`27J1Kp(C?{&x`>Kh=d(PTc9Vz=r|b#dg^v zIOpyI=pe-vP-p!>6rjR>^kNKN|J5P_4L+KX${bFZlR)=Ct;3 zs-I5SHVNb+Nzbh73wWe9;bb#fWic9@kN*pUg!fp_#8;r%i3ZBj_B80mMJlp>+VhqI zT?OF)y~?69U=vlQ>Jn6aTTHzYY4?!;7k-Uc@21Kdt+OPI&HH{wY?k_R%z`!Es^=1( z5{AxW3B>BfJNC&*E`*0h>)!{ZoeX&nr3bb0nLh3&eu-m!+RG-b6na zo(69VTR|S)$@p5W;{&G$qXwJxukUO1u}Px`TqC+?D9GSJr{uw>CdYoW*MY0oCT(up zvq6WmE0;Civ1g6E zr);?VH}+rz4*c820ZyJAO{Xv35l&)3nCb-0>w4uwFJ?rXK&p%^5m&7GQbft4g8o{E~?u`SzJ4(HOTBCiR01C63i~RG-**Eqn|I3#zm~=jCrQCsgyHZcLat6O&M-A66 zM?}m>A-J+o2wrRUnW~doL3qN;z?tW?mkbQMHz=}(ZZ5&y z-K<}Cxy8Z`4Cp(x=Dm3CVoy7*9tVa{4~(9hIcK^T-i#O?fg?b(m2XcSmYbY)TKTh)9n+h@k)T8I$64#sSNy1aJak5>btz0hwt~2>wAmO^Zs3SP zmX<-8iCzpzr^q!uzZ-!!BG2Dg2VhPoQ#C4Q;dWS4_s*k

@v-{3IPRGi|koEl8&S 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 z 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 diff --git a/figure/plot-maps-1.png b/figure/plot-maps-1.png deleted file mode 100644 index 29cefd307e749e74dd9d9eef2d92d241fdbd145f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6914 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 a2rRMn+9V?xSp^#aLTB`i^>R;MzV<(EsqYs6 diff --git a/figure/plot-match-1.png b/figure/plot-match-1.png deleted file mode 100644 index 5d49f58e5f3bb9c339aaa98f3c88140ff157565e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42711 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ⅇyYN2yd-O;va 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�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 diff --git a/figure/plot-users-prodcucers-1.png b/figure/plot-users-prodcucers-1.png deleted file mode 100644 index 18f207c2736de83465ff50602ee55ad0eb740720..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12273 zcmd6t2Ut{VvaT1RfD#pvBp|xoDu^gKqoANfB}i?A8hR=cw)N`}PPzQHTE_XtYT+LXb1aotrmQoa5(*J+xIEM{vuF zw)|JQysw`KdUGh~%!!w8?tazbR~wgX=Ba3vE0C>p$gtoT%r9i*%+iq0M>)0y4Quyx zX;ZIIoG-XeF8f?grMCCx?c;aL(4#D-PTAWZuAU|1US-nj5OJUBNnce}wf71E zB1B5idqZ2|Fmn4TLimdZA5rI(<_mpUTBaL4*2CqzoSZoWKD@lV)%zP-7QvQ7rOWkC zsZDYYUza^h_ugr&_6Q|qSmd4VJI6>#DNhUN$5;_u{g5n9OjOvQuIIsP*`FI9AK%s0 z^;*;|GAgQiXC|Y)z1@eHlKGl}ucrn{XNk?I@IvXgHvUofxx7XSCZR%`Q88LtT17=g z)_Olu+EbS`o<~KQ3WVh!tgNiiu&b4pm90;88g9%D=y`5Wz$@V0p_`*#dMVvUh=>mQ zy!QJztM^tm25p?CyOQ$rx%l{cgF1+8XTOq>b?we%VDzq-)f z-A&0Xvel!mca&8|R(5xDk<&L?)U9|d*Yo&(&U5xrpU;(UPCt*$j~_oqu9C2RF<)azMHG_=dHhprHL^ zyQ=?U)$Rh^(B$Ogs^yQ2uV25G^e3a|F?;SQz{WN+UotvU_)r-R3ya{eFdM;+VW-jk zzUqUXfq{X+LAS|v^zq}z;To4~{YW9`N-X-aYih1TOu>q!Bqa$72&DGRC@j)@Q%R6S zj3u4WO5D3cilEYLMyv2~{a*w!1a~t8;*a@xtL+e1S64n>Uf2TnJ-dHQ%*@OzEa>X$ zTF*-e$s{RlZ*8fls`m8uYGNWomBfyDOtjEg(01K3FVf8DQBzUrUzxPUHud$Dl$Y=9 ztk3pdIm{ozeHHNzC;6Xy__W~@84(cy%O??7US3{USct`90|NuY!^2Gy+alRGIXBnW zdDY1gZ><2A_L}tcbY1u5TgF>(zbPmwy{40*s&EIpv9YlxiDhMF)6>%|o?CCJ#=oQ~ zH-@qB%MwJYsHveQy>3e5k6G!>#ZjC28RVl@#RM@?%l@mZ zH*eo=Dzl%A4f!!SnUb7rjV(+oF5aklOvr8WY08=4)Q_1NAqaS5=Z@E+#>U2BVmql^ zuDkOkS~*vc(xPbA8W9nZAMNPfT2ju7i4cYiAyOo7JI&y{V?z|8ud=eUvx|vUy?Jv+ zNJukDi9UN~ydhXoWZ9Q1{^d(9mzD1*bzY~1q3XQ}PN@qz7*t#R6AB6niNI_fOfjEi zU$zcJw3YEz^MwQv_pMydLhkU$$c_2IzNz=72_C3{eB&&RRFRV38IDV=O?OZ3ZLe~$ zERI&=IuoUB^1Ir5l4NNou5+0m>}}8XW^oIp<>z-bG&EE+R4mn!X3ej4rzr03?v@mP zB@erD|Dtph98X=&o;|COAU3?R{N~M@ckj*?M4hCjR@TtyUs)cssowt-!<`(}W5#1` zZJi~rlW)`A<#lq}G)aWZLi0R)sgN?5 z`#{p%e5TlH(A~p>`oxKFV;vnG=@5n_vH)M-FFidm{m<)KgXQExgm#tJti+@)@LoPZ zPoIj{RphRGSo!gz6k4J0V~mzz`SHHlJ}ryiD!!&p>uO6YR(vSl^*`#g8A<6idZGT( zBx855ZV01;Pej~PnIt<02L}<`rY~}uoW~i=9fE$$YLA)C2=HSAr_m=KjT>1AH@Hk> zkY^{afrDf?tQLnFJjF|SBW(srozMz`Y}$6+@|f%Sj4LaQn?gSD3p>? zS36qx+_`hBtE;jyGU3$*g_`ql)7CQ}?)mdrvzob>!-AYe*xq??@bK__`SPXkQ9B3@ zU;7Y4cZh?dqv%y*3F%&&7E;b4w@wPwFp4drrKe||h&#md?laF^kJ+D>wQ?I*6}HCj zsp&2m5)yLCZAK_eGplM@4!5d}=^I_S#8oNnOZ71ECAPARk&aKBjB%vumi(f{p-i7o zEc!=}9)(@y=jTUAO!38xr%lR_%F)p=DJiKgfRa|i$i(CrtDLqS0aA0Z;7GqkPGvHg zfUq#9cIjQ5bHP1U-{9cZ!iU|yR3AQk0M+DGCxDF{wB1pIG`-8qyLRP@g7{E>e`@vE zMA_tPx2>^&EOiE3!^3p8vr1_yI~~66t8M(Sk^4r8hBDMSGa`-@k`oXOm7hL+dQI;} zuKV^1Ea;Rp!C<2k>mlU*O>cs~d#Kk5^d^63W+vdg^rrL9g9i^hJv~ol6XzNqrqh>% zZPkly4Cu?e&;4jTqzX-68bPJ+O%4gPb*wHRVhrSHZf?$Mu=rBq9!l^t839p06)`dK z{-Uglv$KGp;Ih5)b&Jxcgvgom?KRJAMIB1B3Ut#?_F32n9~d&4Rtvn*6Sg>n?BN6m zf8{y;_PLJ71RHV~yN8UEDl9uvjz!7ytHGV_*Un`=`-h@iN_sr^;(DKp6}o8eWopJ` z359pBEfEp&`~<<@KJY&ps%VkPvuv&okd2Rl!6nfwvYl0cur5q~WD;@0CM{wPOYG-+t(yzN4g*uq0awedQ}!oV~6n zB*Za9{vZSQ{@E24&%U*$rC!=2nH|Z5av8Xa+{)aP(7EI&t+M095i>ERbcwItl@Irh z1z{J}MlP8N$5G_Y%$QRv4|AvmY}3u({wP%+vJpz3rovXFIqWi95{K>zl~R!q8IFnmJjcI^4+7*R(f{>px}bL;B{b>&`^I9oXto#S4byNjJ; z=WdzlQ3qqy&M_InOXSZLHzyO4l}_;R1kQQjn61rETF2rT=UE;I)p%<`y!D^p=U?ut z*20inrx=o={QK4Y(?a|czlx_EYE6S9C&y;Hw4lH~>Wa=~JxV0)xPESY47cgRKtamH zx6KhZ8!0LOiCKa(yobmlxh;A#iJ6_RlPs@xi05b)nUB@_fjK)Varp3I4Ga&m!djy* zcuqQ0g(&p2V7_@zI=mRt47U6{!E;*vN66o8jbCk-|Mqj=jW&2aHwH`tC|OQPsHmvC zfB*jGty>(r75yC@iX?eP%_qR+*2T28wt9GYwCNHeH48D~H6KG5`K^ZpSnDCLd-mx# z(a_Rf_<67^+uPf(uB?DCf{rMlg&Y@#${y7D$5av_-oxBp-k0p`?dxi5hlYk)T3Tde zWO}o87-?zw%|5@`+uH-hl#k;Bhr=vjtN-yCy}xWvUtfZdqYVAV^72Dexe0N6ywL2? zl8Vr^@u{iQy}`(cRF!m;O)AHnNeTo;ZK!KroRp=qsc4zo#+=K}bc!DpWV#nGUVxCW zt7T4&RPOp7rOwaKAOH4^^w_a?iHULhqbm3AU2~jKF?QZrn}&jfKkq44fvu9;#l@w_ z{q9Gpo9vZ^FVr$r59XU>J~ddQf`)m{K3g~752<-3biM|zqTFHnomz$;m1F>gD)Y18 zV0Mtn+qa{Coikl3Dl11lHg$~qM@Oq6pVzBt3n#8Am=vC)XFQ&@)+Gfdq@~*GKBT^t zr6se?V(X^A`bxT$wY5Tx^QbiCLvvG|iJT!B7=d+yW zdisAWrT_`wvR%f9d?1W}t?f8?E*-wK49^ zybt?ldM>Mw@Gs(snt+OsoSZx)D99DJzv)LMgkFd-eSMUYvKkCM6w2D*j_ja(-T=dN zkd0Y526q4F1_b*7S)c6aQF=bh==?x({QW?Xg62=3hM;VMM>%jJvwfjI0!74X_~XZn7D$x&8wbMtsKI>F@!eS}PsTvmEImyn`@ zLTFf6*qAHc+u-emMqvQoH_@v|F3UNoXZ>K6t*orz(%s$nCR(GYsi|?>9bU&+LF!jp zIjiZ=DHERMMOn?o;-$WQ@FliIA`+i$P zBf7fUOGYNh*v*_>nc&pv)9@ZjMYIqv8(WLP5ds98s#om^C)&pBey}~6;C0}#KlN5J z0HhIYma>{!WOVe@#6*wX>lcu#P75m0k5qYJxNq@AfT~>coZeT4~Sy>aM zLZC>CZU`bo9G?#m6d9IA{6lEvjn#0MDV zR`4la9v-Mz*X9Pe+1X`DuDPrj$@UN-*E8hMk0H+VSAVoIgd_vPfD(XN7-f0y-irn{ zpZ$TAZ)x07?0!^}>FK^y^ha(Dh$m1>tSzsc9_6fWX&^YEBo;k%Lo=)R8+%?5qdT>< zvvVoe=Moz|Q`5=z9O8|+?so|rk>ST!9fZaf#`j8|utX^CjCKnLB81q+i5^;^eCJ^n zU2gUBk)~`l%+6mQUo-p&yJ@7k`618`Fz_WB_j6_G4W;qSY@<%aJ4?IF4$c+Ohn1Px z?K^kIhB*=M`KvVgY!T*rTg!%xp)?X-`ucF2UN|RL*Yc!ekiJhUJF!;nt+WCxVF>yC z?AhAE!Clxlr`Smmq+9Mtzuv)0)XSGIAtoWf)}dyM*i@iFy!Wrs=$jW|+uAq)m&Dmr zJq-=La`|$h#(e~dHesvrCuih?ZCPJmubQF8p;P_^Fp_~W0g^fX^@ESc&Kf<`3QBKxn|sQ67Jyc0%kFK$_O3;d_9d}|rRFh@0yD|UmV+aO5XLo&;-}dWu)|)^G z)U!0#8^sSEL6HxrDh0rX=N=xH9Dq*X1(d@}MVTbepdkp<(QA7mik4GXyV7+%UeLa3 zYdmbXL6-1Yyt`V+GNmoTAXy)MRT{{vk?|*U)^SrltnaS6b=}-!2i@-`@{{Q()Rb!7QRda?PlTsxHP+2u(E(fH5yG zPa+VM43wh?Uf&qXBta4)m8kdjCBVA2ojR6-rFP*(k=?lhe$|vTBu?Owfw1R(MrNkv z@^}M?yhPx6*+>#rK&<8#7NAs0N=mV9+Pb<6v$JjmaR{REGB`Mx>K*JkP?@77Bm#Ed zn+PdI-aPx**f=>kDZVq67#bQ1=t&|lQ96u`n?=;sVQXoOl=cc41qCyY*E*KikncBamgfqr>T9s{4b zWLkR0JGXD&&0d^tLkp|ZgCEAMP(+^n?KdNcM1Ole#^GwOYES3EVk-{yRM1X1ETz+u z4_Si1?~FlYg#ZoVuyC-q4}SKHjFeO>&*0YP!f-}LMg;q7kj(US^IG4du)x5lVJ$m5 zJJ}{Cc@7ejlT9G>TbAD6c|}CdU}PXEHNsQq(xTk?>{$qjA-<-QXvZ6&2aD3QpOUgl z+g# zt@&Y$dUg8BiXAoM%jMuKfLoe)n_H`aH(AdMz}DXE-|b9lWI~uAA%$b)PhL=nr-L=q z>WzN!;y5ECBLjn`rX~Y$Gd(@rw=nUIh2dQQXFK+#Ko_7uLJK=dNl5{5j0z7weB_AZ zdvc^E>!XTy2m`MSy_vbWD~Q3Ma|qX^OVj(CqqGv>EP#-~E0a=EXiuG@I4y8jFfKbI zgPnsz)svZQ$&1wst*pW)NMfmyf$8w=ugF8>b$aneT zMc5%31N;&M$ef~@S}(K@Qppzk^S(u>>ppB%Dk>_n+G{w$&Bd$_x>yY#=i}p34Jrv6 z4FU>p1n_pj7VN@cUw=R3j#}snwAT*u9x(S)D~cRvVey*!%sO#FWdx+XRqY6pOCt_; zsVhl#c4p?srx1gKn8!5_Bx)gb<|o;a_RAo#vmVoRqa3HD3-i09?v27*&6J%{N!S5%3u` zJ%?sUg0Ry<2>-}MHnws&c}T60W;yOsAvNV|izb%{L5Z>X#;v7~z5!te3cQa8&+A{5 z<>lpD6h(gj?KcwE@OrNJ?n92TXy@y{Z_$<)xfcW^+q$dv}x$ne0cIHMZ zwdnCV=nuyQT3QTS3)0Z@=g*~?UGSO&9TC8U5+nc!_Ve-Q`GpTXQC3>|j0t*7{ds5| z*cRmyl9I|wO0b2&K!a5ke>7eX>!A?C)c|c3NJG#P!@=GHBMg4r-Q7KwgOQ5rO+xpf zB+YTI^T_qH)wumdFWm0vtTdQtIMx$Eow_MI(87JTA582~#fXJJ`?-6q5%yTK`f z>jvruM4Fhx8LTzPbv4bbUhH`d>L{xJu?jSQdX&%}g(^lJH8D|S8u*LaVjkA>4LEoU z3Jy59%3*Vc}I{`~60uHVoKB~WYu8UwDqy|V+m_~NR7kkH0drzHIbAR^1~ zwKrA~Kk@13K=S-JT{-^o??wl>$2OOKcW9TWfXoE06Y&Ah+tkLAn!f{xA*z; z=dLcLiLQ54XN84@FI{>FR|>FfdwUy}=*Ep35+u-82h%sJt_od914+$-sF7{xjr}s8 zLZ=sxCAhr2_o2cR$L*~`Z`6+pnzn%X{$K_m7hqm~b`C*M0NInWa&dF}Q9&(Y!byne zk3s_j+74D5O`u|A(mLAO$?|c~IHsVm7UV_{s}KJ+X!P#@Q$N20PeYPRF&HT6xC`)< zot7c*2C5q(#30U6s0KP7CI;yr{~-&~*3rQ)dj2$GVQE?T3;9`Q{x^`Ve+fAKdMxC> z{wM`><>NoMot6J!)4~`a%=^=8+__LY35kg8B}M7(05`EPHwWYlc@i?YBx`+|a!M$a z)B`Y_GN+V6+&|r&0@a8w)nA)x$jRn^m})45$xN-y&C6F+^#Q{fR%&40 zq4ML<|BJ~P*|eY>cFxyB8ze;PobP8d9_Zmy|1Q_m(h?LF#(D8#U}&gyF==Z{3$yDK z>wl8wAJ}&G^6ssztwKC${yP}>u4~!>UH%vhU`8FTwEMgt#xQN%pJ5JP}UzR)XXXhy^^J7u^obar65iSBDlTW$O5>* z1I*C!w?=kK6I0U*=g-d%l|cgM5*M$2|Ngg&7jKh{LEGK@%f3f^ zwgy5B6%Je939w->lLEbpE51#iKAn`<+TC?R(Ibd(_jDAMa4nmuK1?RSH=%4N+5n^v z4-d0-ymf&_6bnm2dODl1z@z1*B`OKPCJk6Whj1_g=0!9#G{t)?w;4fO)zsBtIfmKd ziua`EkFppM{bKOw|2C&KCwnP0uoYVlj4v#B0{Op>c^TYE$Gb@`iS3!+sJ1E@wmOzvuH zS3LSACA{Uw$661aoZz6KOr0ZGpa1j+n>Dc*=Vd^Ei6tc^MWoZIU?+jMZBBL8!Lq3+ zD|c_NPGV5=>78boIzb;N3FeWOZQkfL{hhr=aM<9p3}k>FnZycQRPNugS;t z5#-VxTpu;^wfFlLxJxYz(W(HH(h0b|NwAHlg;AGb5DMx>TS&?3uy;Y=)(Nfdn>sqK zLrx%~IBn*987<}YzZ{N`7!=+u54K7 zTt9*g57v38z%(o_P79Vo{!;}cRdBRGZlf(`+X`*MW(QO_U7>V^jXqrNh)GMbd{3LS zRZ&sVt1D(AekSgoZkd&P8(WW%fItOI5M8@=4FJ*8urPk1$>XO-pO8*E-3+u2Oi*+B!Qbst-OdE;jZ@TO4?8(+2+A*pkL|%XHex4G)n{ zDc5^J;%*z37TnSM-g6{LSQzu*6B8Th?p_@*O(;U$x>~DnXzue{$<1M>1iM~d>!DJ( zow89^Dz|^c!GHmPHIKdJM(7%WJe`2Cj>k~k;$icu$7aQ zRZdfBOLyI0?}JSK&|EPFgBi;oEU}>^BLnKP2e6Ng zogEhaHBkRLtAQrZYuHvOR#@oh%rrDqRU^h))-iL*6iqM;=I`rE2K=BcmKWxW%ye~M zKe*#B9S93*_ld4pe=BHdeZ7YgH>-y`Mn?9jy}inP+YWXMAclgJ9T*>h8Z=ufvCM8l z25`$DsXzTd^Lc!c;+}V8rtx1p_fB>7Rsi}a(p}Pv1WF;lRv&*~)wvc8PepbqV zb{huZpsfVx3~Fy4{Tgo=Euw@W$5)zHI5|fvTng-t-b?AeLx2nOZ%rNTAG?lVb+A%W33YcyBMzHo7+%O zWxSAMOGn2d6u9_)MuOXdAY`A~S_vB)n>u5~*CJ4v(?eew%4R6U|`MJ1O^l&>-5AJA{ zSog57!faRue)rQA=NdLr?6Z$Iy*Rfs2A|>V>PmF@@YeP=Io;JW!orw$?`m_gpl0|& z7-$N_8;FIrMBy=ELBiFI4K?e#r|>Dr7#MQ(!OpBCrRZRco>Gszkn2 z0IMO9fr@ZkzAPsrqg3VF+|V$Q7$yd8CL=Y~4ApH?unw(ynv*A?c?IL9KslZ6-Mfdz z7LA>+2h+|!n+m-x89)42fYtV+GB4VJ8OYtOZ(%UaDhBQQf<9%yTue;p=g)1oS0=zX z6u~>%UMGC;AqD{eCJd-@8ML%TT@ogW0KW2O6inD#I}q=KbicZwcuGPpL9B9s+g90a z=#=Ymi6PJ3c?l9Iss8tPXm4mGEP}6}-#Rd~f(|k6p~#Rq+QiDj%b5c$(10Gai!PGF z?a@UVIr{=LkSuf-WUM+XS1lB)>IOr*#*(Nda?_Rk17nYZz>tvr@nB8{1_oa$SeC4u zoXyo$hAQ@}P#!{G>6VlfTOwo>aX=3+nfrMKJ#R8ge^noErvcW3 zkU={ECF_aNYz+;^ec0dMUj*Wm^4gW{>ebKC$A0rh9}EsBjM>3XG2dWNh!=S4uJ{t> z>jDBA*Ju0URC|C(K_LXjWNFEkwf^VSDo~jjnA|H6(h{4La(eE$?{%=6fC2NiAZkro zNykw)mA45UOcp^qBe>Le4F^RNx|-&)%ly!(vR$81O^S*_{#YX9`9 z@cS@J8{4Ie7wQ{Pn~!5ANa93^e3C+*kQ4 zkzV5qQBFY3G9xcEX?pD NcWx=%%$Cr9@*fzS`i1}i diff --git a/man/MOD13Q1.MT.yearly.patterns.Rd b/man/MOD13Q1.MT.yearly.patterns.Rd index ca1ab92..8e73786 100644 --- a/man/MOD13Q1.MT.yearly.patterns.Rd +++ b/man/MOD13Q1.MT.yearly.patterns.Rd @@ -12,18 +12,18 @@ MOD13Q1.MT.yearly.patterns } \description{ This dataset has a list of patterns with the phenological cycle of: Water, -Cotton-Fallow, Forest, Low vegetation, Pasture, Soybean-Cotton, Soybean-Maize, Soybean-Millet, -Soybean-Sunflower, and Wetland. These time series are based on the MODIS product -MOD13Q1 250 m 16 days \insertCite{Didan:2015}{dtwSat}. -The patterns were built from ground truth samples of each +Cotton-Fallow, Forest, Low vegetation, Pasture, Soybean-Cotton, Soybean-Maize, Soybean-Millet, +Soybean-Sunflower, and Wetland. These time series are based on the MODIS product +MOD13Q1 250 m 16 days \insertCite{Didan:2015}{dtwSat}. +The patterns were built from ground truth samples of each crop using Generalized Additive Models (GAM), see \link[dtwSat]{createPatterns}. } \references{ \insertAllCited{} - - \insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} + +\insertRef{Maus:2019}{dtwSat} + +\insertRef{Maus:2016}{dtwSat} } \seealso{ For details about MOD13Q1 see \insertCite{Didan:2015}{dtwSat}. diff --git a/man/MOD13Q1.patterns.list.Rd b/man/MOD13Q1.patterns.list.Rd index 1a84770..697a86d 100644 --- a/man/MOD13Q1.patterns.list.Rd +++ b/man/MOD13Q1.patterns.list.Rd @@ -5,9 +5,9 @@ \alias{MOD13Q1.patterns.list} \title{Data: patterns time series} \format{ -A named \code{list} of three \link[zoo]{zoo} objects, ''Soybean'', ''Cotton'', +A named \code{list} of three \link[zoo]{zoo} objects, ''Soybean'', ''Cotton'', and ''Maize'', whose indices are \code{\link[base]{Dates}} in the format ''yyyy-mm-dd''. -Each node has 6 attributes: ''ndvi'', ''evi'', ''red'', ''nir'', ''blue'', +Each node has 6 attributes: ''ndvi'', ''evi'', ''red'', ''nir'', ''blue'', and ''mir''. } \usage{ @@ -15,21 +15,21 @@ MOD13Q1.patterns.list } \description{ This dataset has a list of patterns with the phenological cycle of: Soybean, -Cotton, and Maize. These time series are based on the MODIS product -MOD13Q1 250 m 16 days \insertCite{Didan:2015}{dtwSat}. The patterns were built -from ground truth samples of each +Cotton, and Maize. These time series are based on the MODIS product +MOD13Q1 250 m 16 days \insertCite{Didan:2015}{dtwSat}. The patterns were built +from ground truth samples of each crop using Generalized Additive Models (GAM), see \link[dtwSat]{createPatterns}. } \references{ \insertAllCited{} - - \insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} + +\insertRef{Maus:2019}{dtwSat} + +\insertRef{Maus:2016}{dtwSat} } \seealso{ \link[dtwSat]{MOD13Q1.ts}, -\link[dtwSat]{MOD13Q1.ts.list}, and +\link[dtwSat]{MOD13Q1.ts.list}, and \link[dtwSat]{createPatterns}. For details about MOD13Q1 see \insertCite{Didan:2015}{dtwSat}. diff --git a/man/MOD13Q1.ts.Rd b/man/MOD13Q1.ts.Rd index e1969fc..ceec72b 100644 --- a/man/MOD13Q1.ts.Rd +++ b/man/MOD13Q1.ts.Rd @@ -5,25 +5,25 @@ \alias{MOD13Q1.ts} \title{Data: An example of satellite time series} \format{ -A \link[zoo]{zoo} object, whose indices are \code{\link[base]{Dates}} -in the format ''yyyy-mm-dd''. Each node has 6 attributes: ''ndvi'', +A \link[zoo]{zoo} object, whose indices are \code{\link[base]{Dates}} +in the format ''yyyy-mm-dd''. Each node has 6 attributes: ''ndvi'', ''evi'', ''red'', ''nir'', ''blue'', and ''mir''. } \usage{ MOD13Q1.ts } \description{ -This dataset has a time series based on the -MODIS product MOD13Q1 250 m 16 days \insertCite{Didan:2015}{dtwSat}. -It is an irregularly sampled time series +This dataset has a time series based on the +MODIS product MOD13Q1 250 m 16 days \insertCite{Didan:2015}{dtwSat}. +It is an irregularly sampled time series using the real date of each pixel from ''2009-08-05'' to ''2013-07-31''. } \references{ \insertAllCited{} - - \insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} + +\insertRef{Maus:2019}{dtwSat} + +\insertRef{Maus:2016}{dtwSat} } \seealso{ \link[dtwSat]{MOD13Q1.ts.list}, diff --git a/man/MOD13Q1.ts.labels.Rd b/man/MOD13Q1.ts.labels.Rd index ab2fcec..57d6c23 100644 --- a/man/MOD13Q1.ts.labels.Rd +++ b/man/MOD13Q1.ts.labels.Rd @@ -5,7 +5,7 @@ \alias{MOD13Q1.ts.labels} \title{Data: Labels of the satellite time series in MOD13Q1.ts} \format{ -An object of class \link[base]{data.frame}, whose attributes are: +An object of class \link[base]{data.frame}, whose attributes are: the label of the crop class ''label'', the start of the crop period ''from'', and the end of the crop period ''to''. The dates are in the format ''yyyy-mm-dd''. } diff --git a/man/MOD13Q1.ts.list.Rd b/man/MOD13Q1.ts.list.Rd index b78f8ef..d5fffb2 100644 --- a/man/MOD13Q1.ts.list.Rd +++ b/man/MOD13Q1.ts.list.Rd @@ -5,28 +5,28 @@ \alias{MOD13Q1.ts.list} \title{Data: A list of satellite time series} \format{ -A \link[zoo]{zoo} object, whose indices are \code{\link[base]{Dates}} -in the format ''yyyy-mm-dd''. Each node has 6 attributes: ''ndvi'', +A \link[zoo]{zoo} object, whose indices are \code{\link[base]{Dates}} +in the format ''yyyy-mm-dd''. Each node has 6 attributes: ''ndvi'', ''evi'', ''red'', ''nir'', ''blue'', and ''mir''. } \usage{ MOD13Q1.ts.list } \description{ -This dataset has a list of time series based on the -MODIS product MOD13Q1 250 m 16 days \insertCite{Didan:2015}{dtwSat}. -It is an irregularly sampled time series +This dataset has a list of time series based on the +MODIS product MOD13Q1 250 m 16 days \insertCite{Didan:2015}{dtwSat}. +It is an irregularly sampled time series using the real date of each pixel from ''2009-08-05'' to ''2013-07-31''. } \references{ \insertAllCited{} - - \insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} + +\insertRef{Maus:2019}{dtwSat} + +\insertRef{Maus:2016}{dtwSat} } \seealso{ -\link[dtwSat]{MOD13Q1.ts}, and +\link[dtwSat]{MOD13Q1.ts}, and \link[dtwSat]{MOD13Q1.patterns.list}. For details about MOD13Q1 see \insertCite{Didan:2015}{dtwSat}. diff --git a/man/createPatterns.Rd b/man/createPatterns.Rd deleted file mode 100644 index 0bf8fbf..0000000 --- a/man/createPatterns.Rd +++ /dev/null @@ -1,104 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/createPatterns.R -\name{createPatterns} -\alias{createPatterns} -\alias{createPatterns,twdtwTimeSeries-method} -\alias{createPatterns-twdtwMatches} -\title{Create patterns} -\usage{ -createPatterns( - x, - from = NULL, - to = NULL, - freq = 1, - attr = NULL, - split = TRUE, - formula, - ... -) - -\S4method{createPatterns}{twdtwTimeSeries}( - x, - from = NULL, - to = NULL, - freq = 1, - attr = NULL, - split = TRUE, - formula, - ... -) -} -\arguments{ -\item{x}{an object of class \code{\link[dtwSat]{twdtwTimeSeries}}.} - -\item{from}{A character or \code{\link[base]{Dates}} object in the format -"yyyy-mm-dd". If not provided it is equal to the smallest date of the -first element in x. See details.} - -\item{to}{A \code{\link[base]{character}} or \code{\link[base]{Dates}} -object in the format "yyyy-mm-dd". If not provided it is equal to the -greatest date of the first element in x. See details.} - -\item{freq}{An integer. The sampling frequency of the output patterns.} - -\item{attr}{A vector character or numeric. The attributes in \code{x} to be used. -If not declared the function uses all attributes.} - -\item{split}{A logical. If TRUE the samples are split by label. If FALSE -all samples are set to the same label.} - -\item{formula}{A formula. Argument to pass to \code{\link[mgcv]{gam}}.} - -\item{...}{other arguments to pass to the function \code{\link[mgcv]{gam}} in the -package \pkg{mgcv}.} -} -\value{ -an object of class \code{\link[dtwSat]{twdtwTimeSeries}} -} -\description{ -Create temporal patterns from objects of class twdtwTimeSeries. -} -\details{ -The hidden assumption is that the temporal pattern is a cycle the repeats itself -within a given time interval. Therefore, all time series samples in \code{x} are aligned -with each other, keeping their respective sequence of days of the year. The function fits a -Generalized Additive Model (GAM) to the aligned set of samples. -} -\examples{ -# Creating patterns from objects of class twdtwTimeSeries -evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) -ndvi = brick(system.file("lucc_MT/data/ndvi.tif", package="dtwSat")) -timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") -rts = twdtwRaster(evi, ndvi, timeline=timeline) - -# Read field samples -\dontrun{ -field_samples = read.csv(system.file("lucc_MT/data/samples.csv", package="dtwSat")) -prj_string = scan(system.file("lucc_MT/data/samples_projection", package="dtwSat"), - what = "character") - -# Extract time series -ts = getTimeSeries(rts, y = field_samples, proj4string = prj_string) - -# Create temporal patterns -patt = createPatterns(x=ts, from="2005-09-01", to="2006-09-01", freq=8, formula = y~s(x)) - -# Plot patterns -autoplot(patt[[1]], facets = NULL) + xlab("Time") + ylab("Value") - -} -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwMatches-class}}, -\code{\link[dtwSat]{twdtwTimeSeries-class}}, -\code{\link[dtwSat]{getTimeSeries}}, and -\code{\link[dtwSat]{twdtwApply}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/create_pattern.Rd b/man/create_pattern.Rd new file mode 100644 index 0000000..b13837a --- /dev/null +++ b/man/create_pattern.Rd @@ -0,0 +1,58 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/create_patterns.R +\name{create_pattern} +\alias{create_pattern} +\title{Create patterns} +\usage{ +create_pattern(x, from, to, freq, attr, formula, ...) +} +\arguments{ +\item{x}{an object of class \code{\link[dtwSat]{twdtwTimeSeries}}.} + +\item{from}{A character or \code{\link[base]{Dates}} object in the format +"yyyy-mm-dd". If not provided it is equal to the smallest date of the +first element in x. See details.} + +\item{to}{A \code{\link[base]{character}} or \code{\link[base]{Dates}} +object in the format "yyyy-mm-dd". If not provided it is equal to the +greatest date of the first element in x. See details.} + +\item{freq}{An integer. The sampling frequency of the output patterns.} + +\item{attr}{A vector character or numeric. The attributes in \code{x} to be used. +If not declared the function uses all attributes.} + +\item{formula}{A formula. Argument to pass to \code{\link[mgcv]{gam}}.} + +\item{...}{other arguments to pass to the function \code{\link[mgcv]{gam}} in the +package \pkg{mgcv}.} + +\item{split}{A logical. If TRUE the samples are split by label. If FALSE +all samples are set to the same label.} +} +\value{ +an object of class \code{\link[dtwSat]{twdtwTimeSeries}} +} +\description{ +Create temporal patterns from objects of class twdtwTimeSeries. +} +\details{ +The hidden assumption is that the temporal pattern is a cycle the repeats itself +within a given time interval. Therefore, all time series samples in \code{x} are aligned +with each other, keeping their respective sequence of days of the year. The function fits a +Generalized Additive Model (GAM) to the aligned set of samples. +} +\references{ +\insertRef{Maus:2019}{dtwSat} + +\insertRef{Maus:2016}{dtwSat} +} +\seealso{ +\code{\link[dtwSat]{twdtwMatches-class}}, +\code{\link[dtwSat]{twdtwTimeSeries-class}}, +\code{\link[dtwSat]{getTimeSeries}}, and +\code{\link[dtwSat]{twdtwApply}} +} +\author{ +Victor Maus, \email{vwmaus1@gmail.com} +} diff --git a/man/dtwSat.Rd b/man/dtwSat.Rd deleted file mode 100644 index ebbd846..0000000 --- a/man/dtwSat.Rd +++ /dev/null @@ -1,26 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dwtSat.R -\name{dtwSat} -\alias{dtwSat} -\title{Time-Weighted Dynamic Time Warping for Satellite Image Time Series} -\description{ -Provides an implementation of the Time-Weighted Dynamic Time Warping -(TWDTW) method for land use and land cover mapping using satellite image time series -\insertCite{Maus:2016,Maus:2019}{dtwSat}. -TWDTW is based on the Dynamic Time Warping technique and has achieved high accuracy -for land use and land cover classification using satellite data. The method is based -on comparing unclassified satellite image time series with a set of known temporal -patterns (e.g. phenological cycles associated with the vegetation). Using 'dtwSat' -the user can build temporal patterns for land cover types, apply the TWDTW analysis -for satellite datasets, visualize the results of the time series analysis, produce -land cover maps, and create temporal plots for land cover change analysis. -} -\references{ -\insertAllCited{} -} -\seealso{ -\code{\link[dtwSat]{twdtwApply}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/get.Rd b/man/get.Rd deleted file mode 100644 index a0aabd3..0000000 --- a/man/get.Rd +++ /dev/null @@ -1,56 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/getInternals.R -\name{get} -\alias{get} -\alias{getAlignments,twdtwMatches-method} -\alias{getAlignments} -\alias{getInternals,twdtwMatches-method} -\alias{getInternals} -\alias{getMatches,twdtwMatches-method} -\alias{getMatches} -\title{Get elements from twdtwMatches objects} -\usage{ -\S4method{getAlignments}{twdtwMatches}(object, timeseries.labels = NULL, patterns.labels = NULL) - -\S4method{getInternals}{twdtwMatches}(object, timeseries.labels = NULL, patterns.labels = NULL) - -\S4method{getMatches}{twdtwMatches}(object, timeseries.labels = NULL, patterns.labels = NULL) -} -\arguments{ -\item{object}{an object of class twdtwMatches.} - -\item{timeseries.labels}{a vector with labels of the time series.} - -\item{patterns.labels}{a vector with labels of the patterns.} -} -\value{ -a list with TWDTW results or an object \code{\link[dtwSat]{twdtwTimeSeries-class}}. -} -\description{ -Get elements from \code{\link[dtwSat]{twdtwMatches-class}} objects. -} -\examples{ -# Getting patterns from objects of class twdtwMatches -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -ts = twdtwTimeSeries(MOD13Q1.ts.list) -mat = twdtwApply(x=ts, y=patt, weight.fun=logisticWeight(-0.1,100), - keep=TRUE, legacy = TRUE) -getPatterns(mat) -getTimeSeries(mat) -getAlignments(mat) -getMatches(mat) -getInternals(mat) - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwMatches-class}}, and -\code{\link[dtwSat]{twdtwApply}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/getTimeSeries.Rd b/man/getTimeSeries.Rd deleted file mode 100644 index 2a0a834..0000000 --- a/man/getTimeSeries.Rd +++ /dev/null @@ -1,94 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/getTimeSeries.R -\name{getTimeSeries} -\alias{getTimeSeries} -\alias{getPatterns} -\alias{getTimeSeries,twdtwTimeSeries-method} -\alias{getTimeSeries-twdtwTimeSeries} -\alias{getTimeSeries,twdtwMatches-method} -\alias{getTimeSeries-twdtwMatches} -\alias{getPatterns,twdtwMatches-method} -\alias{getPatterns-twdtwMatches} -\alias{getTimeSeries,twdtwRaster-method} -\alias{getTimeSeries-twdtwRaster} -\title{Get time series from twdtw* objects} -\usage{ -\S4method{getTimeSeries}{twdtwTimeSeries}(object, labels = NULL) - -\S4method{getTimeSeries}{twdtwMatches}(object, labels = NULL) - -\S4method{getPatterns}{twdtwMatches}(object, labels = NULL) - -\S4method{getTimeSeries}{twdtwRaster}(object, y, labels = NULL, proj4string = NULL, id.labels = NULL) -} -\arguments{ -\item{object}{an object of class twdtw*.} - -\item{labels}{character vector with time series labels. For signature -\code{\link[dtwSat]{twdtwRaster}} this argument can be used to set the -labels for each sample in \code{y}, or it can be combined with \code{id.labels} -to select samples with a specific label.} - -\item{y}{a \code{\link[base]{data.frame}} whose attributes are: longitude, -latitude, the start ''from'' and the end ''to'' of the time interval -for each sample. This can also be a \code{\link[sp]{SpatialPointsDataFrame}} -whose attributes are the start ''from'' and the end ''to'' of the time interval. -If missing ''from'' and/or ''to'', they are set to the time range of the -\code{object}.} - -\item{proj4string}{projection string, see \code{\link[sp]{CRS-class}}. Used -if \code{y} is a \code{\link[base]{data.frame}}.} - -\item{id.labels}{a numeric or character with an column name from \code{y} to -be used as sample labels. Optional.} -} -\value{ -An object of class \code{\link[dtwSat]{twdtwTimeSeries}}. - -a list with TWDTW results or an object \code{\link[dtwSat]{twdtwTimeSeries-class}}. -} -\description{ -Get time series from objects of class twdtw*. -} -\examples{ -# Getting time series from objects of class twdtwTimeSeries -ts = twdtwTimeSeries(MOD13Q1.ts.list) -getTimeSeries(ts, 2) -# Getting time series from objects of class twdtwTimeSeries -ts = twdtwTimeSeries(MOD13Q1.ts.list) -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -mat = twdtwApply(x=ts, y=patt, keep=TRUE, legacy=TRUE) -getTimeSeries(mat, 2) - -## This example creates a twdtwRaster object and extract time series from it. - -# Creating objects of class twdtwRaster with evi and ndvi time series -evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) -ndvi = brick(system.file("lucc_MT/data/ndvi.tif", package="dtwSat")) -timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") -rts = twdtwRaster(evi, ndvi, timeline=timeline) - -# Location and time range -ts_location = data.frame(longitude = -55.96957, latitude = -12.03864, - from = "2007-09-01", to = "2013-09-01") -prj_string = "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0" - -# Extract time series -ts = getTimeSeries(rts, y = ts_location, proj4string = prj_string) - -autoplot(ts[[1]], facets = NULL) + xlab("Time") + ylab("Value") - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwRaster-class}}, -\code{\link[dtwSat]{twdtwTimeSeries-class}}, and -\code{\link[dtwSat]{twdtwMatches-class}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/getDatesFromDOY.Rd b/man/get_dates_from_doy.Rd similarity index 61% rename from man/getDatesFromDOY.Rd rename to man/get_dates_from_doy.Rd index 9d5e676..d925fdf 100644 --- a/man/getDatesFromDOY.Rd +++ b/man/get_dates_from_doy.Rd @@ -1,36 +1,29 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/miscellaneous.R \docType{methods} -\name{getDatesFromDOY} -\alias{getDatesFromDOY} +\name{get_dates_from_doy} +\alias{get_dates_from_doy} \title{Get dates from year and day of the year} \usage{ -getDatesFromDOY(year, doy) +get_dates_from_doy(year, doy) } \arguments{ \item{year}{A vector with the years.} -\item{doy}{A vector with the day of the year. +\item{doy}{A vector with the day of the year. It must have the same length as \code{year}.} } \value{ A \code{\link[base]{Dates}} object. } \description{ -This function retrieves the date corresponding to the given +This function retrieves the date corresponding to the given year and day of the year. -} -\examples{ -year = c(2000, 2001) -doy = c(366, 365) -dates = getDatesFromDOY(year, doy) -dates - } \references{ \insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} + +\insertRef{Maus:2016}{dtwSat} } \seealso{ \link[dtwSat]{shiftDates} diff --git a/man/linearWeight.Rd b/man/linearWeight.Rd deleted file mode 100644 index f4fdb4a..0000000 --- a/man/linearWeight.Rd +++ /dev/null @@ -1,45 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/linearWeight.R -\docType{methods} -\name{linearWeight} -\alias{linearWeight} -\title{Linear weight function} -\usage{ -linearWeight(a, b = 0) -} -\arguments{ -\item{a}{numeric. The slop of the line.} - -\item{b}{numeric. The intercept of the line.} -} -\value{ -A \code{\link[base]{function}} object. -} -\description{ -Builds a linear time weight -function to compute the TWDTW local cost matrix [1]. -} -\details{ -The linear \code{linearWeight} and \code{logisticWeight} weight functions -can be passed to \code{\link[dtwSat]{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 -\insertCite{Maus:2016;textual}{dtwSat} the logistic weight had better results than the -linear for land cover classification. See \insertCite{Maus:2016;textual}{dtwSat} and -\insertCite{Maus:2019;textual}{dtwSat}. -} -\examples{ -lin_fun = linearWeight(a=0.1) -lin_fun - -} -\references{ -\insertAllCited{} -} -\seealso{ -\code{\link[dtwSat]{twdtwApply}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/logisticWeight.Rd b/man/logisticWeight.Rd deleted file mode 100644 index df44b49..0000000 --- a/man/logisticWeight.Rd +++ /dev/null @@ -1,45 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/logisticWeight.R -\docType{methods} -\name{logisticWeight} -\alias{logisticWeight} -\title{Logistic weight function} -\usage{ -logisticWeight(alpha, beta) -} -\arguments{ -\item{alpha}{numeric. The steepness of logistic weight.} - -\item{beta}{numeric. The midpoint of logistic weight.} -} -\value{ -A \code{\link[base]{function}} object. -} -\description{ -Builds a logistic time weight -function to compute the TWDTW local cost matrix [1]. -} -\details{ -The linear \code{linearWeight} and \code{logisticWeight} weight functions -can be passed to \code{\link[dtwSat]{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 analyze time series with phenological cycles -of vegetation that are usually bound to seasons. In previous studies by -\insertCite{Maus:2016;textual}{dtwSat} the logistic weight had better results than the -linear for land cover classification. See \insertCite{Maus:2016;textual}{dtwSat} and -\insertCite{Maus:2019;textual}{dtwSat}. -} -\examples{ -log_fun = logisticWeight(alpha=-0.1, beta=100) -log_fun - -} -\references{ -\insertAllCited{} -} -\seealso{ -\code{\link[dtwSat]{twdtwApply}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plot.Rd b/man/plot.Rd deleted file mode 100644 index 9651a23..0000000 --- a/man/plot.Rd +++ /dev/null @@ -1,66 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plot.R -\name{plot} -\alias{plot} -\alias{plot,twdtwAssessment,ANY-method} -\alias{plot-twdtwAssessment} -\alias{plot,twdtwCrossValidation,ANY-method} -\alias{plot-twdtwTimeSeries} -\alias{plot,twdtwTimeSeries,ANY-method} -\alias{plot,twdtwMatches,ANY-method} -\alias{plot-twdtwMatches} -\alias{plot,twdtwRaster,ANY-method} -\alias{plot-twdtwRaster} -\title{Plotting twdtw* objects} -\usage{ -\S4method{plot}{twdtwAssessment,ANY}(x, type = "area", ...) - -\S4method{plot}{twdtwCrossValidation,ANY}(x, type = "crossvalidation", ...) - -\S4method{plot}{twdtwTimeSeries,ANY}(x, type = "timeseries", ...) - -\S4method{plot}{twdtwMatches,ANY}(x, type = "alignments", ...) - -\S4method{plot}{twdtwRaster,ANY}(x, type = "maps", ...) -} -\arguments{ -\item{x}{An object of class twdtw*.} - -\item{type}{A character for the plot type: ''paths'', ''matches'', -''alignments'', ''classification'', ''cost'', ''patterns'', ''timeseries'', -''maps'', ''area'', ''changes'', and ''distance''.} - -\item{...}{additional arguments to pass to plotting functions. -\code{\link[dtwSat]{plotPaths}}, -\code{\link[dtwSat]{plotCostMatrix}}, -\code{\link[dtwSat]{plotAlignments}}, -\code{\link[dtwSat]{plotMatches}}, -\code{\link[dtwSat]{plotClassification}}, -\code{\link[dtwSat]{plotPatterns}}, -\code{\link[dtwSat]{plotTimeSeries}}, -\code{\link[dtwSat]{plotMaps}}, -\code{\link[dtwSat]{plotArea}}, or -\code{\link[dtwSat]{plotChanges}}.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Methods for plotting objects of class twdtw*. -} -\details{ -\describe{ - \item{Plot types}{: - \cr\code{paths}: Method for plotting the minimum paths in the cost matrix of TWDTW. - \cr\code{matches}: Method for plotting the matching points from TWDTW analysis. - \cr\code{alignments}: Method for plotting the alignments and respective TWDTW dissimilarity measures. - \cr\code{classification}: Method for plotting the classification of each subinterval of the time series based on TWDTW analysis. - \cr\code{cost}: Method for plotting the internal matrices used during the TWDTW computation. - \cr\code{patterns}: Method for plotting the temporal patterns. - \cr\code{timeseries}: Method for plotting the temporal patterns. - } -} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotAccuracy.Rd b/man/plotAccuracy.Rd deleted file mode 100644 index d0a1570..0000000 --- a/man/plotAccuracy.Rd +++ /dev/null @@ -1,65 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotAccuracy.R -\name{plotAccuracy} -\alias{plotAccuracy} -\title{Plotting accuracy assessment} -\usage{ -plotAccuracy( - x, - perc = TRUE, - conf.int = 0.95, - time.labels = NULL, - category.name = NULL, - category.type = NULL -) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwAssessment}} or -\code{\link[dtwSat]{twdtwCrossValidation}}.} - -\item{perc}{if TRUE shows the results in percent of area. Otherwise shows the -area in the map units or km2 for no project raster. Default is TRUE.} - -\item{conf.int}{confidence level (0-1) for interval estimation of the population mean. -For details see \code{\link[Hmisc]{smean.cl.normal}}. Used if \code{x} is -\code{\link[dtwSat]{twdtwCrossValidation}}.} - -\item{time.labels}{a character or numeric for the time periods or NULL to -aggregate all classified periods in the same plot. Default is NULL. Used -if \code{x} is \code{\link[dtwSat]{twdtwAssessment}}.} - -\item{category.name}{a character vector defining the class names. If NULL -the class names in the object \code{x} are used. Default is NULL.} - -\item{category.type}{a character defining the categories type "numeric" -or "letter", if NULL the class names are used. Default is NULL.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting accuracy assessment results. -} -\examples{ -\dontrun{ - -# See ?twdtwAssess and ?twdtwCrosValidate - -plotAccuracy(x) - -plotAccuracy(x, category.type="letter") - -} - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwAssessment}} and \code{\link[dtwSat]{twdtwAssess}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotAdjustedArea.Rd b/man/plotAdjustedArea.Rd deleted file mode 100644 index 5b3f680..0000000 --- a/man/plotAdjustedArea.Rd +++ /dev/null @@ -1,60 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotAdjustedArea.R -\name{plotAdjustedArea} -\alias{plotAdjustedArea} -\title{Plotting area and uncertainty} -\usage{ -plotAdjustedArea( - x, - perc = TRUE, - time.labels = NULL, - category.name = NULL, - category.type = NULL -) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwAssessment}} or -\code{\link[dtwSat]{twdtwCrossValidation}}.} - -\item{perc}{if TRUE shows the results in percent of area. Otherwise shows the -area in the map units or km2 for no project raster. Default is TRUE.} - -\item{time.labels}{a character or numeric for the time periods or NULL to -aggregate all classified periods in the same plot. Default is NULL. Used -if \code{x} is \code{\link[dtwSat]{twdtwAssessment}}.} - -\item{category.name}{a character vector defining the class names. If NULL -the class names in the object \code{x} are used. Default is NULL.} - -\item{category.type}{a character defining the categories type "numeric" -or "letter", if NULL the class names are used. Default is NULL.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting area and uncertainty. -} -\examples{ -\dontrun{ - -# See ?twdtwAssess - -plotAdjustedArea(twdtw_assess) - -plotAdjustedArea(twdtw_assess, category.type="letter") - -} - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwAssessment}} and \code{\link[dtwSat]{twdtwAssess}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotAlignments.Rd b/man/plotAlignments.Rd deleted file mode 100644 index d050cdb..0000000 --- a/man/plotAlignments.Rd +++ /dev/null @@ -1,63 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotAlignments.R -\name{plotAlignments} -\alias{plotAlignments} -\title{Plotting alignments} -\usage{ -plotAlignments( - x, - timeseries.labels = NULL, - patterns.labels = NULL, - attr = 1, - threshold = Inf -) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwMatches}}.} - -\item{timeseries.labels}{the label or index of the time series. -Default is 1.} - -\item{patterns.labels}{a vector with labels of the patterns. If not -declared the function will plot the alignments for all patterns in \code{x}.} - -\item{attr}{An \link[base]{integer} or \link[base]{character} vector -indicating the attribute for plotting. Default is 1.} - -\item{threshold}{A number. The TWDTW dissimilarity threshold, \emph{i.e.} the -maximum TWDTW cost for consideration. Default is \code{Inf}.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting the alignments and TWDTW -dissimilarity measures. -} -\examples{ -log_fun = logisticWeight(-0.1, 100) -ts = twdtwTimeSeries(MOD13Q1.ts.list) -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) - -plotAlignments(mat1) - -plotAlignments(mat1, attr=c("evi","ndvi")) - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwMatches-class}}, -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{plotPaths}}, -\code{\link[dtwSat]{plotCostMatrix}}, -\code{\link[dtwSat]{plotMatches}}, and -\code{\link[dtwSat]{plotClassification}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotArea.Rd b/man/plotArea.Rd deleted file mode 100644 index 3becab5..0000000 --- a/man/plotArea.Rd +++ /dev/null @@ -1,106 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotArea.R -\name{plotArea} -\alias{plotArea} -\title{Plotting accumulated area} -\usage{ -plotArea( - x, - time.levels = NULL, - time.labels = NULL, - class.levels = NULL, - class.labels = NULL, - class.colors = NULL, - perc = TRUE -) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwRaster}}.} - -\item{time.levels}{A \link[base]{character} or \link[base]{numeric} -vector with the layers to plot. For plot type ''change'' the minimum length -is two.} - -\item{time.labels}{A \link[base]{character} or \link[base]{numeric} -vector with the labels of the layers. It must have the same -length as time.levels. Default is NULL.} - -\item{class.levels}{A \link[base]{character} or \link[base]{numeric} -vector with the levels of the raster values. Default is NULL.} - -\item{class.labels}{A \link[base]{character} or \link[base]{numeric} -vector with the labels of the raster values. It must have the same -length as class.levels. Default is NULL.} - -\item{class.colors}{a set of aesthetic values. It must have the same -length as class.levels. Default is NULL. See -\link[ggplot2]{scale_fill_manual} for details.} - -\item{perc}{if TRUE shows the results in percent of area. Otherwise shows the -area in the map units or km2 for no project raster. Default is TRUE.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting time series of accumulated area. -} -\examples{ -\dontrun{ - -# Create raster time series -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) - -# Read field samples -field_samples = read.csv(system.file("lucc_MT/data/samples.csv", package="dtwSat")) -proj_str = scan(system.file("lucc_MT/data/samples_projection", - package="dtwSat"), what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -library(caret) -set.seed(1) -I = unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples = field_samples[I,] -validation_samples = field_samples[-I,] - -# Create temporal patterns -training_ts = getTimeSeries(rts, y = training_samples, proj4string = proj_str) -temporal_patterns = createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Run TWDTW analysis for raster time series -log_fun = weight.fun=logisticWeight(-0.1,50) -r_twdtw = twdtwApply(x=rts, y=temporal_patterns, weight.fun=log_fun, format="GTiff", - overwrite=TRUE) - -# Classify raster based on the TWDTW analysis -r_lucc = twdtwClassify(r_twdtw, format="GTiff", overwrite=TRUE) - -plotArea(r_lucc) - -plotArea(r_lucc, perc=FALSE) - -} -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwRaster-class}}, -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{plotMaps}}, -\code{\link[dtwSat]{plotChanges}}, and -\code{\link[dtwSat]{plotDistance}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotChanges.Rd b/man/plotChanges.Rd deleted file mode 100644 index 898d2ea..0000000 --- a/man/plotChanges.Rd +++ /dev/null @@ -1,85 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotChanges.R -\name{plotChanges} -\alias{plotChanges} -\title{Plotting changes} -\usage{ -plotChanges( - x, - time.levels = NULL, - time.labels = NULL, - class.levels = NULL, - class.labels = NULL, - class.colors = NULL -) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwRaster}}.} - -\item{time.levels}{A \link[base]{character} or \link[base]{numeric} -vector with the layers to plot. For plot type ''change'' the minimum length -is two.} - -\item{time.labels}{A \link[base]{character} or \link[base]{numeric} -vector with the labels of the layers. It must have the same -length as time.levels. Default is NULL.} - -\item{class.levels}{A \link[base]{character} or \link[base]{numeric} -vector with the levels of the raster values. Default is NULL.} - -\item{class.labels}{A \link[base]{character} or \link[base]{numeric} -vector with the labels of the raster values. It must have the same -length as class.levels. Default is NULL.} - -\item{class.colors}{A set of aesthetic values. It must have the same -length as class.levels. Default is NULL. See -\link[ggplot2]{scale_fill_manual} for details.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting changes over time. -} -\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") - -r_lucc = twdtwClassify(r_twdtw, format="GTiff", overwrite=TRUE) - -plotChanges(r_lucc) - -} -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwRaster-class}}, -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{plotArea}}, -\code{\link[dtwSat]{plotMaps}}, and -\code{\link[dtwSat]{plotDistance}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotClassification.Rd b/man/plotClassification.Rd deleted file mode 100644 index eee6911..0000000 --- a/man/plotClassification.Rd +++ /dev/null @@ -1,68 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotClassification.R -\name{plotClassification} -\alias{plotClassification} -\title{Plotting subintervals classification} -\usage{ -plotClassification( - x, - timeseries.labels = NULL, - patterns.labels = NULL, - attr, - ... -) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwMatches}}.} - -\item{timeseries.labels}{The label or index of the time series. -Default is 1.} - -\item{patterns.labels}{A vector with labels of the patterns. If not -declared the function will plot one alignment for each pattern.} - -\item{attr}{An \link[base]{integer} vector or \link[base]{character} vector -indicating the attribute for plotting. If not declared the function will plot -all attributes.} - -\item{...}{Additional arguments passed to \code{\link[dtwSat]{twdtwClassify}}.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting the classification of each -subinterval of the time series based on TWDTW analysis. -} -\examples{ -log_fun = logisticWeight(-0.1, 100) -ts = twdtwTimeSeries(MOD13Q1.ts.list) -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) - -# Classify interval -from = as.Date("2007-09-01") -to = as.Date("2013-09-01") -by = "6 month" -gp = plotClassification(x=mat1, from=from, to=to, by=by, overlap=.5) -gp - - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwMatches-class}}, -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{twdtwClassify}}, -\code{\link[dtwSat]{plotAlignments}}, -\code{\link[dtwSat]{plotPaths}}, -\code{\link[dtwSat]{plotMatches}}, and -\code{\link[dtwSat]{plotCostMatrix}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotCostMatrix.Rd b/man/plotCostMatrix.Rd deleted file mode 100644 index b9e5fd0..0000000 --- a/man/plotCostMatrix.Rd +++ /dev/null @@ -1,62 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotCostMatrix.R -\name{plotCostMatrix} -\alias{plotCostMatrix} -\title{Plotting paths} -\usage{ -plotCostMatrix( - x, - timeseries.labels = NULL, - patterns.labels = NULL, - matrix.name = "costMatrix" -) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwMatches}}.} - -\item{timeseries.labels}{The label or index of the time series. -Default is 1.} - -\item{patterns.labels}{A vector with labels of the patterns. If not -declared the function will plot one alignment for each pattern.} - -\item{matrix.name}{A character. The name of the matrix to plot, -"costMatrix" for accumulated cost, "localMatrix" for local cost, -or "timeWeight" for time-weight. Default is "costMatrix".} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting low cost paths in the TWDTW -cost matrix. -} -\examples{ -log_fun = logisticWeight(-0.1, 100) -ts = twdtwTimeSeries(MOD13Q1.ts.list) -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) - -plotCostMatrix(mat1, matrix.name="costMatrix") - -plotCostMatrix(mat1, matrix.name="localMatrix") - -plotCostMatrix(mat1, matrix.name="timeWeight") - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwMatches-class}}, -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{plotAlignments}}, -\code{\link[dtwSat]{plotPaths}}, -\code{\link[dtwSat]{plotMatches}}, and -\code{\link[dtwSat]{plotClassification}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotDistance.Rd b/man/plotDistance.Rd deleted file mode 100644 index 2beaf9d..0000000 --- a/man/plotDistance.Rd +++ /dev/null @@ -1,68 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotDistance.R -\name{plotDistance} -\alias{plotDistance} -\title{Plotting distance maps} -\usage{ -plotDistance(x, time.levels = 1, time.labels = 1, layers = NULL) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwRaster}}.} - -\item{time.levels}{A \link[base]{character} or \link[base]{numeric} -vector with the layers to plot. For plot type ''change'' the minimum length -is two.} - -\item{time.labels}{A \link[base]{character} or \link[base]{numeric} -vector with the labels of the layers. It must have the same -length as time.levels. Default is NULL.} - -\item{layers}{A \link[base]{character} or \link[base]{numeric} -vector with the layers/bands of the raster time series.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting TWDTW distance maps. -} -\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", mc.cores=3) - -plotDistance(r_twdtw) - -} -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwRaster-class}}, -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{plotArea}}, -\code{\link[dtwSat]{plotChanges}}, and -\code{\link[dtwSat]{plotDistance}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotMapSamples.Rd b/man/plotMapSamples.Rd deleted file mode 100644 index 2e57872..0000000 --- a/man/plotMapSamples.Rd +++ /dev/null @@ -1,120 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotMapSamples.R -\name{plotMapSamples} -\alias{plotMapSamples} -\title{Plotting maps} -\usage{ -plotMapSamples(x, samples = "all", ...) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwAssessment}}.} - -\item{samples}{A character defining the samples to plot -"correct", "incorrect", "all". Default is "all".} - -\item{...}{Other arguments to pass to \code{\link[dtwSat]{twdtwRaster}}} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting maps and samples. -} -\examples{ -\dontrun{ - -# Example of TWDTW analysis using raster files -library(dtwSat) -library(caret) - -# Load raster data -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") - -# Create raster time series -rts <- twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) - -# Load field samples and projection -field_samples <- - read.csv(system.file("lucc_MT/data/samples.csv", package = "dtwSat")) -proj_str <- - scan(system.file("lucc_MT/data/samples_projection", package = "dtwSat"), - what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -set.seed(1) -I <- unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples <- field_samples[I, ] -validation_samples <- field_samples[-I, ] - -# Get time series form raster -training_ts <- getTimeSeries(rts, y = training_samples, proj4string = proj_str) -validation_ts <- getTimeSeries(rts, y = validation_samples, proj4string = proj_str) - -# Create temporal patterns -temporal_patterns <- createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Set TWDTW weight function -log_fun <- logisticWeight(-0.1, 50) - -# Run TWDTW analysis -system.time( - r_twdtw <- - twdtwApply(x = rts, y = temporal_patterns, weight.fun = log_fun, progress = 'text') -) - -# Plot TWDTW distances for the first year -plot(r_twdtw, type = "distance", time.levels = 1) - -# Classify raster based on the TWDTW analysis -r_lucc <- twdtwClassify(r_twdtw, progress = 'text') - -# Plot TWDTW classification results -plot(r_lucc, type = "map") - -# Assess classification -twdtw_assess <- - twdtwAssess(object = r_lucc, y = validation_samples, - proj4string = proj_str, conf.int = .95) - -# Plot map accuracy -plot(twdtw_assess, type = "accuracy") - -# Plot area uncertainty -plot(twdtw_assess, type = "area") - -# Plot misclassified samples -plot(twdtw_assess, type = "map", samples = "incorrect") - -# Get latex table with error matrix -twdtwXtable(twdtw_assess, table.type = "matrix") - -# Get latex table with error accuracy -twdtwXtable(twdtw_assess, table.type = "accuracy") - -# Get latex table with area uncertainty -twdtwXtable(twdtw_assess, table.type = "area") - -} - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwAssessment}}, -\code{\link[dtwSat]{plotAccuracy}}, and -\code{\link[dtwSat]{plotAdjustedArea}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotMaps.Rd b/man/plotMaps.Rd deleted file mode 100644 index b366474..0000000 --- a/man/plotMaps.Rd +++ /dev/null @@ -1,85 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotMaps.R -\name{plotMaps} -\alias{plotMaps} -\title{Plotting maps} -\usage{ -plotMaps( - x, - time.levels = NULL, - time.labels = NULL, - class.levels = NULL, - class.labels = NULL, - class.colors = NULL -) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwRaster}}.} - -\item{time.levels}{A \link[base]{character} or \link[base]{numeric} -vector with the layers to plot. For plot type ''change'' the minimum length -is two.} - -\item{time.labels}{A \link[base]{character} or \link[base]{numeric} -vector with the labels of the layers. It must have the same -length as time.levels. Default is NULL.} - -\item{class.levels}{A \link[base]{character} or \link[base]{numeric} -vector with the levels of the raster values. Default is NULL.} - -\item{class.labels}{A \link[base]{character} or \link[base]{numeric} -vector with the labels of the raster values. It must have the same -length as class.levels. Default is NULL.} - -\item{class.colors}{A set of aesthetic values. It must have the same -length as class.levels. Default is NULL. See -\link[ggplot2]{scale_fill_manual} for details.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting time series of maps. -} -\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", mc.cores=3) - -r_lucc = twdtwClassify(r_twdtw, format="GTiff", overwrite=TRUE) - -plotMaps(r_lucc) - -} -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwRaster-class}}, -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{plotArea}}, -\code{\link[dtwSat]{plotChanges}}, and -\code{\link[dtwSat]{plotDistance}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotMatches.Rd b/man/plotMatches.Rd deleted file mode 100644 index 9098386..0000000 --- a/man/plotMatches.Rd +++ /dev/null @@ -1,76 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotMatches.R -\docType{methods} -\name{plotMatches} -\alias{plotMatches} -\title{Plotting matching points} -\usage{ -plotMatches( - x, - timeseries.labels = 1, - patterns.labels = NULL, - k = 1, - attr = 1, - shift = 0.5, - show.dist = FALSE -) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwMatches}}.} - -\item{timeseries.labels}{The label or index of the time series. -Default is 1.} - -\item{patterns.labels}{A vector with labels of the patterns. If not -declared the function will plot one alignment for each pattern.} - -\item{k}{A positive integer. The index of the last alignment to include in -the plot. If not declared the function will plot the best match for -each pattern.} - -\item{attr}{An \link[base]{integer} or \link[base]{character} vector -indicating the attribute for plotting. Default is 1.} - -\item{shift}{A number that shifts the pattern position in the \code{x} -direction. Default is 0.5.} - -\item{show.dist}{Show the distance for each alignment. Default is FALSE.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting the matching points from -TWDTW analysis. -} -\examples{ -log_fun = logisticWeight(-0.1, 100) -ts = twdtwTimeSeries(MOD13Q1.ts.list) -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) - -plotMatches(mat1) - -plotMatches(mat1, patterns.labels="Soybean", k=4) - -plotMatches(mat1, patterns.labels=c("Soybean","Maize"), k=4) - -plotMatches(mat1, patterns.labels=c("Soybean","Cotton"), k=c(3,1)) - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwMatches-class}}, -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{plotPaths}}, -\code{\link[dtwSat]{plotCostMatrix}}, -\code{\link[dtwSat]{plotAlignments}}, and -\code{\link[dtwSat]{plotClassification}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotPaths.Rd b/man/plotPaths.Rd deleted file mode 100644 index d08260e..0000000 --- a/man/plotPaths.Rd +++ /dev/null @@ -1,56 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotPaths.R -\name{plotPaths} -\alias{plotPaths} -\title{Plotting paths} -\usage{ -plotPaths(x, timeseries.labels = NULL, patterns.labels = NULL, k = NULL) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwMatches}}.} - -\item{timeseries.labels}{The label or index of the time series. -Default is 1.} - -\item{patterns.labels}{A vector with labels of the patterns. If not -declared the function will plot one alignment for each pattern.} - -\item{k}{A positive integer. The index of the last alignment to include in -the plot. If not declared the function will plot all low cost paths.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting low cost paths in the TWDTW -cost matrix. -} -\examples{ -log_fun = logisticWeight(-0.1, 100) -ts = twdtwTimeSeries(MOD13Q1.ts.list) -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) - -plotPaths(mat1) - -plotPaths(mat1, patterns.labels="Soybean", k=1:2) - -plotPaths(mat1, patterns.labels=c("Maize","Cotton"), k=2) - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwMatches-class}}, -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{plotAlignments}}, -\code{\link[dtwSat]{plotCostMatrix}}, -\code{\link[dtwSat]{plotMatches}}, and -\code{\link[dtwSat]{plotClassification}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotTimeSeries.Rd b/man/plotTimeSeries.Rd deleted file mode 100644 index 8233ef1..0000000 --- a/man/plotTimeSeries.Rd +++ /dev/null @@ -1,43 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotTimeSeries.R -\name{plotTimeSeries} -\alias{plotTimeSeries} -\title{Plotting time series} -\usage{ -plotTimeSeries(x, labels = NULL, attr) -} -\arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwTimeSeries}}, -\code{\link[zoo]{zoo}}, or list of class \code{\link[zoo]{zoo}}.} - -\item{labels}{A vector with labels of the time series. If missing, all -elements in the list will be plotted (up to a maximum of 16).} - -\item{attr}{An \link[base]{integer} vector or \link[base]{character} vector -indicating the attribute for plotting. If not declared the function will plot -all attributes.} -} -\value{ -A \link[ggplot2]{ggplot} object. -} -\description{ -Method for plotting the temporal patterns. -} -\examples{ -ts = twdtwTimeSeries(MOD13Q1.ts.list) -plotTimeSeries(ts) -plotTimeSeries(ts, attr="evi") - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwTimeSeries-class}} and -\code{\link[dtwSat]{plotPatterns}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/plotPatterns.Rd b/man/plot_patterns.Rd similarity index 68% rename from man/plotPatterns.Rd rename to man/plot_patterns.Rd index 44e91f7..cf7e32b 100644 --- a/man/plotPatterns.Rd +++ b/man/plot_patterns.Rd @@ -1,23 +1,23 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/plotPatterns.R -\name{plotPatterns} -\alias{plotPatterns} +% Please edit documentation in R/plot_patterns.R +\name{plot_patterns} +\alias{plot_patterns} \title{Plotting temporal patterns} \usage{ -plotPatterns(x, labels = NULL, attr, year = 2005) +plot_patterns(x, labels = NULL, attr, year = 2005) } \arguments{ -\item{x}{An object of class \code{\link[dtwSat]{twdtwTimeSeries}}, +\item{x}{An object of class \code{\link[dtwSat]{twdtwTimeSeries}}, \code{\link[zoo]{zoo}}, or list of \code{\link[zoo]{zoo}}.} -\item{labels}{A vector with labels of the time series. If not declared +\item{labels}{A vector with labels of the time series. If not declared the function will plot all time series.} -\item{attr}{An \link[base]{integer} vector or \link[base]{character} vector -indicating the attribute for plotting. If not declared the function will plot +\item{attr}{An \link[base]{integer} vector or \link[base]{character} vector +indicating the attribute for plotting. If not declared the function will plot all attributes.} -\item{year}{An integer. The base year to shift the dates of the time series to. +\item{year}{An integer. The base year to shift the dates of the time series to. If NULL then the time series is not shifted. Default is 2005.} } \value{ @@ -25,20 +25,14 @@ A \link[ggplot2]{ggplot} object. } \description{ Method for plotting the temporal patterns. -} -\examples{ -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -plotPatterns(patt) -plotPatterns(patt, attr="evi") - } \references{ \insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} + +\insertRef{Maus:2016}{dtwSat} } \seealso{ -\code{\link[dtwSat]{twdtwTimeSeries-class}} and +\code{\link[dtwSat]{twdtwTimeSeries-class}} and \code{\link[dtwSat]{plotTimeSeries}} } \author{ diff --git a/man/reexports.Rd b/man/reexports.Rd deleted file mode 100644 index 82e3410..0000000 --- a/man/reexports.Rd +++ /dev/null @@ -1,19 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/zzz.R -\docType{import} -\name{reexports} -\alias{reexports} -\alias{symmetric1} -\alias{symmetric2} -\alias{asymmetric} -\alias{rabinerJuangStepPattern} -\title{Objects exported from other packages} -\keyword{internal} -\description{ -These objects are imported from other packages. Follow the links -below to see their documentation. - -\describe{ - \item{dtw}{\code{\link[dtw:stepPattern]{asymmetric}}, \code{\link[dtw:stepPattern]{rabinerJuangStepPattern}}, \code{\link[dtw:stepPattern]{symmetric1}}, \code{\link[dtw:stepPattern]{symmetric2}}} -}} - diff --git a/man/resampleTimeSeries.Rd b/man/resampleTimeSeries.Rd deleted file mode 100644 index c2b008f..0000000 --- a/man/resampleTimeSeries.Rd +++ /dev/null @@ -1,40 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/resampleTimeSeries.R -\name{resampleTimeSeries} -\alias{resampleTimeSeries} -\alias{resampleTimeSeries,twdtwTimeSeries-method} -\alias{resampleTimeSeries-twdtwMatches} -\title{Resample time series} -\usage{ -resampleTimeSeries(object, length = NULL) - -\S4method{resampleTimeSeries}{twdtwTimeSeries}(object, length = NULL) -} -\arguments{ -\item{object}{an object of class twdtwTimeSeries.} - -\item{length}{An integer. The number of samples to resample the time series to. -If not declared the length is set to the length of the longest time series.} -} -\value{ -An object of class \code{\link[dtwSat]{twdtwTimeSeries}} whose -time series have the same number of samples (points). -} -\description{ -Resample time series in the object to have the same length. -} -\examples{ -# Resampling time series from objects of class twdtwTimeSeries -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -npatt = resampleTimeSeries(patt, length=46) -nrow(patt) -nrow(npatt) - -} -\seealso{ -\code{\link[dtwSat]{twdtwTimeSeries-class}}, and -\code{\link[dtwSat]{twdtwApply}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/shiftDates.Rd b/man/shiftDates.Rd deleted file mode 100644 index 0ff01d8..0000000 --- a/man/shiftDates.Rd +++ /dev/null @@ -1,55 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/miscellaneous.R -\name{shiftDates} -\alias{shiftDates} -\alias{shiftDates,twdtwTimeSeries-method} -\alias{shiftDates-twdtwTimeSeries} -\alias{shiftDates,list-method} -\alias{shiftDates-list} -\alias{shiftDates,zoo-method} -\alias{shiftDates-zoo} -\title{Shift dates} -\usage{ -shiftDates(object, year = NULL) - -\S4method{shiftDates}{twdtwTimeSeries}(object, year = NULL) - -\S4method{shiftDates}{list}(object, year = NULL) - -\S4method{shiftDates}{zoo}(object, year = NULL) -} -\arguments{ -\item{object}{\code{\link[dtwSat]{twdtwTimeSeries}} objects, -\code{\link[zoo]{zoo}} objects or a list of \code{\link[zoo]{zoo}} objects.} - -\item{year}{the base year to shift the time series to.} -} -\value{ -An object of the same class as the input \code{object}. -} -\description{ -This function shifts the dates of the time series to a -given base year. -} -\examples{ -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -npatt = shiftDates(patt, year=2005) -index(patt) -index(npatt) - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} - -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwTimeSeries-class}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/shift_dates.Rd b/man/shift_dates.Rd new file mode 100644 index 0000000..6ed829b --- /dev/null +++ b/man/shift_dates.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/miscellaneous.R +\name{shift_dates} +\alias{shift_dates} +\title{Shift dates} +\usage{ +shift_dates(x, year) +} +\arguments{ +\item{year}{the base year to shift the time series to.} + +\item{object}{\code{\link[dtwSat]{twdtwTimeSeries}} objects, +\code{\link[zoo]{zoo}} objects or a list of \code{\link[zoo]{zoo}} objects.} +} +\value{ +An object of the same class as the input \code{object}. +} +\description{ +This function shifts the dates of the time series to a +given base year. +} +\references{ +\insertRef{Maus:2019}{dtwSat} + +\insertRef{Maus:2016}{dtwSat} +} +\author{ +Victor Maus, \email{vwmaus1@gmail.com} +} diff --git a/man/subset.Rd b/man/subset.Rd deleted file mode 100644 index ef0fb5d..0000000 --- a/man/subset.Rd +++ /dev/null @@ -1,87 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/subset.R -\name{subset} -\alias{subset} -\alias{subset,twdtwTimeSeries-method} -\alias{subset-twdtwTimeSeries} -\alias{subset,twdtwMatches-method} -\alias{subset-twdtwMatches} -\alias{subset,twdtwRaster-method} -\alias{subset-twdtwRaster} -\title{Subset time series} -\usage{ -\S4method{subset}{twdtwTimeSeries}(x, labels = NULL) - -\S4method{subset}{twdtwMatches}(x, timeseries.labels = NULL, patterns.labels = NULL, k = NULL) - -\S4method{subset}{twdtwRaster}(x, e = NULL, layers = NULL) -} -\arguments{ -\item{x}{An objects of class twdtw*.} - -\item{labels}{A character vector with time series labels.} - -\item{timeseries.labels}{a vector with labels of the time series.} - -\item{patterns.labels}{a vector with labels of the patterns.} - -\item{k}{A positive integer. The index of the last alignment to include in -the subset.} - -\item{e}{An extent object, or any object from which an Extent object can -be extracted. See \link[raster]{crop} for details.} - -\item{layers}{A vector with the names of the \code{twdtwRaster} object to include in -the subset.} -} -\value{ -An object of class twdtw*. -} -\description{ -Get subsets from objects of class twdtw*. -} -\examples{ -# Getting time series from objects of class twdtwTimeSeries -ts = twdtwTimeSeries(MOD13Q1.ts.list) -ts = subset(ts, 2) -ts -# Getting time series from objects of class twdtwTimeSeries -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -mat = twdtwApply(x=ts, y=patt, weight.fun=logisticWeight(-0.1,100), - keep=TRUE, legacy=TRUE) -mat = subset(mat, k=4) - -## This example creates a twdtwRaster object and extracts time series from it. - -# Creating objects of class twdtwRaster with evi and ndvi time series -evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) -ndvi = brick(system.file("lucc_MT/data/ndvi.tif", package="dtwSat")) -timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") -rts = twdtwRaster(evi, ndvi, timeline=timeline) - -rts_evi = subset(rts, layers="evi") - -field_samples = read.csv(system.file("lucc_MT/data/samples.csv", package="dtwSat")) -prj_string = scan(system.file("lucc_MT/data/samples_projection", package="dtwSat"), - what = "character") - -# Extract time series -ts_evi = getTimeSeries(rts_evi, y = field_samples, proj4string = prj_string) - -# Subset all labels = "Forest" -ts_forest = subset(ts_evi, labels="Forest") - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwRaster-class}}, -\code{\link[dtwSat]{twdtwTimeSeries-class}}, and -\code{\link[dtwSat]{twdtwMatches-class}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwApply.Rd b/man/twdtwApply.Rd deleted file mode 100644 index 9b885a9..0000000 --- a/man/twdtwApply.Rd +++ /dev/null @@ -1,272 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/twdtwApply.R -\name{twdtwApply} -\alias{twdtwApply} -\alias{twdtwApply,twdtwTimeSeries-method} -\alias{twdtwApply-twdtwTimeSeries} -\alias{twdtwApply,twdtwRaster-method} -\alias{twdtwApply-twdtwRaster} -\title{Apply TWDTW analysis} -\usage{ -twdtwApply( - x, - y, - resample = TRUE, - length = NULL, - weight.fun = function(phi, psi) phi, - dist.method = "Euclidean", - step.matrix = symmetric1, - n = NULL, - span = NULL, - min.length = 0, - ... -) - -\S4method{twdtwApply}{twdtwTimeSeries}( - x, - y, - resample, - length, - weight.fun, - dist.method, - step.matrix, - n, - span, - min.length, - legacy = FALSE, - keep = FALSE, - ... -) - -\S4method{twdtwApply}{twdtwRaster}( - x, - y, - resample, - length, - weight.fun, - dist.method, - step.matrix, - n, - span, - min.length, - breaks = NULL, - from = NULL, - to = NULL, - by = NULL, - overlap = 0.5, - filepath = "", - fill = NULL, - legacy = FALSE, - progress = "text", - minrows = 1, - alpha = -0.1, - beta = 50, - ... -) -} -\arguments{ -\item{x}{An object of class twdtw*. This is the target time series. -Usually, it is a set of unclassified time series.} - -\item{y}{An object of class \link[dtwSat]{twdtwTimeSeries}. -The temporal patterns.} - -\item{resample}{Resample the patterns to have the same length. Default is TRUE. -See \link[dtwSat]{resampleTimeSeries} for details.} - -\item{length}{An integer. Length of patterns used with \code{patterns.length}. -If not declared the length of the output patterns will be the length of -the longest pattern.} - -\item{weight.fun}{A function. Any function that receives two matrices and -performs a computation on them, returning a single matrix with the same -dimensions. The first matrix is the DTW local cost matrix and the -second a matrix of the time differences in days. The function should return a -matrix of DTW local cost weighted by the time differences. If not declared -the time-weight is zero. In this case the function runs the standard version -of the dynamic time warping. See details.} - -\item{dist.method}{A character. Method to derive the local cost matrix. -Default is ''Euclidean'' see \code{\link[proxy]{dist}} in package -\pkg{proxy}.} - -\item{step.matrix}{See \code{\link[dtw]{stepPattern}} in package \pkg{dtw} -\insertCite{Giorgino:2009}{dtwSat}.} - -\item{n}{An integer. The maximun number of matches to perform. -NULL will return all matches.} - -\item{span}{A number. Span between two matches, \emph{i.e.} the minimum -interval between two matches; for details see \insertCite{Muller:2007}{dtwSat}. -If not declared it removes all overlapping matches of the same pattern. To include -overlapping matches of the same pattern use \code{span=0}.} - -\item{min.length}{A number between 0 an 1. This argument removes overfittings. -Minimum length after warping. Percentage of the original pattern length. Default is 0.5, -meaning that the matching cannot be shorter than half of the pattern length.} - -\item{...}{Arguments to pass to \code{\link[raster]{writeRaster}} and -\code{\link[raster]{pbCreate}}} - -\item{legacy}{logical. If FALSE, runs a faster new TWDTW implementation. Default FLASE} - -\item{keep}{Preserves the cost matrix, inputs, and other internal structures. -Default is FALSE. For plot methods use \code{keep=TRUE}.} - -\item{breaks}{A vector of class \code{\link[base]{Dates}}. This replaces the arguments \code{from}, -\code{to}, and \code{by}.} - -\item{from}{A character or \code{\link[base]{Dates}} object in the format "yyyy-mm-dd".} - -\item{to}{A \code{\link[base]{character}} or \code{\link[base]{Dates}} object in the format "yyyy-mm-dd".} - -\item{by}{A \code{\link[base]{character}} with the interval size, \emph{e.g.} "6 month".} - -\item{overlap}{A number between 0 and 1. The minimum overlapping -between one match and the interval of classification. Default is 0.5, -\emph{i.e.} an overlap minimum of 50\%.} - -\item{filepath}{A character. The path at which to save the raster with results. If not provided the -function saves in the current work directory.} - -\item{fill}{A character to fill the classification gaps. -For signature \code{twdtwTimeSeries} the default is \code{fill="unclassified"}, -for signature \code{twdtwRaster} the default is \code{fill="unclassified"}.} - -\item{progress}{character. 'text' or 'window'.} - -\item{minrows}{Integer. Minimum number of rows in each block} - -\item{alpha}{Numeric. The steepness of TWDTW logistic weight.} - -\item{beta}{Numeric. The midpoint of TWDTW logistic weight.} -} -\value{ -An object of class twdtw*. -} -\description{ -This function performs a multidimensional Time-Weighted DTW -analysis and retrieves the matches between the temporal patterns and -a set of time series \insertCite{Maus:2019}{dtwSat}. -} -\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 for analyzing time series with phenological cycles -of vegetation that are usually bound to seasons. In previous studies by -\insertCite{Maus:2016}{dtwSat} the logistic weight had better results than the -linear for land cover classification. -See \insertCite{Maus:2016,Maus:2019}{dtwSat} for details about the method. -} -\examples{ -# Applying TWDTW analysis to objects of class twdtwTimeSeries -log_fun = logisticWeight(-0.1, 100) -ts = twdtwTimeSeries(MOD13Q1.ts.list) -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -mat1 = twdtwApply(x=ts, y=patt, weight.fun=log_fun, keep=TRUE, legacy=TRUE) -mat1 - -\dontrun{ -# Parallel processin -require(parallel) -mat_list = mclapply(as.list(ts), mc.cores=2, FUN=twdtwApply, y=patt, weight.fun=log_fun) -mat2 = twdtwMatches(alignments=mat_list) -} -\dontrun{ - -# Example of TWDTW analysis using raster files -library(dtwSat) -library(caret) - -# Load raster data -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") - -# Create raster time series -rts <- twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) - -# Load field samples and projection -field_samples <- - read.csv(system.file("lucc_MT/data/samples.csv", package = "dtwSat")) -proj_str <- - scan(system.file("lucc_MT/data/samples_projection", package = "dtwSat"), - what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -set.seed(1) -I <- unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples <- field_samples[I, ] -validation_samples <- field_samples[-I, ] - -# Get time series form raster -training_ts <- getTimeSeries(rts, y = training_samples, proj4string = proj_str) -validation_ts <- getTimeSeries(rts, y = validation_samples, proj4string = proj_str) - -# Create temporal patterns -temporal_patterns <- createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Set TWDTW weight function -log_fun <- logisticWeight(-0.1, 50) - -# Run TWDTW analysis -system.time( - r_twdtw <- - twdtwApply(x = rts, y = temporal_patterns, weight.fun = log_fun, progress = 'text') -) - -# Plot TWDTW distances for the first year -plot(r_twdtw, type = "distance", time.levels = 1) - -# Classify raster based on the TWDTW analysis -r_lucc <- twdtwClassify(r_twdtw, progress = 'text') - -# Plot TWDTW classification results -plot(r_lucc, type = "map") - -# Assess classification -twdtw_assess <- - twdtwAssess(object = r_lucc, y = validation_samples, - proj4string = proj_str, conf.int = .95) - -# Plot map accuracy -plot(twdtw_assess, type = "accuracy") - -# Plot area uncertainty -plot(twdtw_assess, type = "area") - -# Plot misclassified samples -plot(twdtw_assess, type = "map", samples = "incorrect") - -# Get latex table with error matrix -twdtwXtable(twdtw_assess, table.type = "matrix") - -# Get latex table with error accuracy -twdtwXtable(twdtw_assess, table.type = "accuracy") - -# Get latex table with area uncertainty -twdtwXtable(twdtw_assess, table.type = "area") - -} - -} -\references{ -\insertAllCited{} -} -\seealso{ -\code{\link[dtwSat]{twdtwMatches-class}}, -\code{\link[dtwSat]{twdtwTimeSeries-class}}, -\code{\link[dtwSat]{twdtwRaster-class}}, -\code{\link[dtwSat]{getTimeSeries}}, and -\code{\link[dtwSat]{createPatterns}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwAssess.Rd b/man/twdtwAssess.Rd deleted file mode 100644 index e89ceb6..0000000 --- a/man/twdtwAssess.Rd +++ /dev/null @@ -1,284 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/twdtwAssess.R -\name{twdtwAssess} -\alias{twdtwAssess} -\alias{twdtwAssess,twdtwRaster-method} -\alias{twdtwAssess-twdtwRaster} -\alias{twdtwAssess,data.frame-method} -\alias{twdtwAssess-data.frame} -\alias{twdtwAssess,table-method} -\alias{twdtwAssess-table} -\alias{twdtwAssess,matrix-method} -\alias{twdtwAssess-matrix} -\alias{twdtwAssess,twdtwMatches-method} -\alias{twdtwAssess-twdtwMatches} -\title{Assess TWDTW classification} -\usage{ -\S4method{twdtwAssess}{twdtwRaster}( - object, - y, - labels = NULL, - id.labels = NULL, - proj4string = NULL, - conf.int = 0.95, - rm.nosample = FALSE, - start_date = NULL -) - -\S4method{twdtwAssess}{data.frame}(object, area, conf.int = 0.95, rm.nosample = TRUE) - -\S4method{twdtwAssess}{table}(object, area, conf.int = 0.95, rm.nosample = TRUE) - -\S4method{twdtwAssess}{matrix}(object, area, conf.int = 0.95, rm.nosample = TRUE) - -\S4method{twdtwAssess}{twdtwMatches}(object, area, conf.int = 0.95, rm.nosample = TRUE) -} -\arguments{ -\item{object}{An object of class \code{\link[dtwSat]{twdtwRaster}} resulting from -the classification, i.e. \code{\link[dtwSat]{twdtwClassify}}. -The argument can also receive an error matrix (confusion matrix) using the classes -\code{\link[base]{data.frame}} or \code{\link[base]{table}}. In this case the user -must provide the area for each class to the argument \code{area}.} - -\item{y}{A \code{\link[base]{data.frame}} whose attributes are: longitude, -latitude, the start ''from'' and the end ''to'' of the time interval -for each sample. This can also be a \code{\link[sp]{SpatialPointsDataFrame}} -whose attributes are the start ''from'' and the end ''to'' of the time interval. -If missing ''from'' and/or ''to'', they are set to the time range of the -\code{object}.} - -\item{labels}{Character vector with time series labels. For signature -\code{\link[dtwSat]{twdtwRaster}} this argument can be used to set the -labels for each sample in \code{y}, or it can be combined with \code{id.labels} -to select samples with a specific label.} - -\item{id.labels}{A numeric or character with an column name from \code{y} to -be used as samples labels. Optional.} - -\item{proj4string}{Projection string, see \code{\link[sp]{CRS-class}}. Used -if \code{y} is a \code{\link[base]{data.frame}}.} - -\item{conf.int}{Specifies the confidence level (0-1).} - -\item{rm.nosample}{If sum of columns and sum of rows of the error matrix are zero -then remove class. Default is TRUE.} - -\item{start_date}{A date. Required if there is only one map to be assessed. Usually this is the -first date of the timeline from satellite images.} - -\item{area}{A numeric vector with the area for each class if the argument \code{object} -is an error matrix (confusion matrix). If \code{object} is \code{\link[dtwSat]{twdtwMatches}} -area can be either a vector with the area of each classified object, or a single number -if the objects are single pixels.} -} -\description{ -Performs an accuracy assessment -of the classified maps. The function returns Overall Accuracy, -User's Accuracy, Produce's Accuracy, error matrix (confusion matrix), -and estimated area according to \insertCite{Olofsson:2013,Olofsson:2014;textual}{dtwSat}. -The function returns the metrics for each time interval and a summary considering all -classified intervals. -} -\examples{ -\dontrun{ - -# Example of TWDTW analysis using raster files -library(dtwSat) -library(caret) - -# Load raster data -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") - -# Create raster time series -rts <- twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) - -# Load field samples and projection -field_samples <- - read.csv(system.file("lucc_MT/data/samples.csv", package = "dtwSat")) -proj_str <- - scan(system.file("lucc_MT/data/samples_projection", package = "dtwSat"), - what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -set.seed(1) -I <- unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples <- field_samples[I, ] -validation_samples <- field_samples[-I, ] - -# Get time series form raster -training_ts <- getTimeSeries(rts, y = training_samples, proj4string = proj_str) -validation_ts <- getTimeSeries(rts, y = validation_samples, proj4string = proj_str) - -# Create temporal patterns -temporal_patterns <- createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Set TWDTW weight function -log_fun <- logisticWeight(-0.1, 50) - -# Run TWDTW analysis -system.time( - r_twdtw <- - twdtwApply(x = rts, y = temporal_patterns, weight.fun = log_fun, progress = 'text') -) - -# Plot TWDTW distances for the first year -plot(r_twdtw, type = "distance", time.levels = 1) - -# Classify raster based on the TWDTW analysis -r_lucc <- twdtwClassify(r_twdtw, progress = 'text') - -# Plot TWDTW classification results -plot(r_lucc, type = "map") - -# Assess classification -twdtw_assess <- - twdtwAssess(object = r_lucc, y = validation_samples, - proj4string = proj_str, conf.int = .95) - -# Plot map accuracy -plot(twdtw_assess, type = "accuracy") - -# Plot area uncertainty -plot(twdtw_assess, type = "area") - -# Plot misclassified samples -plot(twdtw_assess, type = "map", samples = "incorrect") - -# Get latex table with error matrix -twdtwXtable(twdtw_assess, table.type = "matrix") - -# Get latex table with error accuracy -twdtwXtable(twdtw_assess, table.type = "accuracy") - -# Get latex table with area uncertainty -twdtwXtable(twdtw_assess, table.type = "area") - -} - - -# Total mapped area by class. Data from [1] -area = c(A = 22353, B = 1122543, C = 610228) - -# Error matrix, columns (Reference) rows (Map) -x = - rbind( - c( 97, 0, 3), - c( 3, 279, 18), - c( 2, 1, 97) - ) - -table_assess = twdtwAssess(x, area, conf.int = .95) - -table_assess - -plot(table_assess, type="area", perc=FALSE) - -plot(table_assess, type="accuracy") - -\dontrun{ - -# Example of TWDTW analysis using raster files -library(dtwSat) -library(caret) - -# Load raster data -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") - -# Create raster time series -rts <- twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) - -# Load field samples and projection -field_samples <- - read.csv(system.file("lucc_MT/data/samples.csv", package = "dtwSat")) -proj_str <- - scan(system.file("lucc_MT/data/samples_projection", package = "dtwSat"), - what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -set.seed(1) -I <- unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples <- field_samples[I, ] -validation_samples <- field_samples[-I, ] - -# Get time series form raster -training_ts <- getTimeSeries(rts, y = training_samples, proj4string = proj_str) -validation_ts <- getTimeSeries(rts, y = validation_samples, proj4string = proj_str) - -# Create temporal patterns -temporal_patterns <- createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Set TWDTW weight function -log_fun <- logisticWeight(-0.1, 50) - -# Run TWDTW analysis -system.time( - r_twdtw <- - twdtwApply(x = rts, y = temporal_patterns, weight.fun = log_fun, progress = 'text') -) - -# Plot TWDTW distances for the first year -plot(r_twdtw, type = "distance", time.levels = 1) - -# Classify raster based on the TWDTW analysis -r_lucc <- twdtwClassify(r_twdtw, progress = 'text') - -# Plot TWDTW classification results -plot(r_lucc, type = "map") - -# Assess classification -twdtw_assess <- - twdtwAssess(object = r_lucc, y = validation_samples, - proj4string = proj_str, conf.int = .95) - -# Plot map accuracy -plot(twdtw_assess, type = "accuracy") - -# Plot area uncertainty -plot(twdtw_assess, type = "area") - -# Plot misclassified samples -plot(twdtw_assess, type = "map", samples = "incorrect") - -# Get latex table with error matrix -twdtwXtable(twdtw_assess, table.type = "matrix") - -# Get latex table with error accuracy -twdtwXtable(twdtw_assess, table.type = "accuracy") - -# Get latex table with area uncertainty -twdtwXtable(twdtw_assess, table.type = "area") - -} - -} -\references{ -\insertAllCited{} - - \insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwClassify}}, -\code{\link[dtwSat]{twdtwAssessment}}, and -\code{\link[dtwSat]{twdtwXtable}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwAssessment-class.Rd b/man/twdtwAssessment-class.Rd deleted file mode 100644 index a79d971..0000000 --- a/man/twdtwAssessment-class.Rd +++ /dev/null @@ -1,48 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/class-twdtwAssessment.R, R/methods.R -\name{twdtwAssessment-class} -\alias{twdtwAssessment-class} -\alias{twdtwAssessment} -\alias{show,twdtwAssessment-method} -\title{class "twdtwAssessment"} -\usage{ -\S4method{show}{twdtwAssessment}(object) -} -\arguments{ -\item{object}{an object of class twdtwAssessment.} -} -\description{ -This class stores the map assessment metrics. -} -\details{ -If the twdtwRaster is unprojected (longitude/latitude) the estimated area is the sum of the approximate -surface area in km2 of each cell (pixel). If the twdtwRaster is projected the estimated area is calculated -using the the pixel resolution in the map unit. -} -\section{Slots }{ - -\describe{ - \item{\code{accuracySummary}:}{Overall Accuracy, User's Accuracy, Producer's Accuracy, - Error Matrix (confusion matrix), and Estimated Area, considering all time periods.} - \item{\code{accuracyByPeriod}:}{Overall Accuracy, User's Accuracy, Producer's Accuracy, - Error Matrix (confusion matrix), and Estimated Area, for each time periods independently - from each other.} - \item{\code{data}:}{A \code{\link[sp]{SpatialPointsDataFrame}} with sample ID, period, - date from, date to, reference labels, predicted labels, and TWDTW distance.} - \item{\code{map}:}{A \code{\link[dtwSat]{twdtwRaster}} with the raster maps.} -} -} - -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwClassify}}, -\code{\link[dtwSat]{twdtwAssess}}, and -\code{\link[dtwSat]{twdtwXtable}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwClassify.Rd b/man/twdtwClassify.Rd deleted file mode 100644 index 3db968a..0000000 --- a/man/twdtwClassify.Rd +++ /dev/null @@ -1,576 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/twdtwClassify.R -\name{twdtwClassify} -\alias{twdtwClassify} -\alias{twdtwClassify,data.frame-method} -\alias{twdtwClassify-data.frame} -\alias{twdtwClassify,list-method} -\alias{twdtwClassify-list} -\alias{twdtwClassify,twdtwTimeSeries-method} -\alias{twdtwClassify-twdtwTimeSeries} -\alias{twdtwClassify,twdtwMatches-method} -\alias{twdtwClassify,twdtwRaster-method} -\alias{twdtwClassify-twdtwRaster} -\title{Classify time series} -\usage{ -twdtwClassify(x, ...) - -\S4method{twdtwClassify}{data.frame}( - x, - y, - step.matrix = symmetric1, - breaks = NULL, - from = NULL, - to = NULL, - by = NULL, - overlap = 0.5, - fill = length(y), - alpha = -0.1, - beta = 50, - time.window = FALSE, - keep = FALSE, - ... -) - -\S4method{twdtwClassify}{list}( - x, - y, - step.matrix = symmetric1, - breaks = NULL, - from = NULL, - to = NULL, - by = NULL, - overlap = 0.5, - fill = length(y), - alpha = -0.1, - beta = 50, - time.window = FALSE, - keep = FALSE, - ... -) - -\S4method{twdtwClassify}{twdtwTimeSeries}( - x, - patterns.labels = NULL, - from = NULL, - to = NULL, - by = NULL, - breaks = NULL, - overlap = 0.5, - thresholds = Inf, - fill = "unclassified", - ... -) - -\S4method{twdtwClassify}{twdtwMatches}( - x, - patterns.labels = NULL, - from = NULL, - to = NULL, - by = NULL, - breaks = NULL, - overlap = 0.5, - thresholds = Inf, - fill = "unclassified" -) - -\S4method{twdtwClassify}{twdtwRaster}( - x, - patterns.labels = NULL, - thresholds = Inf, - fill = 255, - filepath = "", - ... -) -} -\arguments{ -\item{x}{An object of class twdtw*. This is the target time series. -Usually, it is a set of unclassified time series.} - -\item{...}{Arguments to pass to specific methods for each twdtw* class -and other arguments to pass to \code{\link[raster]{writeRaster}} and -\code{\link[raster]{pbCreate}}. If \code{x} of -\code{\link[dtwSat]{twdtwTimeSeries-class}} additional arguments passed to -\code{\link[dtwSat]{twdtwApply}}.} - -\item{y}{a list of data.frame objects similar to \code{x}. -The temporal patterns used to classify the time series in \code{x}.} - -\item{step.matrix}{See \code{\link[dtw]{stepPattern}} in package \pkg{dtw} -\insertCite{Giorgino:2009}{dtwSat}.} - -\item{breaks}{A vector of class \code{\link[base]{Dates}}. This replaces the arguments \code{from}, -\code{to}, and \code{by}.} - -\item{from}{A character or \code{\link[base]{Dates}} object in the format "yyyy-mm-dd".} - -\item{to}{A \code{\link[base]{character}} or \code{\link[base]{Dates}} object in the format "yyyy-mm-dd".} - -\item{by}{A \code{\link[base]{character}} with the interval size, \emph{e.g.} "6 month".} - -\item{overlap}{A number between 0 and 1. The minimum overlapping -between one match and the interval of classification. Default is 0.5, -\emph{i.e.} an overlap minimum of 50\%.} - -\item{fill}{A character to fill the classification gaps. -For signature \code{twdtwTimeSeries} the default is \code{fill="unclassified"}, -for signature \code{twdtwRaster} the default is \code{fill="unclassified"}.} - -\item{alpha}{Numeric. The steepness of TWDTW logistic weight.} - -\item{beta}{Numeric. The midpoint of TWDTW logistic weight.} - -\item{time.window}{logical. TRUE will constrain the TWDTW computation to the -value of the parameter \code{beta} defined in the logistic weight function. -Default is FALSE.} - -\item{keep}{Preserves the cost matrix, inputs, and other internal structures. -Default is FALSE. For plot methods use \code{keep=TRUE}.} - -\item{patterns.labels}{a vector with labels of the patterns.} - -\item{thresholds}{A numeric vector the same length as \code{patterns.labels}. -The TWDTW dissimilarity thresholds, i.e. the maximum TWDTW cost for consideration -in the classification. Default is \code{Inf} for all \code{patterns.labels}.} - -\item{filepath}{A character. The path at which to save the raster with results. -If not provided the function saves in the same directory as the input time series raster.} -} -\value{ -An object of class twdtw*. -} -\description{ -This function classifies the intervals of a time series -based on the TWDTW results. -} -\examples{ -\dontrun{ - -# Example of TWDTW analysis using raster files -library(dtwSat) -library(caret) - -# Load raster data -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") - -# Create raster time series -rts <- twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) - -# Load field samples and projection -field_samples <- - read.csv(system.file("lucc_MT/data/samples.csv", package = "dtwSat")) -proj_str <- - scan(system.file("lucc_MT/data/samples_projection", package = "dtwSat"), - what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -set.seed(1) -I <- unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples <- field_samples[I, ] -validation_samples <- field_samples[-I, ] - -# Get time series form raster -training_ts <- getTimeSeries(rts, y = training_samples, proj4string = proj_str) -validation_ts <- getTimeSeries(rts, y = validation_samples, proj4string = proj_str) - -# Create temporal patterns -temporal_patterns <- createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Set TWDTW weight function -log_fun <- logisticWeight(-0.1, 50) - -# Run TWDTW analysis -system.time( - r_twdtw <- - twdtwApply(x = rts, y = temporal_patterns, weight.fun = log_fun, progress = 'text') -) - -# Plot TWDTW distances for the first year -plot(r_twdtw, type = "distance", time.levels = 1) - -# Classify raster based on the TWDTW analysis -r_lucc <- twdtwClassify(r_twdtw, progress = 'text') - -# Plot TWDTW classification results -plot(r_lucc, type = "map") - -# Assess classification -twdtw_assess <- - twdtwAssess(object = r_lucc, y = validation_samples, - proj4string = proj_str, conf.int = .95) - -# Plot map accuracy -plot(twdtw_assess, type = "accuracy") - -# Plot area uncertainty -plot(twdtw_assess, type = "area") - -# Plot misclassified samples -plot(twdtw_assess, type = "map", samples = "incorrect") - -# Get latex table with error matrix -twdtwXtable(twdtw_assess, table.type = "matrix") - -# Get latex table with error accuracy -twdtwXtable(twdtw_assess, table.type = "accuracy") - -# Get latex table with area uncertainty -twdtwXtable(twdtw_assess, table.type = "area") - -} - -\dontrun{ - -# Example of TWDTW analysis using raster files -library(dtwSat) -library(caret) - -# Load raster data -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") - -# Create raster time series -rts <- twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) - -# Load field samples and projection -field_samples <- - read.csv(system.file("lucc_MT/data/samples.csv", package = "dtwSat")) -proj_str <- - scan(system.file("lucc_MT/data/samples_projection", package = "dtwSat"), - what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -set.seed(1) -I <- unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples <- field_samples[I, ] -validation_samples <- field_samples[-I, ] - -# Get time series form raster -training_ts <- getTimeSeries(rts, y = training_samples, proj4string = proj_str) -validation_ts <- getTimeSeries(rts, y = validation_samples, proj4string = proj_str) - -# Create temporal patterns -temporal_patterns <- createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Set TWDTW weight function -log_fun <- logisticWeight(-0.1, 50) - -# Run TWDTW analysis -system.time( - r_twdtw <- - twdtwApply(x = rts, y = temporal_patterns, weight.fun = log_fun, progress = 'text') -) - -# Plot TWDTW distances for the first year -plot(r_twdtw, type = "distance", time.levels = 1) - -# Classify raster based on the TWDTW analysis -r_lucc <- twdtwClassify(r_twdtw, progress = 'text') - -# Plot TWDTW classification results -plot(r_lucc, type = "map") - -# Assess classification -twdtw_assess <- - twdtwAssess(object = r_lucc, y = validation_samples, - proj4string = proj_str, conf.int = .95) - -# Plot map accuracy -plot(twdtw_assess, type = "accuracy") - -# Plot area uncertainty -plot(twdtw_assess, type = "area") - -# Plot misclassified samples -plot(twdtw_assess, type = "map", samples = "incorrect") - -# Get latex table with error matrix -twdtwXtable(twdtw_assess, table.type = "matrix") - -# Get latex table with error accuracy -twdtwXtable(twdtw_assess, table.type = "accuracy") - -# Get latex table with area uncertainty -twdtwXtable(twdtw_assess, table.type = "area") - -} - -\dontrun{ - -# Example of TWDTW analysis using raster files -library(dtwSat) -library(caret) - -# Load raster data -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") - -# Create raster time series -rts <- twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) - -# Load field samples and projection -field_samples <- - read.csv(system.file("lucc_MT/data/samples.csv", package = "dtwSat")) -proj_str <- - scan(system.file("lucc_MT/data/samples_projection", package = "dtwSat"), - what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -set.seed(1) -I <- unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples <- field_samples[I, ] -validation_samples <- field_samples[-I, ] - -# Get time series form raster -training_ts <- getTimeSeries(rts, y = training_samples, proj4string = proj_str) -validation_ts <- getTimeSeries(rts, y = validation_samples, proj4string = proj_str) - -# Create temporal patterns -temporal_patterns <- createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Set TWDTW weight function -log_fun <- logisticWeight(-0.1, 50) - -# Run TWDTW analysis -system.time( - r_twdtw <- - twdtwApply(x = rts, y = temporal_patterns, weight.fun = log_fun, progress = 'text') -) - -# Plot TWDTW distances for the first year -plot(r_twdtw, type = "distance", time.levels = 1) - -# Classify raster based on the TWDTW analysis -r_lucc <- twdtwClassify(r_twdtw, progress = 'text') - -# Plot TWDTW classification results -plot(r_lucc, type = "map") - -# Assess classification -twdtw_assess <- - twdtwAssess(object = r_lucc, y = validation_samples, - proj4string = proj_str, conf.int = .95) - -# Plot map accuracy -plot(twdtw_assess, type = "accuracy") - -# Plot area uncertainty -plot(twdtw_assess, type = "area") - -# Plot misclassified samples -plot(twdtw_assess, type = "map", samples = "incorrect") - -# Get latex table with error matrix -twdtwXtable(twdtw_assess, table.type = "matrix") - -# Get latex table with error accuracy -twdtwXtable(twdtw_assess, table.type = "accuracy") - -# Get latex table with area uncertainty -twdtwXtable(twdtw_assess, table.type = "area") - -} - -\dontrun{ - -# Example of TWDTW analysis using raster files -library(dtwSat) -library(caret) - -# Load raster data -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") - -# Create raster time series -rts <- twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) - -# Load field samples and projection -field_samples <- - read.csv(system.file("lucc_MT/data/samples.csv", package = "dtwSat")) -proj_str <- - scan(system.file("lucc_MT/data/samples_projection", package = "dtwSat"), - what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -set.seed(1) -I <- unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples <- field_samples[I, ] -validation_samples <- field_samples[-I, ] - -# Get time series form raster -training_ts <- getTimeSeries(rts, y = training_samples, proj4string = proj_str) -validation_ts <- getTimeSeries(rts, y = validation_samples, proj4string = proj_str) - -# Create temporal patterns -temporal_patterns <- createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Set TWDTW weight function -log_fun <- logisticWeight(-0.1, 50) - -# Run TWDTW analysis -system.time( - r_twdtw <- - twdtwApply(x = rts, y = temporal_patterns, weight.fun = log_fun, progress = 'text') -) - -# Plot TWDTW distances for the first year -plot(r_twdtw, type = "distance", time.levels = 1) - -# Classify raster based on the TWDTW analysis -r_lucc <- twdtwClassify(r_twdtw, progress = 'text') - -# Plot TWDTW classification results -plot(r_lucc, type = "map") - -# Assess classification -twdtw_assess <- - twdtwAssess(object = r_lucc, y = validation_samples, - proj4string = proj_str, conf.int = .95) - -# Plot map accuracy -plot(twdtw_assess, type = "accuracy") - -# Plot area uncertainty -plot(twdtw_assess, type = "area") - -# Plot misclassified samples -plot(twdtw_assess, type = "map", samples = "incorrect") - -# Get latex table with error matrix -twdtwXtable(twdtw_assess, table.type = "matrix") - -# Get latex table with error accuracy -twdtwXtable(twdtw_assess, table.type = "accuracy") - -# Get latex table with area uncertainty -twdtwXtable(twdtw_assess, table.type = "area") - -} - -\dontrun{ - -# Example of TWDTW analysis using raster files -library(dtwSat) -library(caret) - -# Load raster data -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") - -# Create raster time series -rts <- twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) - -# Load field samples and projection -field_samples <- - read.csv(system.file("lucc_MT/data/samples.csv", package = "dtwSat")) -proj_str <- - scan(system.file("lucc_MT/data/samples_projection", package = "dtwSat"), - what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -set.seed(1) -I <- unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples <- field_samples[I, ] -validation_samples <- field_samples[-I, ] - -# Get time series form raster -training_ts <- getTimeSeries(rts, y = training_samples, proj4string = proj_str) -validation_ts <- getTimeSeries(rts, y = validation_samples, proj4string = proj_str) - -# Create temporal patterns -temporal_patterns <- createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Set TWDTW weight function -log_fun <- logisticWeight(-0.1, 50) - -# Run TWDTW analysis -system.time( - r_twdtw <- - twdtwApply(x = rts, y = temporal_patterns, weight.fun = log_fun, progress = 'text') -) - -# Plot TWDTW distances for the first year -plot(r_twdtw, type = "distance", time.levels = 1) - -# Classify raster based on the TWDTW analysis -r_lucc <- twdtwClassify(r_twdtw, progress = 'text') - -# Plot TWDTW classification results -plot(r_lucc, type = "map") - -# Assess classification -twdtw_assess <- - twdtwAssess(object = r_lucc, y = validation_samples, - proj4string = proj_str, conf.int = .95) - -# Plot map accuracy -plot(twdtw_assess, type = "accuracy") - -# Plot area uncertainty -plot(twdtw_assess, type = "area") - -# Plot misclassified samples -plot(twdtw_assess, type = "map", samples = "incorrect") - -# Get latex table with error matrix -twdtwXtable(twdtw_assess, table.type = "matrix") - -# Get latex table with error accuracy -twdtwXtable(twdtw_assess, table.type = "accuracy") - -# Get latex table with area uncertainty -twdtwXtable(twdtw_assess, table.type = "area") - -} - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{twdtwMatches-class}}, -\code{\link[dtwSat]{twdtwTimeSeries-class}}, and -\code{\link[dtwSat]{twdtwRaster-class}}, -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwCrossValidate.Rd b/man/twdtwCrossValidate.Rd deleted file mode 100644 index 25024a3..0000000 --- a/man/twdtwCrossValidate.Rd +++ /dev/null @@ -1,81 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/twdtwCrossValidate.R -\name{twdtwCrossValidate} -\alias{twdtwCrossValidate} -\alias{twdtwCrossValidate,twdtwTimeSeries-method} -\alias{twdtwCrossValidate-twdtwTimeSeries} -\title{Cross Validate temporal patterns} -\usage{ -\S4method{twdtwCrossValidate}{twdtwTimeSeries}(object, times, p, ...) -} -\arguments{ -\item{object}{An object of class \code{\link[dtwSat]{twdtwTimeSeries}}.} - -\item{times}{Number of partitions to create.} - -\item{p}{The percentage of data that goes to training. -See \code{\link[caret]{createDataPartition}} for details.} - -\item{...}{Other arguments to be passed to \code{\link[dtwSat]{createPatterns}} and -to \code{\link[dtwSat]{twdtwApply}}.} -} -\description{ -Splits the set of time series into training and validation and -computes accuracy metrics. The function uses stratified sampling and a simple -random sampling for each stratum. For each data partition this function -performs a TWDTW analysis and returns the Overall Accuracy, User's Accuracy, -Produce's Accuracy, error matrix (confusion matrix), and a \code{\link[base]{data.frame}} -with the classification (Predicted), the reference classes (Reference), -and the results of the TWDTW analysis. -} -\examples{ -\dontrun{ -# Data folder -data_folder = system.file("lucc_MT/data", package = "dtwSat") - -# Read dates -dates = scan(paste(data_folder,"timeline", sep = "/"), what = "dates") - -# Read raster time series -evi = brick(paste(data_folder,"evi.tif", sep = "/")) -raster_timeseries = twdtwRaster(evi, timeline = dates) - -# Read field samples -field_samples = read.csv(paste(data_folder,"samples.csv", sep = "/")) -table(field_samples[["label"]]) - -# Read field samples projection -proj_str = scan(paste(data_folder,"samples_projection", sep = "/"), - what = "character") - -# Get sample time series from raster time series -field_samples_ts = getTimeSeries(raster_timeseries, - y = field_samples, proj4string = proj_str) -field_samples_ts - -# Run cross validation -set.seed(1) -# Define TWDTW weight function -log_fun = logisticWeight(alpha=-0.1, beta=50) -cross_validation = twdtwCrossValidate(field_samples_ts, times=3, p=0.1, - freq = 8, formula = y ~ s(x, bs="cc"), weight.fun = log_fun) -cross_validation - -summary(cross_validation) - -plot(cross_validation) - -twdtwXtable(cross_validation) - -twdtwXtable(cross_validation, show.overall=FALSE) - -} -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwCrossValidation-class.Rd b/man/twdtwCrossValidation-class.Rd deleted file mode 100644 index f78ec53..0000000 --- a/man/twdtwCrossValidation-class.Rd +++ /dev/null @@ -1,85 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/class-crossValidation.R, R/methods.R -\name{twdtwCrossValidation-class} -\alias{twdtwCrossValidation-class} -\alias{twdtwCrossValidation} -\alias{show,twdtwCrossValidation-method} -\alias{summary,twdtwCrossValidation-method} -\title{class "twdtwCrossValidation"} -\usage{ -\S4method{show}{twdtwCrossValidation}(object) - -\S4method{summary}{twdtwCrossValidation}(object, conf.int = 0.95, ...) -} -\arguments{ -\item{object}{an object of class twdtwCrossValidation.} - -\item{conf.int}{specifies the confidence level (0-1) for interval estimation of the -population mean. For more details see \code{\link[ggplot2]{mean_cl_boot}}.} - -\item{...}{Other arguments. Not used.} -} -\description{ -This class stores the results of the cross-validation. -} -\section{Slots }{ - -\describe{ - \item{\code{partitions}:}{A list with the indices of time series used for training.} - \item{\code{accuracy}:}{A list with the accuracy and other TWDTW information for each - data partitions.} -} -} - -\examples{ -\dontrun{ -# Data folder -data_folder = system.file("lucc_MT/data", package = "dtwSat") - -# Read dates -dates = scan(paste(data_folder,"timeline", sep = "/"), what = "dates") - -# Read raster time series -evi = brick(paste(data_folder,"evi.tif", sep = "/")) -raster_timeseries = twdtwRaster(evi, timeline = dates) - -# Read field samples -field_samples = read.csv(paste(data_folder,"samples.csv", sep = "/")) -table(field_samples[["label"]]) - -# Read field samples projection -proj_str = scan(paste(data_folder,"samples_projection", sep = "/"), - what = "character") - -# Get sample time series from raster time series -field_samples_ts = getTimeSeries(raster_timeseries, - y = field_samples, proj4string = proj_str) -field_samples_ts - -# Run cross validation -set.seed(1) -# Define TWDTW weight function -log_fun = logisticWeight(alpha=-0.1, beta=50) -cross_validation = twdtwCrossValidate(field_samples_ts, times=3, p=0.1, - freq = 8, formula = y ~ s(x, bs="cc"), weight.fun = log_fun) -cross_validation - -summary(cross_validation) - -plot(cross_validation) - -} -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwMatches-class}}, -\code{\link[dtwSat]{createPatterns}}, and -\code{\link[dtwSat]{twdtwApply}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwMatches-class.Rd b/man/twdtwMatches-class.Rd deleted file mode 100644 index 7ad7654..0000000 --- a/man/twdtwMatches-class.Rd +++ /dev/null @@ -1,131 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/class-twdtwMatches.R, R/methods.R -\name{twdtwMatches-class} -\alias{twdtwMatches-class} -\alias{twdtwMatches} -\alias{twdtwMatches,ANY-method} -\alias{twdtwMatches-create} -\alias{index,twdtwMatches-method} -\alias{length,twdtwMatches-method} -\alias{as.list,twdtwMatches-method} -\alias{as.list,twdtwRaster-method} -\alias{[,twdtwMatches,ANY,ANY,ANY-method} -\alias{[[,twdtwMatches,numeric,ANY-method} -\alias{labels,twdtwMatches-method} -\alias{show,twdtwMatches-method} -\alias{is.twdtwMatches,ANY-method} -\alias{is.twdtwMatches} -\title{class "twdtwMatches"} -\usage{ -\S4method{twdtwMatches}{ANY}(timeseries = NULL, patterns = NULL, alignments = NULL) - -\S4method{index}{twdtwMatches}(x) - -\S4method{length}{twdtwMatches}(x) - -\S4method{as.list}{twdtwMatches}(x) - -\S4method{as.list}{twdtwRaster}(x) - -\S4method{[}{twdtwMatches,ANY,ANY,ANY}(x, i, j, drop = TRUE) - -\S4method{[[}{twdtwMatches,numeric,ANY}(x, i, j, drop = TRUE) - -\S4method{labels}{twdtwMatches}(object) - -\S4method{show}{twdtwMatches}(object) - -\S4method{is.twdtwMatches}{ANY}(x) -} -\arguments{ -\item{timeseries}{a \code{\link[dtwSat]{twdtwTimeSeries}} object.} - -\item{patterns}{a \code{\link[dtwSat]{twdtwTimeSeries}} object.} - -\item{alignments}{an object of class list with the TWDTW results with -the same length as \code{timeseries} or a list of twdtwMatches.} - -\item{x}{an object of class twdtwMatches.} - -\item{i}{indices of the time series.} - -\item{j}{indices of the pattern.} - -\item{drop}{if TRUE returns a data.frame, if FALSE returns a list. -Default is TRUE.} - -\item{object}{an object of class twdtwMatches.} - -\item{labels}{a vector with labels of the time series.} -} -\description{ -Class for Time-Weighted Dynamic Time Warping results. -} -\section{Methods (by generic)}{ -\itemize{ -\item \code{twdtwMatches(ANY)}: Create object of class twdtwMatches. - -\item \code{is.twdtwMatches(ANY)}: Check if the object belongs to the class twdtwMatches. - -}} -\section{Slots }{ - -\describe{ - \item{\code{timeseries}:}{An object of class \code{\link[dtwSat]{twdtwTimeSeries-class}} with the satellite time series.} - \item{\code{pattern}:}{An object of class \code{\link[dtwSat]{twdtwTimeSeries-class}} with the temporal patterns.} - \item{\code{alignments}:}{A \code{\link[base]{list}} of TWDTW results with the same length as - the \code{timeseries}. Each element in this list has the following results for each temporal pattern - in \code{patterns}: - \cr\code{from}: a vector with the starting dates of each match in the format "YYYY-MM-DD", - \cr\code{to}: a vector with the ending dates of each match in the format "YYYY-MM-DD", - \cr\code{distance}: a vector with TWDTW dissimilarity measure, and - \cr\code{K}: the number of matches of the pattern. - } - \item{This list might have additional elements:}{ if \code{keep=TRUE} in the \code{twdtwApply} call - the list is extended to include internal structures used during the TWDTW computation: - \cr\code{costMatrix}: cumulative cost matrix, - \cr\code{directionMatrix}: directions of steps that would be taken from each element of matrix, - \cr\code{startingMatrix}: the starting points of each element of the matrix, - \cr\code{stepPattern}: \code{\link[dtw]{stepPattern}} used for the - computation, see package \code{\link[dtw]{dtw}}, - \cr\code{N}: the length of the \code{pattern}, - \cr\code{M}: the length of the time series \code{timeseries}, - \cr\code{timeWeight}: time weight matrix, - \cr\code{localMatrix}: local cost matrix, - \cr\code{matching}: A list whose elements have the matching points for - each match between pattern the time series, such that: - \cr--\code{index1}: a vector with matching points of the pattern, and - \cr--\code{index2}: a vector with matching points of the time series. - } -} -} - -\examples{ -ts = twdtwTimeSeries(timeseries=MOD13Q1.ts.list) -patterns = twdtwTimeSeries(timeseries=MOD13Q1.patterns.list) -matches = twdtwApply(x = ts, y = patterns, keep=TRUE, legacy=TRUE) -class(matches) -length(matches) -matches -# Creating objects of class twdtwMatches -ts = twdtwTimeSeries(MOD13Q1.ts.list) -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -mat = twdtwApply(ts, patt, weight.fun = logisticWeight(-0.1, 100), - keep=TRUE, legacy=TRUE) -mat = twdtwMatches(ts, patterns=patt, alignments=mat) -mat - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{twdtwTimeSeries-class}}, and -\code{\link[dtwSat]{twdtwRaster-class}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwRaster-class.Rd b/man/twdtwRaster-class.Rd deleted file mode 100644 index e1ab6a0..0000000 --- a/man/twdtwRaster-class.Rd +++ /dev/null @@ -1,203 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/class-twdtwRaster.R, R/methods.R -\name{twdtwRaster-class} -\alias{twdtwRaster-class} -\alias{twdtwRaster} -\alias{twdtwRaster,ANY-method} -\alias{twdtwRaster-create} -\alias{dim,twdtwRaster-method} -\alias{res,twdtwRaster-method} -\alias{extent,twdtwRaster-method} -\alias{writeRaster,twdtwRaster,ANY-method} -\alias{ncol,twdtwRaster-method} -\alias{nrow,twdtwRaster-method} -\alias{nlayers,twdtwRaster-method} -\alias{levels,twdtwRaster-method} -\alias{layers,twdtwRaster-method} -\alias{layers} -\alias{coverages,twdtwRaster-method} -\alias{coverages} -\alias{bands,twdtwRaster-method} -\alias{bands} -\alias{names,twdtwRaster-method} -\alias{index,twdtwRaster-method} -\alias{length,twdtwRaster-method} -\alias{[,twdtwRaster,ANY,ANY,ANY-method} -\alias{[[,twdtwRaster,ANY,ANY-method} -\alias{labels,twdtwRaster-method} -\alias{crop,twdtwRaster-method} -\alias{coordinates,twdtwRaster-method} -\alias{show,twdtwRaster-method} -\alias{is.twdtwRaster,ANY-method} -\alias{is.twdtwRaster} -\alias{projecttwdtwRaster,twdtwRaster-method} -\alias{projecttwdtwRaster} -\title{class "twdtwRaster"} -\usage{ -\S4method{twdtwRaster}{ANY}( - ..., - timeline, - doy = NULL, - layers = NULL, - labels = NULL, - levels = NULL, - filepath = NULL -) - -\S4method{dim}{twdtwRaster}(x) - -\S4method{res}{twdtwRaster}(x) - -\S4method{extent}{twdtwRaster}(x, y, ...) - -\S4method{writeRaster}{twdtwRaster,ANY}(x, filepath = ".", ...) - -\S4method{ncol}{twdtwRaster}(x) - -\S4method{nrow}{twdtwRaster}(x) - -\S4method{nlayers}{twdtwRaster}(x) - -\S4method{levels}{twdtwRaster}(x) - -\S4method{layers}{twdtwRaster}(x) - -\S4method{coverages}{twdtwRaster}(x) - -\S4method{bands}{twdtwRaster}(x) - -\S4method{names}{twdtwRaster}(x) - -\S4method{index}{twdtwRaster}(x) - -\S4method{length}{twdtwRaster}(x) - -\S4method{[}{twdtwRaster,ANY,ANY,ANY}(x, i) - -\S4method{[[}{twdtwRaster,ANY,ANY}(x, i) - -\S4method{labels}{twdtwRaster}(object) - -\S4method{crop}{twdtwRaster}(x, y, ...) - -\S4method{coordinates}{twdtwRaster}(obj, ...) - -\S4method{extent}{twdtwRaster}(x, y, ...) - -\S4method{show}{twdtwRaster}(object) - -\S4method{is.twdtwRaster}{ANY}(x) - -\S4method{projecttwdtwRaster}{twdtwRaster}(x, crs, ...) -} -\arguments{ -\item{...}{objects of class \code{\link[raster]{RasterBrick-class}} or -\code{\link[raster]{RasterStack-class}}.} - -\item{timeline}{a vector with the dates of the satellite images -in the format of "YYYY-MM-DD".} - -\item{doy}{A \code{\link[raster]{RasterBrick-class}} or -\code{\link[raster]{RasterStack-class}} with a sequence of days of the year for each pixel. -\code{doy} must have the same spatial and temporal extents as the Raster* objects passed to \code{...}. -If \code{doy} is not provided then at least one Raster* object must be passed through \code{...}.} - -\item{layers}{a vector with the names of the \code{Raster*} objects -passed to "\code{...}". If not provided the layers are set to the -names of objects in "\code{...}".} - -\item{labels}{a vector of class \code{\link[base]{character}} with -labels of the values in the Raster* objects. This is -useful for categorical Raster* values of land use classes.} - -\item{levels}{a vector of class \code{\link[base]{numeric}} with -levels of the values in the Raster* objects. This is -useful for categorical Raster* values of land use classes.} - -\item{filepath}{A character. The path to save the raster time series. If provided the -function saves a raster file for each Raster* object in the list, \emph{i.e} one file -for each time series. This way the function retrieves a list of -\code{\link[raster]{RasterBrick-class}}. It is useful when the time series are -originally stored in separated files. See details.} - -\item{x}{an object of class twdtwRaster.} - -\item{y}{Extent object, or any object from which an Extent object can be extracted.} - -\item{i}{indices of the time series.} - -\item{object}{an object of class twdtwRaster.} - -\item{obj}{object of class twdtwRaster.} - -\item{crs}{character or object of class 'CRS'. PROJ.4 description of -the coordinate reference system. For other arguments and more details see -\code{\link[raster]{projectRaster}}.} -} -\description{ -Class for set of satellite time series. -} -\details{ -The performance of the functions \code{\link[dtwSat]{twdtwApply}} and -\code{\link[dtwSat]{getTimeSeries}} is improved if the Raster* objects are connected -to files with the whole time series for each attribute. -} -\section{Methods (by generic)}{ -\itemize{ -\item \code{twdtwRaster(ANY)}: Create object of class twdtwRaster. - -\item \code{is.twdtwRaster(ANY)}: Check if the object belongs to the class twdtwRaster. - -\item \code{projecttwdtwRaster(twdtwRaster)}: project twdtwRaster object. - -}} -\section{Slots }{ - -\describe{ - \item{\code{timeseries}:}{A list of multi-layer Raster* objects - with the satellite image time series.} - \item{\code{timeline}:}{A vector of class \code{\link[base]{date}} - with dates of the satellite images in \code{timeseries}.} - \item{\code{layers}:}{A vector of class \code{\link[base]{character}} - with the names of the Raster* objects.} - \item{\code{labels}:}{A vector of class \code{\link[base]{factor}} - with levels and labels of the values in the Raster* objects. This - is useful for categorical Raster* values of land use classes.} -} -} - -\examples{ -# Creating a new object of class twdtwTimeSeries -evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) -timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") -rts = new("twdtwRaster", timeseries = evi, timeline = timeline) - -\dontrun{ -# Creating objects of class twdtwRaster -evi = brick(system.file("lucc_MT/data/evi.tif", package="dtwSat")) -timeline = scan(system.file("lucc_MT/data/timeline", package="dtwSat"), what="date") -ts_evi = twdtwRaster(evi, timeline=timeline) - -ndvi = brick(system.file("lucc_MT/data/ndvi.tif", package="dtwSat")) -blue = brick(system.file("lucc_MT/data/blue.tif", package="dtwSat")) -red = brick(system.file("lucc_MT/data/red.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")) -rts = twdtwRaster(doy, evi, ndvi, blue, red, nir, mir, timeline = timeline) -} -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwApply}}, -\code{\link[dtwSat]{getTimeSeries}}, -\code{\link[dtwSat]{twdtwMatches-class}}, and -\code{\link[dtwSat]{twdtwTimeSeries-class}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwReduceTime.Rd b/man/twdtwReduceTime.Rd deleted file mode 100644 index 2f9a466..0000000 --- a/man/twdtwReduceTime.Rd +++ /dev/null @@ -1,108 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/twdtw_reduce_time.R -\name{twdtwReduceTime} -\alias{twdtwReduceTime} -\title{Faster version of TWDTW apply} -\usage{ -twdtwReduceTime( - x, - y, - alpha = -0.1, - beta = 50, - time.window = FALSE, - dist.method = "Euclidean", - step.matrix = symmetric1, - from = NULL, - to = NULL, - by = NULL, - breaks = NULL, - overlap = 0.5, - fill = length(y) + 1, - keep = FALSE, - ... -) -} -\arguments{ -\item{x}{a data.frame with the target time series. Usually, it is an -unclassified time series. It must contain two or more columns, one column -called \code{date} with dates in the format "YYYY-MM-DD". The other columns -can have any names (e.g., red, blue, nir, evi, ndvi) as long as they match -the column names in the temporal patterns \code{y}.} - -\item{y}{a list of data.frame objects similar to \code{x}. -The temporal patterns used to classify the time series in \code{x}.} - -\item{alpha}{Numeric. The steepness of TWDTW logistic weight.} - -\item{beta}{Numeric. The midpoint of TWDTW logistic weight.} - -\item{time.window}{logical. TRUE will constrain the TWDTW computation to the -value of the parameter \code{beta} defined in the logistic weight function. -Default is FALSE.} - -\item{dist.method}{A character. Method to derive the local cost matrix. -Default is ''Euclidean'' see \code{\link[proxy]{dist}} in package -\pkg{proxy}.} - -\item{step.matrix}{See \code{\link[dtw]{stepPattern}} in package \pkg{dtw} -\insertCite{Giorgino:2009}{dtwSat}.} - -\item{from}{A character or \code{\link[base]{Dates}} object in the format "yyyy-mm-dd".} - -\item{to}{A \code{\link[base]{character}} or \code{\link[base]{Dates}} object in the format "yyyy-mm-dd".} - -\item{by}{A \code{\link[base]{character}} with the interval size, \emph{e.g.} "6 month".} - -\item{breaks}{A vector of class \code{\link[base]{Dates}}. This replaces the arguments \code{from}, -\code{to}, and \code{by}.} - -\item{overlap}{A number between 0 and 1. The minimum overlapping -between one match and the interval of classification. Default is 0.5, -\emph{i.e.} an overlap minimum of 50\%.} - -\item{fill}{An integer to fill the classification gaps.} - -\item{keep}{Preserves the cost matrix, inputs, and other internal structures. -Default is FALSE. For plot methods use \code{keep=TRUE}.} - -\item{...}{Arguments to pass to \code{\link[raster]{writeRaster}} and -\code{\link[raster]{pbCreate}}} -} -\description{ -This function is a faster implementation of -\link[dtwSat]{twdtwApply} that is in average 4x faster. The time weight function -is coded in Fortran. It does not keep any intermediate data. -It performs a multidimensional TWDTW analysis -\insertCite{Maus:2019}{dtwSat} and retrieves only the best matches between -the unclassified time series and the patterns for each defined time interval. -} -\examples{ -\dontrun{ - -library(dtwSat) -from = "2009-09-01" -to = "2017-09-01" -by = "12 month" - -# S4 objects for original implementation -tw_patt = readRDS(system.file("lucc_MT/patterns/patt.rds", package = "dtwSat")) -tw_ts = twdtwTimeSeries(MOD13Q1.ts) - -# Table from csv for faster version -mn_patt <- lapply(dir(system.file("lucc_MT/patterns", package = "dtwSat"), - pattern = ".csv$", full.names = TRUE), read.csv, stringsAsFactors = FALSE) -mn_ts <- read.csv(system.file("reduce_time/ts_MODIS13Q1.csv", package = "dtwSat"), - stringsAsFactors = FALSE) - -# Benchtmark -rbenchmark::benchmark( - legacy_twdtw = twdtwClassify(twdtwApply(x = tw_ts, y = tw_patt, weight.fun = log_fun), - from = from, to = to, by = by)[[1]], - fast_twdtw = twdtwReduceTime(x = mn_ts, y = mn_patt, rom = from, to = to, by = by) - ) -} - -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwTimeSeries-class.Rd b/man/twdtwTimeSeries-class.Rd deleted file mode 100644 index 2ce2304..0000000 --- a/man/twdtwTimeSeries-class.Rd +++ /dev/null @@ -1,127 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/class-twdtwTimeSeries.R, R/methods.R -\name{twdtwTimeSeries-class} -\alias{twdtwTimeSeries-class} -\alias{twdtwTimeSeries} -\alias{twdtwTimeSeries,ANY-method} -\alias{twdtwTimeSeries-create} -\alias{dim,twdtwTimeSeries-method} -\alias{index,twdtwTimeSeries-method} -\alias{nrow,twdtwTimeSeries-method} -\alias{ncol,twdtwTimeSeries-method} -\alias{length,twdtwTimeSeries-method} -\alias{as.list,twdtwTimeSeries-method} -\alias{as.data.frame,twdtwTimeSeries-method} -\alias{[,twdtwTimeSeries,ANY,ANY,ANY-method} -\alias{[[,twdtwTimeSeries,ANY,ANY-method} -\alias{labels,twdtwTimeSeries-method} -\alias{levels,twdtwTimeSeries-method} -\alias{show,twdtwTimeSeries-method} -\alias{as.twdtwTimeSeries,ANY-method} -\alias{as.twdtwTimeSeries} -\alias{is.twdtwTimeSeries,ANY-method} -\alias{is.twdtwTimeSeries} -\title{class "twdtwTimeSeries"} -\usage{ -\S4method{twdtwTimeSeries}{ANY}(..., labels = NULL) - -\S4method{dim}{twdtwTimeSeries}(x) - -\S4method{index}{twdtwTimeSeries}(x) - -\S4method{nrow}{twdtwTimeSeries}(x) - -\S4method{ncol}{twdtwTimeSeries}(x) - -\S4method{length}{twdtwTimeSeries}(x) - -\S4method{as.list}{twdtwTimeSeries}(x) - -\S4method{as.data.frame}{twdtwTimeSeries}(x) - -\S4method{[}{twdtwTimeSeries,ANY,ANY,ANY}(x, i) - -\S4method{[[}{twdtwTimeSeries,ANY,ANY}(x, i) - -\S4method{labels}{twdtwTimeSeries}(object) - -\S4method{levels}{twdtwTimeSeries}(x) - -\S4method{show}{twdtwTimeSeries}(object) - -\S4method{as.twdtwTimeSeries}{ANY}(x) - -\S4method{is.twdtwTimeSeries}{ANY}(x) -} -\arguments{ -\item{...}{\code{\link[dtwSat]{twdtwTimeSeries}} objects, -\code{\link[zoo]{zoo}} objects or a list of \code{\link[zoo]{zoo}} objects.} - -\item{labels}{a vector with labels of the time series.} - -\item{x}{an object of class twdtwTimeSeries.} - -\item{i}{indices of the time series.} - -\item{object}{an object of class twdtwTimeSeries.} -} -\description{ -Class for setting irregular time series. -} -\section{Methods (by generic)}{ -\itemize{ -\item \code{twdtwTimeSeries(ANY)}: Create object of class twdtwTimeSeries. - -\item \code{as.twdtwTimeSeries(ANY)}: convert list of data.frame to class twdtwTimeSeries. - -\item \code{is.twdtwTimeSeries(ANY)}: Check if the object belongs to the class twdtwTimeSeries. - -}} -\section{Slots }{ - -\describe{ - \item{\code{timeseries}:}{A list of \code{\link[zoo]{zoo}} objects.} - \item{\code{labels}:}{A vector of class \code{\link[base]{factor}} with time series labels.} -} -} - -\examples{ -# Creating a new object of class twdtwTimeSeries -ptt = new("twdtwTimeSeries", timeseries = MOD13Q1.patterns.list, - labels = names(MOD13Q1.patterns.list)) -class(ptt) -labels(ptt) -levels(ptt) -length(ptt) -nrow(ptt) -ncol(ptt) -dim(ptt) -# Creating objects of class twdtwTimeSeries from zoo objects -ts = twdtwTimeSeries(MOD13Q1.ts) -ts - -# Creating objects of class twdtwTimeSeries from list of zoo objects -patt = twdtwTimeSeries(MOD13Q1.patterns.list) -patt - -# Joining objects of class twdtwTimeSeries -tsA = twdtwTimeSeries(MOD13Q1.ts.list[[1]], labels = "A") -tsB = twdtwTimeSeries(B = MOD13Q1.ts.list[[2]]) -ts = twdtwTimeSeries(tsA, tsB, C=MOD13Q1.ts) -ts - -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwMatches-class}}, -\code{\link[dtwSat]{twdtwRaster-class}}, -\code{\link[dtwSat]{getTimeSeries}}, and -\code{\link[dtwSat]{twdtwApply}} -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/man/twdtwXtable.Rd b/man/twdtwXtable.Rd deleted file mode 100644 index 94b3c82..0000000 --- a/man/twdtwXtable.Rd +++ /dev/null @@ -1,139 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/twdtwXtable.R -\name{twdtwXtable} -\alias{twdtwXtable} -\alias{twdtwXtable,twdtwAssessment-method} -\alias{twdtwXtable-twdtwAssessment} -\alias{twdtwXtable,twdtwCrossValidation-method} -\alias{twdtwXtable-twdtwCrossValidation} -\title{LaTeX table from accuracy metrics} -\usage{ -\S4method{twdtwXtable}{twdtwAssessment}( - object, - table.type = "accuracy", - show.prop = TRUE, - category.name = NULL, - category.type = NULL, - rotate.col = FALSE, - time.labels = NULL, - caption = NULL, - digits = 2, - show.footnote = TRUE, - ... -) - -\S4method{twdtwXtable}{twdtwCrossValidation}( - object, - conf.int = 0.95, - show.overall = TRUE, - category.name = NULL, - category.type = NULL, - caption = NULL, - digits = 2, - show.footnote = TRUE, - ... -) -} -\arguments{ -\item{object}{an object of class twdtwAssessment.} - -\item{table.type}{Table type, 'accuracy' for User's and Producer's Accuracy, -'errormatrix' for error matrix, and 'area' for area and uncertainty. -Default is 'accuracy'.} - -\item{show.prop}{If TRUE shows the estimated proportion of area. -Used with \code{table.type='accuracy'}. Default is TRUE.} - -\item{category.name}{A character vector defining the class names. If NULL -the class names in the object \code{x} are used. Default is NULL.} - -\item{category.type}{A character defining the categories type "numeric" -or "letter", if NULL the class names are used. Default is NULL.} - -\item{rotate.col}{Rotate class column names in latex table. Default is FALSE.} - -\item{time.labels}{A character or numeric for the time period or NULL to -include all classified periods. Default is NULL.} - -\item{caption}{The table caption.} - -\item{digits}{Number of digits to show.} - -\item{show.footnote}{Show confidence interval in the footnote.} - -\item{...}{Other arguments to pass to \code{\link[xtable]{print.xtable}}.} - -\item{conf.int}{Specifies the confidence level (0-1).} - -\item{show.overall}{If TRUE shows the overall accuracy of the cross-validation. -Default is TRUE.} -} -\description{ -Creates LaTeX table from accuracy metrics -} -\examples{ -\dontrun{ - -# Create raster time series -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) - -# Read field samples -field_samples = read.csv(system.file("lucc_MT/data/samples.csv", package="dtwSat")) -proj_str = scan(system.file("lucc_MT/data/samples_projection", - package="dtwSat"), what = "character") - -# Split samples for training (10\%) and validation (90\%) using stratified sampling -library(caret) -set.seed(1) -I = unlist(createDataPartition(field_samples$label, p = 0.1)) -training_samples = field_samples[I,] -validation_samples = field_samples[-I,] - -# Create temporal patterns -training_ts = getTimeSeries(rts, y = training_samples, proj4string = proj_str) -temporal_patterns = createPatterns(training_ts, freq = 8, formula = y ~ s(x)) - -# Run TWDTW analysis for raster time series -log_fun = weight.fun=logisticWeight(-0.1,50) -r_twdtw = twdtwApply(x=rts, y=temporal_patterns, weight.fun=log_fun, format="GTiff", - overwrite=TRUE) - -# Classify raster based on the TWDTW analysis -r_lucc = twdtwClassify(r_twdtw, format="GTiff", overwrite=TRUE) -plot(r_lucc) - -# Assess classification -twdtw_assess = twdtwAssess(object = r_lucc, y = validation_samples, - proj4string = proj_str, conf.int=.95) -twdtw_assess - -# Create latex tables -twdtwXtable(twdtw_assess, table.type="errormatrix", rotate.col=TRUE, - caption="Error matrix", digits=2, comment=FALSE) -twdtwXtable(twdtw_assess, table.type="accuracy", category.type="letter", - caption="Accuracy metrics.") -twdtwXtable(twdtw_assess, table.type="area", category.type="letter", - digits = 0, caption="Area and uncertainty") - -} -} -\references{ -\insertRef{Maus:2019}{dtwSat} - - \insertRef{Maus:2016}{dtwSat} -} -\seealso{ -\code{\link[dtwSat]{twdtwAssess}} and -\code{\link[dtwSat]{twdtwAssessment}}. -} -\author{ -Victor Maus, \email{vwmaus1@gmail.com} -} diff --git a/src/bestmatches.f b/src/bestmatches.f deleted file mode 100644 index 82642d1..0000000 --- a/src/bestmatches.f +++ /dev/null @@ -1,80 +0,0 @@ -CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -C C -C (c) Victor Maus C -C Institute for Geoinformatics (IFGI) C -C University of Muenster (WWU), Germany C -C C -C Earth System Science Center (CCST) C -C National Institute for Space Research (INPE), Brazil C -C C -C C -C Find best matches TWDTW - 2016-03-26 C -C C -CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -C -C XM - Two columns matrix with 'from' and 'to' dates as integers -C AM - Matrix (P-1 x L) with classification intervals (P-1) and possible classes (L) -C DM - Vector length K DTW distance for each alignment -C DP - Vector length P-1 with classification intervals -C X - Vector length K with alignments index -C IM - Matrix to return best matches, intervals, and class labels -C A - Vector with alignment index -C K - Number of alignments -C P - Number of dates defineing classification intervals -C L - Number of classes -C OV - Minimum temporal overlap - SUBROUTINE bestmatches(XM,AM,DM,DP,X,IM,DB,A,K,P,L,OV) -C I/O Variables - INTEGER K, P, L, XM(K,2), X(K), DP(P), IM(P-1,4), A(K) - DOUBLE PRECISION AM(P-1,L), DD, DM(K), OV, DB(P-1) -C Internals - DOUBLE PRECISION R - INTEGER I, J, IL, B1, B2, D1, D2 -C For all time intervals - DO 30 J = 1, P-1 - B1 = DP(J) - B2 = DP(J+1) - DD = AM(J,1) - -C For all TWDTW matches - DO 20 I = 1, K -C print *, "I: ", I - D1 = XM(I,1) - D2 = XM(I,2) - IL = X(I) - IF ((D2.LT.B1).OR.(D1.GT.B2)) THEN -C print *, "D1: ", D1, "D2: ", D2 - GOTO 20 - ENDIF - IF (D1.LT.B1) THEN - D1 = B1 - ENDIF - IF (B2.LT.D2) THEN - D2 = B2 - ENDIF - R = REAL(D2 - D1) / REAL(B2 - B1) - IF( .NOT.(OV.LE.R.AND.R.LE.(2-OV)) ) THEN -C print *, "R: ", R - GOTO 20 - ENDIF - IF( DM(I).GE.AM(J,IL) ) THEN -C print *, "DM(I): ", DM(I) - GOTO 20 - ENDIF - AM(J,IL) = DM(I) - IF( DM(I).LT.DD ) THEN - DD = DM(I) - IM(J,1) = IL - IM(J,2) = I - IM(J,3) = A(I) -C print *, "IM: ", IM - DB(J) = DD - ENDIF - 20 CONTINUE - 30 CONTINUE - END - - - - - diff --git a/src/computecost.f b/src/computecost.f deleted file mode 100644 index 962fd89..0000000 --- a/src/computecost.f +++ /dev/null @@ -1,89 +0,0 @@ -CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -C C -C (c) Victor Maus C -C Institute for Geoinformatics (IFGI) C -C University of Muenster (WWU), Germany C -C C -C Earth System Science Center (CCST) C -C National Institute for Space Research (INPE), Brazil C -C C -C C -C Efficient computation of DTW cost matrix - 2015-10-16 C -C C -C This function was adpted from the C function 'computeCM' C -C implemented in the R package 'dtw' by Toni Giorgino. C -CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -C -C CM - Input local cost and output cumulative cost matrix -C DM - Direction matrix -C VM - Starting points matrix -C SM - Matrix of step patterns -C N - Number of rows in CM, DM, and VM -C M - Number of columns CM, DM, and VM -C NS - Number of rows in SM - SUBROUTINE computecost(CM, DM, VM, SM, N, M, NS) -C 800 FORMAT(I4,I4,I4,I4,F8.0,F8.0) -C I/O Variables - INTEGER N, M, NS, SM(NS,4), DM(N,M), VM(N,M) - DOUBLE PRECISION CM(N,M) -C Internals - DOUBLE PRECISION W, CP(NS), VMIN - INTEGER I, J, IL(NS), JL(NS), K, PK, KMIN, ZERO, ONE - PARAMETER(ZERO=0,ONE=1) - REAL NAN, INF - NAN = ZERO - NAN = NAN / NAN - INF = HUGE(ZERO) - VM(1,1) = 1 -C Initialize the firt row and col of the matrices - DO 21 I = 2, N - CM(I,1) = CM(I-1,1) + CM(I,1) - DM(I,1) = 3 - VM(I,1) = 1 - 21 CONTINUE - DO 31 J = 2, M - CM(1,J) = CM(1,J-1) + CM(1,J) - DM(1,J) = 2 - VM(1,J) = J - 31 CONTINUE -C Compute cumulative cost matrix - DO 32 J = 2, M - DO 22 I = 2, N -C Initialize list of step cost - DO 10 K = 1, NS - CP(K) = NAN - 10 CONTINUE - DO 11 K = 1, NS - PK = SM(K,1) - IL(K) = I - SM(K,2) - JL(K) = J - SM(K,3) - IF ((IL(K).GT.ZERO).AND.(JL(K).GT.ZERO)) THEN - W = SM(K,4) - IF (W.EQ.-ONE) THEN - CP(PK) = CM(IL(K),JL(K)) - ELSE - CP(PK) = CP(PK) + CM(IL(K),JL(K))*W - ENDIF - ENDIF - 11 CONTINUE - KMIN = -ONE - VMIN = INF - ILMIN = -ONE - JLMIN = -ONE - DO 12 K = 1, NS - PK = SM(K,1) - IF (CP(PK).EQ.CP(PK).AND.CP(PK).LT.VMIN) THEN - KMIN = PK - VMIN = CP(PK) - ILMIN = IL(K) - JLMIN = JL(K) - ENDIF - 12 CONTINUE - IF (KMIN.GT.-ONE) THEN - CM(I,J) = VMIN - DM(I,J) = KMIN - VM(I,J) = VM(ILMIN, JLMIN) - ENDIF - 22 CONTINUE - 32 CONTINUE - END diff --git a/src/ellapsed.f b/src/ellapsed.f deleted file mode 100644 index a854ad0..0000000 --- a/src/ellapsed.f +++ /dev/null @@ -1,17 +0,0 @@ -C Computation ellapsed time in days -C -C TD - time difference in days - SUBROUTINE ellapsed(TD) - DOUBLE PRECISION TD, HPC - PARAMETER(PC=366.0) - HPC = PC/2 -C Compute ellapsed time difference - TD = SQRT(TD * TD) -C Correct ellapsed time with year cycle - IF (TD.GT.HPC) THEN - TD = PC - TD - ENDIF - TD = ABS(TD) - RETURN - END - diff --git a/src/g.f b/src/g.f deleted file mode 100644 index 8406ffc..0000000 --- a/src/g.f +++ /dev/null @@ -1,37 +0,0 @@ -CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -C C -C (c) Victor Maus C -C Institute for Geoinformatics (IFGI) C -C University of Muenster (WWU), Germany C -C C -C Earth System Science Center (CCST) C -C National Institute for Space Research (INPE), Brazil C -C C -C C -C Computation allapsed time - 2016-01-22 C -C C -CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -C -C TM - Time difference matrix -C N - Number of rows in CM -C M - Number of columns CM -C PC - Cycle length in the unity of the measurements - SUBROUTINE g(TM, N, M, PC) -C I/O Variables - INTEGER N, M - DOUBLE PRECISION TM(N,M), PC -C Internals - DOUBLE PRECISION HPC - INTEGER I, J - PARAMETER(TWO=2.0) - HPC = PC/2 -C Compute ellapsed time matrix - DO 30 J = 1, M - DO 20 I = 1, N - IF (TM(I,J).GT.HPC) THEN - TM(I,J) = ABS(PC - TM(I,J)) - ENDIF - 20 CONTINUE - 30 CONTINUE - END - \ No newline at end of file diff --git a/src/init.c b/src/init.c deleted file mode 100644 index de747f3..0000000 --- a/src/init.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include // for NULL -#include - - -/* FIXME: - Check these declarations against the C/Fortran source code. - */ - -/* .Fortran calls */ -extern void F77_NAME(bestmatches)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); -extern void F77_NAME(computecost)(void *, void *, void *, void *, void *, void *, void *); -extern void F77_NAME(twdtw)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); -extern void F77_NAME(g)(void *, void *, void *, void *); -extern void F77_NAME(tracepath)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); - -static const R_FortranMethodDef FortranEntries[] = { - {"bestmatches", (DL_FUNC) &F77_NAME(bestmatches), 12}, - {"computecost", (DL_FUNC) &F77_NAME(computecost), 7}, - {"twdtw", (DL_FUNC) &F77_NAME(twdtw), 13}, - {"g", (DL_FUNC) &F77_NAME(g), 4}, - {"tracepath", (DL_FUNC) &F77_NAME(tracepath), 11}, - {NULL, NULL, 0} -}; - -void R_init_dtwSat(DllInfo *dll) -{ - R_registerRoutines(dll, NULL, NULL, FortranEntries, NULL); - R_useDynamicSymbols(dll, FALSE); - R_forceSymbols(dll, FALSE); -} - - diff --git a/src/logtwdtw.f b/src/logtwdtw.f deleted file mode 100644 index a8d0480..0000000 --- a/src/logtwdtw.f +++ /dev/null @@ -1,31 +0,0 @@ -C Compute TWDTW distance using logistic weight -C -C XM - matrix with the time series (N,D) -C YM - matrix with the temporal profile (M,D) -C N - Number of rows in CM, DM, and VM - time series -C M - Number of columns CM, DM, and VM - temporal profile -C D - Number of spectral dimensions including time in XM and YM -C I - Single point in the time series to calculate the local distance -C J - Single point in the temporal profile to calculate the local distance -C A - Time-Weight parameter alpha -C B - Time-Weight parameter beta - REAL FUNCTION distance(YM, XM, N, M, D, I, J, TW, TD) - INTEGER N, M, D, I, J, K - DOUBLE PRECISION XM(M,D), YM(N,D), TD, BD, CD, TW(2) - PARAMETER(ZERO=0) - REAL NAN - NAN = ZERO - NAN = NAN / NAN - distance = NAN -C TD = YM(I,1) - XM(J,1) -C CALL ellapsed(TD) - CD = ZERO - DO 30 K = 2, D - BD = YM(I,K) - XM(J,K) - CD = CD + (BD * BD) - 30 CONTINUE -C WRITE (*,*) 'The value of X J', J, 'is', XM(J,D) - distance = SQRT(CD) + 1.0 / (1.0 + EXP(TW(1) * (TD - TW(2)))) - RETURN - END - diff --git a/src/tracepath.f b/src/tracepath.f deleted file mode 100644 index 6431f0b..0000000 --- a/src/tracepath.f +++ /dev/null @@ -1,77 +0,0 @@ -CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -C C -C (c) Victor Maus C -C Institute for Geoinformatics (IFGI) C -C University of Muenster (WWU), Germany C -C C -C Earth System Science Center (CCST) C -C National Institute for Space Research (INPE), Brazil C -C C -C C -C Efficient computation of DTW trace back - 2015-10-17 C -C C -CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -C -C DM - Direction matrix -C SM - Matrix of step patterns -C JMIN - Positions o the minimum points -C IND1 - Alignment indices in the pattern -C IND2 - Alignment indices in the template -C POS - Starting points in IND1 and IND2 -C N - Number of rows in DM -C M - Number of columns DM -C NS - Number of rows in SM -C NJ - Number of minimum points -C AL - Length of IND1 and IND2 - SUBROUTINE tracepath(DM,SM,JMIN,IND1,IND2,POS,N,M,NS,NJ,AL) -C 800 FORMAT(I4,I4,I4,I4,I4,I4,I4,I4) -C I/O Variables - INTEGER N, M, NS, NJ, AL - INTEGER IND1(AL),IND2(AL),POS(NJ+1),SM(NS,4),DM(N,M),JMIN(NJ) -C Internals - INTEGER K, PK, I, J, P, PI, PJ, S, IS(NS), STEPS(NS,4*NS) - INTEGER ZERO, ONE - PARAMETER(ZERO=0,ONE=1) -C Initialize steps - DO 10 PK = 1, SM(NS,1) - STEPS(PK,1) = ZERO - IS(PK) = 2 - 10 CONTINUE -C Get steps direction - DO 11 K = 1, NS - PK = SM(K,1) - PI = SM(K,2) - PJ = SM(K,3) - IF (PI.EQ.ZERO.AND.PJ.EQ.ZERO) THEN - GO TO 11 - ENDIF - STEPS(PK,1) = STEPS(PK,1) + ONE - STEPS(PK,IS(PK)) = PI - STEPS(PK,IS(PK)+1) = PJ - IS(PK) = IS(PK) + 2 - 11 CONTINUE -C Trace back - P = ONE - POS(1) = ZERO - DO 30 JM = 1, NJ - I = N - J = JMIN(JM) - S = DM(I,J) - 20 IF (I.NE.ONE.AND.P.LT.AL) THEN - IND1(P) = I - IND2(P) = J - NS = STEPS(S,1) - DO 12 K = 1, NS - P = P + 1 - IND1(P) = I - STEPS(S,2*K) - IND2(P) = J - STEPS(S,2*K+1) - I = IND1(P) - J = IND2(P) - 12 CONTINUE - S = DM(I,J) - GO TO 20 - ENDIF - POS(JM+1) = P - P = P + 1 - 30 CONTINUE - END diff --git a/src/twdtw.f b/src/twdtw.f deleted file mode 100644 index df96fe8..0000000 --- a/src/twdtw.f +++ /dev/null @@ -1,157 +0,0 @@ -C Computation of TWDTW cost matrix -C -C XM - matrix with the time series (N,D) -C YM - matrix with the temporal profile (M,D) -C CM - Output cumulative cost matrix -C DM - Direction matrix -C VM - Starting points matrix -C SM - Matrix of step patterns -C N - Number of rows in CM, DM, and VM - time series -C M - Number of columns CM, DM, and VM - temporal profile -C D - Number of spectral dimensions including time in XM and YM -C NS - Number of rows in SM -C TW - Time-Weight parameters alpha and beta -C LB - Constrain TWDTW calculation to band given by TW(2) - SUBROUTINE twdtw(XM, YM, CM, DM, VM, SM, N, M, D, NS, TW, LB, JB) -C I/O Variables - INTEGER N, M, D, NS, SM(NS,4), DM(N+1,M), VM(N+1,M), JB(N) - DOUBLE PRECISION XM(M,D), YM(N,D), CM(N+1,M), TW(2) - LOGICAL LB -C Internals - DOUBLE PRECISION W, CP(NS), VMIN, A, B, TD - INTEGER I, J, IL(NS), JL(NS), K, PK, KMIN, ZERO, ONE, JM - PARAMETER(ZERO=0,ONE=1) - DOUBLE PRECISION NAN, INF - NAN = 0.0 - NAN = NAN / NAN - INF = HUGE(0.0) - IML = 1 - VM(1,1) = 1 - -C Initialize the firt row and col of the matrices - DO 21 I = 2, N+1 - TD = YM(I-1,1) - XM(1,1) - CALL ellapsed(TD) -C IF (TD.GT.TW(2)) THEN -C CM(I,1) = INF -C ELSE - CM(I,1) = CM(I-1,1) + - & distance(YM, XM, N, M, D, I-1, 1, TW, TD) -C ENDIF -C WRITE (*,*) 'The distance ',I,',1 is ', CM(I,1) - DM(I,1) = 3 - VM(I,1) = 1 - 21 CONTINUE - DO 31 J = 2, M - TD = YM(2,1) - XM(J,1) - CALL ellapsed(TD) -C IF (TD.GT.TW(2)) THEN -C CM(2,J) = INF -C ELSE - CM(2,J) = CM(2,J-1) + - & distance(YM, XM, N, M, D, 1, J, TW, TD) -C ENDIF -C WRITE (*,*) 'The distance 2,',J,' is ', CM(2,J) - DM(1,J) = 2 - VM(1,J) = J - 31 CONTINUE -C Compute cumulative cost matrix - J = 2 - DO 32 WHILE ( J .LE. M ) - I = 2 - DO 22 WHILE ( I .LE. N+1 ) -C PRINT *, "J: ", J, "I: ", I -C Calculate local distance -C # the call takes I-1 because local matrix has an additional row at the begning - TD = YM(I-1,1) - XM(J,1) - CALL ellapsed(TD) - IF (LB.AND.(TD.GT.TW(2))) THEN -C print *, "I: ", I, "TD: ", TD, " -- TW: ", TW(2) - CM(I,J) = INF - DM(I,J) = -ONE - VM(I,J) = ZERO - GOTO 44 - ELSE - CM(I,J) = distance(YM, XM, N, M, D, I-1, J, TW, TD) - ENDIF -C Initialize list of step cost - DO 10 K = 1, NS - CP(K) = NAN - 10 CONTINUE - DO 11 K = 1, NS - PK = SM(K,1) - IL(K) = I - SM(K,2) - JL(K) = J - SM(K,3) - IF ((IL(K).GT.ZERO).AND.(JL(K).GT.ZERO)) THEN - W = SM(K,4) - IF (W.EQ.-ONE) THEN - CP(PK) = CM(IL(K),JL(K)) - ELSE - CP(PK) = CP(PK) + CM(IL(K),JL(K))*W - ENDIF - ENDIF - 11 CONTINUE - KMIN = -ONE - VMIN = INF - ILMIN = -ONE - JLMIN = -ONE - DO 12 K = 1, NS - PK = SM(K,1) - IF (CP(PK).EQ.CP(PK).AND.CP(PK).LT.VMIN) THEN - KMIN = PK - VMIN = CP(PK) - ILMIN = IL(K) - JLMIN = JL(K) - ENDIF - 12 CONTINUE - IF (KMIN.GT.-ONE) THEN - CM(I,J) = VMIN - DM(I,J) = KMIN - VM(I,J) = VM(ILMIN, JLMIN) - ENDIF - 44 CONTINUE - I = I + 1 - 22 CONTINUE - J = J + 1 - 32 CONTINUE - 99 CONTINUE - J = 1 - K = ZERO -C PRINT *, "DONE: LOOP 1" - DO 69 WHILE ( J .LE. M ) - IF (VM(N+1,J).NE.ZERO) THEN - IF (K.EQ.ZERO) THEN - K = 1 - JB(K) = J - JM = VM(N+1,J) - GOTO 68 - ENDIF - IF (VM(N+1,J).NE.JM) THEN - K = K + 1 - JB(K) = J - JM = VM(N+1,J) - GOTO 68 - ENDIF -C PRINT *, J, "JB:",JB(k),"-", CM(N+1,J),"-",CM(N+1,JB(K)) - IF (CM(N+1,J).LT.CM(N+1,JB(K))) THEN - JB(K) = J - GOTO 68 - ENDIF - ENDIF - 68 CONTINUE - J = J + 1 - 69 CONTINUE -C PRINT *, "XM", XM -C PRINT *, "YM", YM -C PRINT *, "CM", CM -C PRINT *, "DM", DM -C PRINT *, "VM", VM -C PRINT *, "SM", SM -C PRINT *, "N", N -C PRINT *, "M", M -C PRINT *, "D", D -C PRINT *, "NS", NS -C PRINT *, "TW", TW -C PRINT *, "LB", LB -C PRINT *, "JB", JB - END diff --git a/tic.R b/tic.R deleted file mode 100644 index ec2f06f..0000000 --- a/tic.R +++ /dev/null @@ -1 +0,0 @@ -add_package_checks() diff --git a/vignettes/twdtw01.Rmd b/vignettes/twdtw01.Rmd deleted file mode 100644 index 23af762..0000000 --- a/vignettes/twdtw01.Rmd +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: "1. TWDTW: Time-Weighted Dynamic Time Warping" -author: "Victor Maus" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{1. TWDTW: Time-Weighted Dynamic Time Warping} - %\VignetteEncoding{UTF-8} - %\VignetteEngine{knitr::rmarkdown} -bibliography: ./../inst/REFERENCES.bib ---- - -```{r, echo=FALSE, include=FALSE} -knitr::opts_chunk$set(collapse = TRUE) -knitr::opts_chunk$set(fig.height = 4.5) -knitr::opts_chunk$set(fig.width = 6) -``` - -This vignette present a short introduction on Time-Weighted Dynamic Time Warping (TWDTW) analysis using `dtwSat`. TWDTW is an algorithm for land cover mapping using multi-band satellite image time series. The algorithm is particularly valuable to produce land cover maps in regions with scarcity of training data. For details see @Maus:2016 and @Maus:2019. - -# Satellite images time series - -Continuous Earth observation measurements produce sequences of multi-temporal images--satellite images time series. TWDTW algorithm can extract information from satellite images time series, in particular about vegetation with annual phenological cycle. - -An example of phenological cycles is available in `dtwSat` as `MOD13Q1.MT.yearly.patterns`, which includes temporal profiles of vegetation in the Brazilian Amazon extracted from `MOD13Q1` time series. You can load and visualize these profiles in your R session using -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -library(dtwSat) - -veg_profiles <- twdtwTimeSeries(MOD13Q1.MT.yearly.patterns) - -veg_profiles - -class(veg_profiles) - -plot(veg_profiles, type = "patterns") -``` - -We can refer to the above profiles as the library of known vegetation phenological cycles in the study area. For this area study area `dtwSat` also provides some examples of time series, which you can load by running -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -veg_ts <- twdtwTimeSeries(MOD13Q1.ts) - -veg_ts - -class(veg_ts) - -plot(veg_ts, type = "timeseries") -``` - -# TWDTW analysis - -Comparing the above time series to the profiles library, which is the sequence of vegetation types in the above time series? To answered this question we can run a TWDTW analysis and compare the above time series to the profiles library, such that -```{r echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -# Define logistic time-weight, see Maus et al. (2016) -weight_fun <- logisticWeight(alpha = -0.1, beta = 50) - -# Run TWDTW analysis -twdtw_matches <- twdtwApply(x = veg_ts, - y = veg_profiles, - weight.fun = weight_fun, - keep = TRUE, legacy=TRUE) - -class(twdtw_matches) - -twdtw_matches -``` - -TWDTW analysis has found `r length(twdtw_matches)` alignments, i.e. `r length(twdtw_matches)` alignments between the profiles in the library and shorter segments of the time series. Each of these matches have an associated dissimilarity metric--the TWDTW distance. Using the code below we can visualize all matches with a TWDTW distance lower than `10.0`. -```{r, echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -plot(x = twdtw_matches, - type = "alignments", - threshold = 10.0) -``` - -Every segment in the figure shows one possible match between the profiles and the time series. The segments with lower TWDTW distance are more likely to be the correct classification for that specific segment. - -To further investigate the segments by looking at the matching points (observation) between a single pattern and the time series. In the code below we visualize the matching observations for the two best (lowest TWDTW distance) alignments of the `Soybean-cotton`. -```{r, echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -plot(x = twdtw_matches, - type = "matches", - attr = "evi", - patterns.labels = "Soybean-cotton", - k = 2) -``` - -We can also investigate the paths of minimum cost in the TWDTW cost matrix for each profile, for example for `Soybean-cotton` run -```{r, echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -plot(x = twdtw_matches, - type = "paths", - patterns.labels = "Soybean-cotton") -``` - -Finally we define sub-intervals of 12 months and classify each segment of the time series into one class in our profiles library, such that -```{r, echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -twdtw_classification <- twdtwClassify(x = twdtw_matches, - from = "2009-09-01", - to = "2014-08-31", - by = "12 month") - -twdtw_classification - -plot(twdtw_classification, type = "classification") -``` - -In this last chunk of code we answered our question. We can see that only the `r length(twdtw_classification)` best alignments over all land cover classes remained, i.e. the alignments with the lowest TWDTW distance per segment. - -This short introduction showed how to use `dtwSat` to analyse and classify a single time series. This is useful to better understand the method and adjust classification parameters. To learn how apply the method to a raster stack please red the next vignette. - -# References - - diff --git a/vignettes/twdtw02-lucc.Rmd b/vignettes/twdtw02-lucc.Rmd deleted file mode 100644 index c39fdd5..0000000 --- a/vignettes/twdtw02-lucc.Rmd +++ /dev/null @@ -1,180 +0,0 @@ ---- -title: "2. Land-cover change analysis with TWDTW" -author: "Victor Maus" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{1. Land-cover change analysis with TWDTW} - %\VignetteEncoding{UTF-8} - %\VignetteEngine{knitr::rmarkdown} -bibliography: ./../inst/REFERENCES.bib ---- - -```{r, echo=FALSE, include=FALSE} -knitr::opts_chunk$set(collapse = TRUE) -knitr::opts_chunk$set(fig.height = 4.5) -knitr::opts_chunk$set(fig.width = 6) -``` - -This vignette provides a short guide on how to perform a Time-Weighted Dynamic Time Warping (TWDTW) analysis on raster image time series using `dtwSat`. For more details about TWDTW read @Maus:2016 and @Maus:2019. - -# Create multi-band image time series - -`dtwSat` provides a set of images extracted from `MOD13Q1` dataset for a region within the Brazilian Amazon. You can load these images with -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -library(dtwSat) - -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")) -``` - -The `tif` files above have been pre-processed, so that a single file has the complete time series for each band. One can also built the time series for each band from independent files using the function `stack` from the R package `raster`. - -Note that every band must have the same extend, resolution, and number of images, i.e. the same number of observations across space and time. To create the multi-band image time series we need the dates of each observation, which for the set of images above are -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -timeline <- scan(system.file("lucc_MT/data/timeline", package = "dtwSat"), what="date") -timeline -``` - -Finally, we can create the multi-band image time series with -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -rts <- twdtwRaster(evi, ndvi, red, blue, nir, mir, timeline = timeline, doy = doy) -rts -``` - -The multi-band image time series has `r length(rts)` bands and `r length(index(rts))` observations ranging from `r index(rts)[1]` to `r tail(index(rts), 1)`. - -# Create a library of vegetation profiles - -To crate a library of profiles we need a set of samples. `dtwSat` provides a set of samples of land cover classes for the study area. We can load the samples with -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -field_samples <- read.csv(system.file("lucc_MT/data/samples.csv", package = "dtwSat")) -head(field_samples) -``` - -We split this samples into a training and a validation set, such that -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -library(caret) - -set.seed(1) # set for reproducibility - -I <- unlist(createDataPartition(field_samples$label, p = 0.1)) - -training_samples <- field_samples[I,] - -validation_samples <- field_samples[-I,] -``` - -To get the time series for each sample in the training set, we can run -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -training_ts <- getTimeSeries(rts, - y = training_samples, - proj4string = "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0") -``` - -Finally, we can use the training samples to crate the profiles library with -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -profiles_library <- createPatterns(training_ts, - freq = 8, - formula = y ~ s(x)) - -plot(profiles_library, type = "patterns") -``` - -The function `createPatterns` using generalized additive models (GAMs) to create the profiles. For details see `?gam` from `mgcv` package. - - - -# Classify image time series - -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -system.time( - twdtw_lucc <- twdtwApply(x = rts, - y = profiles_library, - alpha = -0.1, - beta = 50, - progress = 'text', - minrows = 30, - legacy = FALSE, - time.window = TRUE) -) -``` - -Note the argument `legacy = FALSE`. Setting this argument to `FALSE` considerably improves the performance of the processing as it does not keep any intermediate dataset. Using `time.window = TRUE` implements a change in the TWDTW algorithm to reduce processing. - -One can also run TWDTW in parallel. For a small area, the performance is not much better than the sequential processing. However, for larger areas, the parallel processing can reduce processing time. To run `twdtwApply` in parallel setup and register a cluster before calling the function, such that -```{r, echo = TRUE, eval = FALSE, warning = FALSE, message = FALSE} -library(doParallel) -library(parallel) -library(foreach) - -cl <- makeCluster(detectCores(), type = "FORK") -registerDoParallel(cl) - -system.time( - twdtw_lucc <- twdtwApply(x = rts, - y = profiles_library, - alpha = -0.1, - beta = 50, - progress = 'text', - minrows = 30, - legacy = FALSE, - time.window = TRUE) -) - -registerDoSEQ() -stopCluster(cl) -``` - -# Assess classifiaction results - -`dtwSat` provides a set of functions to asses the classification results. For example with -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -# Plot TWDTW distances for the first year - plot(twdtw_lucc, type = "distance", time.levels = 1) - -# Plot TWDTW classification results - plot(twdtw_lucc, type = "map") - -# Plot mapped area time series - plot(twdtw_lucc, type = "area") - -# Plot land-cover changes - plot(twdtw_lucc, type = "changes") -``` - -The package also offers a set of methods to assess the classification accuracy and visualize the results. -```{r , echo = TRUE, eval = TRUE, warning = FALSE, message = FALSE} -# Assess classification - twdtw_assess <- - twdtwAssess(twdtw_lucc, - y = validation_samples, - proj4string = "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0", - conf.int = .95) - -# Plot map accuracy - plot(twdtw_assess, type = "accuracy") - -# Plot area uncertainty - plot(twdtw_assess, type = "area") - -# Plot misclassified samples - plot(twdtw_assess, type = "map", samples = "incorrect") - -# Get latex table with error matrix - twdtwXtable(twdtw_assess, table.type = "matrix") - -# Get latex table with error accuracy - twdtwXtable(twdtw_assess, table.type = "accuracy") - -# Get latex table with area uncertainty - twdtwXtable(twdtw_assess, table.type = "area") -``` - -This short introduction showed how to use `dtwSat` for land-cover change analyse. To learn TWDTW read @Maus:2016 and @Maus:2019. - -# References diff --git a/vignettes/twdtw03-speed.Rmd b/vignettes/twdtw03-speed.Rmd deleted file mode 100644 index 13c7435..0000000 --- a/vignettes/twdtw03-speed.Rmd +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: "2. TWDTW processing time" -author: "Victor Maus" -output: -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{1. TWDTW processing time} - %\VignetteEncoding{UTF-8} - %\VignetteEngine{knitr::rmarkdown} -bibliography: ./../inst/REFERENCES.bib -editor_options: - chunk_output_type: console ---- - -```{r, echo=FALSE, include=FALSE} -knitr::opts_chunk$set(collapse = TRUE) -knitr::opts_chunk$set(fig.height = 4.5) -knitr::opts_chunk$set(fig.width = 6) -``` -This vignette tests the performance of TWDTW. For details about method read @Maus:2016 and @Maus:2019. - -# Data - -This vignette uses data from the R package `sitsdata`, which can be installed from Github run -```{r, eval=FALSE} -remotes::install_github(repo = 'e-sensing/sitsdata', ref = '16c8fa7') -``` -The keep this vignette reproducible, I set the argument `ref` to a commit on the online Github repository. - -```{r, eval=FALSE} -library(dtwSat) -library(sitsdata) -library(dplyr) -data(samples_cerrado_mod13q1) -samples_cerrado_mod13q1 |> - group_by(label) |> - summarise(n_samples = n()) -``` - -# Performance - -## Performance on implementations - single time series - - -```{r} -# TODO: -# - twdtwCLassify call for twdtwTimeSeries class and list of data.frame/data.table -# - the same as above with the legacy option -rbenchmark::benchmark( - legacy = twdtwClassify(twdtwApply(x = tw_ts, y = tw_patt, weight.fun = log_fun), from = from, to = to, by = by)[[1]], - fast = twdtwReduceTime(x = mn_ts, y = mn_patt, from = from, to = to, by = by) -) -``` - -## Performance on a real world dataset - -## Performance on a real world with dense time sereis - -In this experiment I increase the number of observation observations in the time series of the example above. - - - - -