diff --git a/DESCRIPTION b/DESCRIPTION index fc6e3e62f..36ed0d3c8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: wallace -Version: 2024.08.02 -Date: 2024-08-02 +Version: 2024.09.18 +Date: 2024-09-18 Title: A Modular Platform for Reproducible Modeling of Species Niches and Distributions Description: The 'shiny' application Wallace is a modular platform for diff --git a/R/indic_aoo.R b/R/indic_aoo.R index bf14079a5..33dc147ce 100644 --- a/R/indic_aoo.R +++ b/R/indic_aoo.R @@ -1,6 +1,33 @@ -##' @title indic_aoo +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# indic_aoo.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# +#' @title indic_aoo #' @description Calculate AOO. #' +#' @details +#' The function calculates the area of occupancy (AOO) from a thresholded +#' prediction raster or a data.frame of occurrence records. +#' #' @param r raster. Thresholded prediction raster. It could be NULL if occs provided. #' @param occs data.frame. Table with occurrences. It could be NULL if raster #' provided. If occs provided raster is ignored. @@ -13,24 +40,57 @@ #' @param logger stores all notification messages to be displayed in the Log #' Window of Wallace GUI. Insert the logger reactive list here for running in #' shiny, otherwise leave the default NULL +#' +#' @examples +#' \dontrun{ +#' ### Set parameters +#' # binary raster +#' r <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif", +#' package = "wallace")) +#' # occurrences +#' +#' ### Run function +#' # aoo from raster +#' aoo_r <- indic_aoo(r, +#' occs = NULL, +#' lon = NULL, +#' lat = NULL, +#' wktFrom = getWKT("wgs84"), +#' wktTo = getWKT("wcea"), +#' logger = NULL) +#' # aoo from occs +#' aoo_occs <- indic_aoo(r <- NULL, +#' occs, +#' lon = "longitude", +#' lat = "latitude", +#' wktFrom = getWKT("wgs84"), +#' wktTo = getWKT("wcea"), +#' logger = NULL) +#' } +#' +#' @return A list of two elements: area and AOOraster. The first is the numeric +#' value of the area (in km^2). The second is a RasterLayer of the extent +#' (in WCEA & 2x2 km resolution). +#' #' @author Gonzalo E. Pinilla-Buitrago +#' @author Bethany A. Johnson #' @export #' indic_aoo <- function(r = NULL, occs = NULL, lon = NULL, lat = NULL, - wktFrom, wktTo, logger) { + wktFrom, wktTo, logger = NULL) { if (!is.null(occs)) { if (is.null(lon) | is.null(lat)) { - logger %>% writeLog("No longitude and/or latitude name provided (**).") + logger %>% writeLog(type = 'error', "No longitude and/or latitude name provided.") return() } else { p.pts <- occs if (sum(c(lon, lat) %in% names(p.pts)) != 2) { - logger %>% writeLog("Longitude and/or latitude names not found (**).") + logger %>% writeLog(type = 'error', "Longitude and/or latitude names not found.") return() } else { p.pts <- p.pts %>% - dplyr::select(c(lon, lat)) %>% + dplyr::select(all_of(c(lon, lat))) %>% #BAJ terra::vect(geom = c(lon, lat)) terra::crs(p.pts) <- wktFrom rast_temp <- terra::rast(terra::ext(terra::project(p.pts, wktTo)) + 10000, @@ -44,7 +104,9 @@ indic_aoo <- function(r = NULL, occs = NULL, lon = NULL, lat = NULL, } } } else if (!is.null(r)) { + if ("RasterLayer" %in% class(r)) { r <- terra::rast(r) + } ## Unsuitable for NAs r[r == 0] <- NA p.poly <- terra::as.polygons(r) @@ -56,8 +118,8 @@ indic_aoo <- function(r = NULL, occs = NULL, lon = NULL, lat = NULL, terra::trim() AOOarea <- terra::freq(AOOraster, value = 1)$count * 4 } else { - logger %>% writeLog("Provide occurrences or raster (**).") + logger %>% writeLog(type = 'error', "Provide occurrences or raster.") return() } - return(list(area = AOOarea, AOOraster = methods::as(AOOraster, "Raster"))) + return(list(area = AOOarea, AOOraster = raster::raster(AOOraster))) } diff --git a/R/indic_area.R b/R/indic_area.R index 17c2079af..979edd189 100644 --- a/R/indic_area.R +++ b/R/indic_area.R @@ -1,5 +1,29 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# indic_area.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title indic_area #' @description Calculate Range size in square kilometers. +#' @details Calculate the geographic range size of a thresholded raster. The units are in square kilometers. #' #' @param r raster. Thresholded prediction raster. It could be NULL if occs provided. #' @param wkt character. Well-known text representation of coordinate reference systems @@ -7,12 +31,23 @@ #' @param logger stores all notification messages to be displayed in the Log #' Window of Wallace GUI. insert the logger reactive list here for running in #' shiny, otherwise leave the default NULL +#' +#' @examples +#' \dontrun{ +#' r <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif",package = "wallace")) +#' wkt <- getWKT("wcea") +#' areaRange <- indic_area(r, wkt, logger = NULL) +#' } +#' @return Numeric value #' @author Gonzalo E. Pinilla-Buitrago +#' @author Bethany A. Johnson #' @export #' indic_area <- function(r, wkt, logger = NULL) { + if ("RasterLayer" %in% class(r)) { r <- terra::rast(r) + } ## Unsuitable for NAs r[r == 0] <- NA ## Raster to polygon diff --git a/R/indic_eoo.R b/R/indic_eoo.R index 5e49af078..01f4869bb 100644 --- a/R/indic_eoo.R +++ b/R/indic_eoo.R @@ -1,5 +1,29 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# indic_eoo.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title indic_eoo #' @description Calculate EOO. +#' @details Calculate extent of occurrence (EOO) based on a binary raster or occurrence points. #' #' @param r raster. Thresholded prediction raster. It could be NULL if occs provided. #' @param occs data.frame. Table with occurrences. It could be NULL if raster @@ -11,34 +35,55 @@ #' @param logger stores all notification messages to be displayed in the Log #' Window of Wallace GUI. Insert the logger reactive list here for running in #' shiny, otherwise leave the default NULL +#' +#' @examples +#' \dontrun{ +#' # binary raster +#' r <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif",package = "wallace")) +#' # occurrences +#' occs <- read.csv(system.file("extdata/Bassaricyon_neblina.csv",package = "wallace")) +#' # wcea +#' wkt <- getWKT("wcea") +#' +#' eoo_r <- indic_eoo(r, occs = NULL, lon = NULL, lat = NULL, wkt, logger = NULL) +#' eoo_o <- indic_eoo(r = NULL, occs, lon = "longitude", lat = "latitude", wkt, logger = NULL) +#' } +#' +#' @return A list of two elements: area and eooPoly. area is a numeric value and eooPoly is a SpatialPolygon. #' @author Andrea Paz #' @author Gonzalo E. Pinilla-Buitrago +#' @author Bethany A. Johnson #' @export #' indic_eoo <- function(r = NULL, occs = NULL, lon = NULL, lat = NULL, - wkt, logger) { + wkt, logger=NULL) { if (!is.null(occs)) { if (is.null(lon) | is.null(lat)) { - logger %>% writeLog("No longitude and/or latitude name provided (**).") + logger %>% writeLog(type = 'error', + "No longitude and/or latitude name provided.") return() } else { p.pts <- occs if (sum(c(lon, lat) %in% names(p.pts)) != 2) { - logger %>% writeLog("Longitude and/or latitude names not found (**).") + logger %>% writeLog(type = 'error', + "Longitude and/or latitude names not found.") return() } else { - p.pts <- p.pts %>% dplyr::select(c(lon, lat)) + p.pts <- p.pts %>% dplyr::select(all_of(c(lon, lat))) } } } else if (!is.null(r)) { + if ("RasterLayer" %in% class(r)) { r <- terra::rast(r) + } r[r == 0] <- NA p.pts <- terra::as.points(r) %>% terra::geom() %>% data.frame() %>% dplyr::select(tidyselect::all_of(c("x", "y"))) } else { - logger %>% writeLog("Provide occurrences or raster (**).") + logger %>% writeLog(type = 'error', + "Provide occurrences or raster.") return() } wgs84 <- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" diff --git a/R/indic_inputPoly.R b/R/indic_inputPoly.R index bff7bd2fc..9d0f2a5f0 100644 --- a/R/indic_inputPoly.R +++ b/R/indic_inputPoly.R @@ -1,29 +1,74 @@ -#' @title indic_inputPoly -#' @description x +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# indic_inputPoly.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# +#' @title indic_inputPoly user-provided shapefile for ratio overlap calculations +#' @description This function allows the user to upload a shapefile to be used in ratio overlap calculations #' -#' @details x -#' @param bgShp_path Path to the user provided shapefile -#' @param bgShp_name Name of the user provided shapefile -#' @param overlapArea x. An sf object. +#' @details +#' This function is used in the Calculate Indicators component. Here, the user +#' provides the path and name of a shapefile to be used with the source polygon +#' to calculate the ratio of overlap between the polygons. The source polygon +#' is a polygonized raster of a range map from: a Wallace SDM (prediction, +#' transfer, or masked), EOO, or AOO. The user shapefile and source polygon must +#' intercept. The function returns an sf object to be used in the indic_overlap() +#' function. +#' +#' @param ovShp_path Path to the user provided shapefile +#' @param ovShp_name Name of the user provided shapefile +#' @param overlapRange sf object. The source polygon for ratio overlap calculations #' @param logger stores all notification messages to be displayed in the Log Window of Wallace GUI. insert the logger reactive list here for running in shiny, #' otherwise leave the default NULL -#' @param spN x -# @keywords - -# @keywords +#' @param spN character. Used to obtain species name for logger messages +#' @examples +#' \dontrun{ +#' # Overlap polygon +#' ovShp_path <- list.files(path = system.file("extdata/wdpa", package = "wallace"), full.names = TRUE) +#' ovShp_name <- list.files(path = system.file("extdata/wdpa", package = "wallace"), full.names = FALSE) +#' +#' # Source polygon +#' overlapRange <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif", package = "wallace")) +#' overlapRange[overlapRange == 0] <- NA +#' overlapRange <- terra::as.polygons(overlapRange) +#' overlapRange <- sf::st_as_sf(overlapRange) +#' +#' # Run function +#' polyData <- indic_inputPoly(ovShp_path, ovShp_name, overlapRange, logger = NULL, spN = NULL) +#' } #' -#' @return x -#' @author Gonzalo E. Pinilla-Buitrago < gpinillabuitrago@@gradcenter.cuny.edu> +#' @return An sf object to be used for calculating ratio overlap +#' @author Gonzalo E. Pinilla-Buitrago +#' @author Bethany A. Johnson # @note +#' @seealso \code{\link{indic_overlap}} #' @export -indic_inputPoly <- function(bgShp_path, bgShp_name, overlapArea, +indic_inputPoly <- function(ovShp_path, ovShp_name, overlapRange, logger = NULL, spN = NULL) { - pathdir <- dirname(bgShp_path) - pathfile <- basename(bgShp_path) + pathdir <- dirname(ovShp_path) + pathfile <- basename(ovShp_path) # get extensions of all input files - exts <- sapply(strsplit(bgShp_name, '\\.'), FUN = function(x) x[2]) + exts <- sapply(strsplit(ovShp_name, '\\.'), FUN = function(x) x[2]) if ('shp' %in% exts) { if (length(exts) < 3) { logger %>% @@ -34,24 +79,23 @@ indic_inputPoly <- function(bgShp_path, bgShp_name, overlapArea, } # get index of .shp i <- which(exts == 'shp') - if (!file.exists(file.path(pathdir, bgShp_name)[i])) { - file.rename(bgShp_path, file.path(pathdir, bgShp_name)) + if (!file.exists(file.path(pathdir, ovShp_name)[i])) { + file.rename(ovShp_path, file.path(pathdir, ovShp_name)) } smartProgress(logger, message = "Uploading shapefile ...", { - polyData <- sf::read_sf(file.path(pathdir, bgShp_name)[i]) + polyData <- sf::read_sf(file.path(pathdir, ovShp_name)[i]) polyData <- replace(polyData, is.na(polyData), values = "NA") }) } else { logger %>% writeLog(type = 'error', hlSpp(spN), - 'Please enter shapefile (.shp, .shx, .dbf).') + paste0("Please enter shapefile (.shp, .shx, .dbf).")) return() } if (is.na(sf::st_crs(polyData))) { logger %>% writeLog( type = 'warning', hlSpp(spN), - "Projection not found for shapefile. It is assume that shapefile datum ", - "is WGS84 (**)" + "Projection not found for shapefile. It is assumed that shapefile datum is WGS84." ) sf::st_crs(polyData) <- 4326 } @@ -60,23 +104,26 @@ indic_inputPoly <- function(bgShp_path, bgShp_name, overlapArea, logger %>% writeLog( type = 'warning', hlSpp(spN), "Original coordinate reference system (CRS) is not WGS84 (EPSG:4326). ", - "Shapefile was reprojected to this CRS. (**)" + "Shapefile was reprojected to this CRS." ) } sf::sf_use_s2(FALSE) - if (sum(lengths(sf::st_intersects(polyData, overlapArea))) == 0) { + if (sum(lengths(sf::st_intersects(polyData, overlapRange))) == 0) { logger %>% writeLog( type = 'error', hlSpp(spN), - "Shapefile does not intersect the area to overlap. Please specify a new polygon. (**)" + "Shapefile does not intersect the area to overlap. Please specify a new polygon." ) return() } - smartProgress(logger, message = "Intersecting spatial data ...", { - nmOverlap <- names(overlapArea) - nmOverlap <- nmOverlap[!(nmOverlap %in% "geometry")] - spatialPoly <- sf::st_intersection(polyData, overlapArea) %>% - dplyr::select(-nmOverlap) - }) + # BAJ 9/6/2024 removed the following + # I dont think this needs to be here, it's already in indic_overlap + # smartProgress(logger, message = "Intersecting spatial data ...", { + # nmOverlap <- names(overlapArea) + # nmOverlap <- nmOverlap[!(nmOverlap %in% "geometry")] + # spatialPoly <- sf::st_intersection(polyData, overlapArea) %>% + # dplyr::select(all_of(nmOverlap)) + # }) + # if it is added back in, change line 128 return(polyData) to return(spatialPoly) logger %>% writeLog(hlSpp(spN), "Spatial data uploaded.") - return(spatialPoly) + return(polyData) } diff --git a/R/indic_overlap.R b/R/indic_overlap.R index c172c0214..18065bd71 100644 --- a/R/indic_overlap.R +++ b/R/indic_overlap.R @@ -1,15 +1,66 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# indic_overlap.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title indic_overlap -#' @description Overlap range map with shapefile or raster -#' @param rangeMap sf polygon. A polygon with the range map. -#' @param inputOverlap sf polygon or raster. A feature to apply overlap. +#' @description Overlap a binary range map with shapefile or raster +#' @details This function calculates the overlap between a range map and a +#' supplied shape or continuous raster. If the inputOverlap is a continuous raster, the +#' function returns a polygon of the overlap and the proportion of range: +#' below 25%, 25-50%, 50-75%, and 75-100%. If the inputOverlap is a polygon, the +#' function returns a polygon of the overlap and the percentage of the range +#' contained within the shape. +#' @param rangeMap sf object representing a binary range map. +#' @param inputOverlap sf polygon or continuous raster. A feature to apply overlap. #' @param field character. Name of the field to select categories/attributes. -#' NULL is inputOverlap is a raster. +#' NULL if inputOverlap is a raster. #' @param category character. String with names of the categories/attributes -#' selected to overlap with range map. NULL is inputOverlap is a raster. -#' @param logger logger +#' selected to overlap with range map. NULL if inputOverlap is a raster. +#' @param logger stores all notification messages to be displayed in the Log +#' Window of Wallace GUI. insert the logger reactive list here for running in +#' shiny, otherwise leave the default NULL #' @param spN species name +#' +#' @examples +#' \dontrun{ +#' ### Set parameters +#' # range map +#' rangeMap <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif", package = "wallace")) +#' rangeMap[rangeMap == 0] <- NA +#' rangeMap <- terra::as.polygons(rangeMap) +#' rangeMap <- sf::st_as_sf(rangeMap) +#' # input overlap raster +#' inputRaster <- raster::raster(nrows=108, ncols=108, xmn=-80, xmx=-75) +#' raster::values(inputRaster)<- runif(n = (108*108)) +#' +#' ### Run function +#' overlap_r <- indic_overlap(rangeMap, inputOverlap = inputRaster, field = NULL, category = NULL, logger = NULL, spN = NULL) +#' } +#' +#' @return A list of 2: a polygon of the overlap and the ratio overlap statistics. #' @author Andrea Paz #' @author Gonzalo E. Pinilla-Buitrago +#' @author Bethany A. Johnson +#' @seealso \code{\link{indic_raster}}, \code{\link{indic_inputPoly}}, \code{\link[changeRangeR]{ratioOverlap}} #' @export #' @@ -28,8 +79,8 @@ indic_overlap <- function(rangeMap, inputOverlap, field = NULL, message = "Calculating range overlap ", { sf::sf_use_s2(FALSE) ratioOverlap <- changeRangeR::ratioOverlap( - r = sf::as_Spatial(rangeMap), - shp = sf::as_Spatial(inputOverlap), + r = rangeMap, + shp = inputOverlap, field = field, category = category) simpRangeMap <- sf::st_union(rangeMap) diff --git a/R/indic_raster.R b/R/indic_raster.R index c72e9a003..c0f68432a 100644 --- a/R/indic_raster.R +++ b/R/indic_raster.R @@ -1,22 +1,72 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# indic_raster.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title indic_raster #' @description Upload user-specified SDM prediction -#' @param rasPath character of path to rasters, must be the full path including +#' @details This function uploads a user-specified raster to be used in the calculate ratio +#' overlap module. It checks to make sure the raster intersects the overlapping object(an sf object; +#' a range map, EOO, AOO, masked map, etc) for calculating ratio overlap +#' +#' @param rasPath character of path to raster, must be the full path including #' file name and extension. -#' @param rasName character vector of raster names to be assigned to loaded -#' rasters. +#' @param rasName character vector of raster name to be assigned to loaded +#' raster. #' @param overlapArea x. An sf object. #' @param logger stores all notification messages to be displayed in the #' Log Window of Wallace GUI. insert the logger reactive list here for #' running in shiny, otherwise leave the default NULL. #' @param spN Species name +#' +#' @examples +#' \dontrun{ +#' #raster +#' rasPath <- system.file("extdata/Bassaricyon_neblina.tif",package = "wallace") +#' rasName <- "Bassaricyon_neblina.tif" +#' #overlapArea +#' rangeMap <- raster::raster(nrows=108, ncols=108, xmn=-79, xmx=-73) +#' raster::values(rangeMap)<- runif(n = (108*108)) +#' ##convert to sf +#' rangeMap <- terra::rast(rangeMap) +#' rangeMap[rangeMap == 0] <- NA +#' rangeMap <- terra::as.polygons(rangeMap) +#' rangeMap <- sf::st_as_sf(rangeMap) +#' +#' # Run function +#' r <- indic_raster(rasPath, rasName, overlapArea = rangeMap, logger = NULL, spN = NULL) +#' } +#' +#' @return A rasterlayer +#' #' @author Gonzalo E. Pinilla-Buitrago #' @author Jamie Kass +#' @author Bethany A. Johnson +#' @seealso \code{\link{indic_overlap}} #' @export indic_raster <- function(rasPath, rasName, overlapArea, logger = NULL, spN = NULL) { rasterName <- fileNameNoExt(rasName) - smartProgress(logger, message = "Uploading user-specified raster (**)...", { + smartProgress(logger, message = "Uploading user-specified raster...", { r <- raster::raster(rasPath) r <- raster::trim(r) names(r) <- "overlapRaster" @@ -27,7 +77,7 @@ indic_raster <- function(rasPath, rasName, overlapArea, writeLog( type = "error", hlSpp(spN), "Wrong extent projection. '", rasterName, - "' cannot be uploaded. (**)") + "' cannot be uploaded.") return() } if (sum(lengths(sf::st_intersects(sf::st_as_sfc(sf::st_bbox(r)), @@ -35,10 +85,19 @@ indic_raster <- function(rasPath, rasName, overlapArea, logger %>% writeLog( type = 'error', hlSpp(spN), "Overlap raster does not match with range map extent. ", - "Please specify a raster. (**)" + "Please specify a new raster." ) return() } + # BAJ + # if (raster is binary) { + # logger %>% + # writeLog( + # type = "error", hlSpp(spN), + # "The raster needs to be continuous. '", rasterName, + # "' cannot be uploaded. Please upload a continuous raster. ") + # return() + # } }) logger %>% writeLog(hlSpp(spN), "User raster file loaded.") return(r) diff --git a/R/indic_time.R b/R/indic_time.R index 5c9dbc273..0af7843c5 100644 --- a/R/indic_time.R +++ b/R/indic_time.R @@ -1,18 +1,71 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# indic_time.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title indic_time #' @description Calculate change in range area through time -#' @param range sf polygon. A polygon with the range map. -#' @param envs rasterStack. Environmental variables. -#' @param thrh interger. Threshold of where envs layers +#' @details This function calls on the changeRangeR::envchange() to calculate +#' the change in range area over time. It calculates the area of polygon of a +#' binary range, a masked range, EOO, or AOO, over time based on environmental +#' variables uploaded by the user and a selected threshold. The bounds of the +#' threshold are selected: "upper" removes values above the threshold (e.g., +#' maximum human footprint), "lower" removes values below the threshold (e.g., +#' minimum forest cover), "neither" does not threshold at any point, & finally +#' "both" thresholds at both threshold values (if provided; e.g., minimum and +#' maximum temperature). +#' @param range sf polygon. A polygon with the range map. Extent must match envs. +#' @param envs rasterStack. Environmental variables. Extent must match range. +#' @param thrh integer. Threshold of where envs layers #' should be thresholded #' @param bound character. character string characterizing the way the threshold #' should happen. "upper" removes values above the threshold (e.g., maximum #' human footprint). "lower" removes values below the threshold (e.g., minimum #' forest cover). "neither" does not threshold at any point. "both" thresholds #' at both threshold values (if provided; e.g., minimum and maximum temperature). -#' @param logger logger +#' @param logger stores all notification messages to be displayed in the Log +#' Window of Wallace GUI. insert the logger reactive list here for running in +#' shiny, otherwise leave the default NULL #' @param spN species name +#' @examples +#' \dontrun{ +#' ### Set parameters +#' # rasterstack of envs +#' pathRast <- list.files(system.file("extdata/MODIS", package = "wallace"), pattern = ".tif$", full.names = TRUE) +#' envs <- raster::stack(pathRast) +#' # range map +#' range <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif",package = "wallace")) +#' # match projections +#' projected_range <- raster::projectRaster(range, envs, method = 'bilinear') +#' # threshold & bounds +#' thrh <- 20 +#' bound <- "lower" +#' ### Run function +#' envChangeArea <- indic_time(projected_range, envs, thrh, bound, logger = NULL, spN = NULL) +#' } +#' @return a matrix array of the area calculations through time #' @author Andrea Paz #' @author Gonzalo E. Pinilla-Buitrago +#' @author Bethany A. Johnson +#' @seealso \code{\link[changeRangeR]{envChange}} #' @export #' @@ -29,7 +82,7 @@ indic_time <- function(range, envs, thrh, bound, logger = NULL, spN = NULL) { }) logger %>% writeLog(hlSpp(spN), "Range area after masking for environmental variables ", - "through time calculation done. (**)") + "through time calculation done. ") return(rangeTime$Area) } diff --git a/R/mask_expPoly.R b/R/mask_expPoly.R index ca2e874d9..f22d7a9bf 100644 --- a/R/mask_expPoly.R +++ b/R/mask_expPoly.R @@ -1,13 +1,56 @@ - +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# mask_expPoly.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title mask_expPoly #' @description Remove or add polygon to prediction +#' @details Mask a range prediction by removing or adding a polygon. The polygon +#' must fall partly within the extent of the prediction. If the prediction is +#' continuous, only remove polygon will work. #' @param polyMask Polygon in shapefile -#' @param prediction Raster prediction -#' @param polyExt Polygon of background extent -#' @param rem Remove areas of polygon from prediction -#' @param logger logger +#' @param prediction Raster prediction, of which to add/remove polyMask. +#' @param polyExt Polygon of the prediction background extent +#' @param rem Remove areas of polygon from prediction or add them to prediction. (TRUE = remove, FALSE = add) +#' @param logger stores all notification messages to be displayed in the Log +#' Window of Wallace GUI. insert the logger reactive list here for running in +#' shiny, otherwise leave the default NULL #' @param spN species name +#' @examples +#' \dontrun{ +#' ### Set parameters +#' # range prediction +#' prediction <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif", package = "wallace")) +#' # bg extent +#' polyExt <- terra::ext(prediction) +#' polyExt <- terra::as.polygons(polyExt) +#' polyExt <-sf::st_as_sf(polyExt) +#' #poly for masking +#' polyMask <- sf::st_read(system.file("extdata/wdpa/WDPA_COL_olinguito.shp", package = "wallace")) +#' ### Run function +#' expertRast <- mask_expPoly(polyMask, prediction, polyExt, rem = TRUE, logger = NULL, spN = NULL) +#' } +#' @return A list of two elements: the masked prediction and the extent #' @author Gonzalo E. Pinilla-Buitrago +#' @author Bethany A. Johnson #' @export #' @@ -20,8 +63,8 @@ mask_expPoly <- function(polyMask, prediction, polyExt, rem = FALSE, if (sum(v) == length(v)) { logger %>% writeLog( type = 'error', hlSpp(spN), - paste("The polygon just included NA values.", - "Please, select a polygon that intersects model prediction.(**)") + paste("The polygon only included NA values.", + "Please select a polygon that intersects the model prediction. ") ) return() } @@ -29,9 +72,7 @@ mask_expPoly <- function(polyMask, prediction, polyExt, rem = FALSE, if (sum(v) > 0) { logger %>% writeLog( type = 'warning', hlSpp(spN), - paste("The polygon selected included some cells with NA values.", - "You cannot changes the predictions (suitable or unsuitable),", - "in these cells.(**)") + "The polygon selected includes some cells with NA values. You cannot change the prediction (suitable or unsuitable) in these cells. " ) } @@ -44,7 +85,7 @@ mask_expPoly <- function(polyMask, prediction, polyExt, rem = FALSE, newPred[newPred > 1] <- 1 extPoly <- polyExt logger %>% writeLog( - hlSpp(spN), "The polygon was added (**)") + hlSpp(spN), "The polygon was added. ") } else { rastValues <- raster::values(prediction) if (length(unique(rastValues)) == 3 | length(unique(rastValues)) == 2) { @@ -61,7 +102,7 @@ mask_expPoly <- function(polyMask, prediction, polyExt, rem = FALSE, }) } logger %>% writeLog( - hlSpp(spN), "The polygon was removed (**)") + hlSpp(spN), "The polygon was removed. ") } return(list(pred = newPred, ext = extPoly)) diff --git a/R/mask_spatialPoly.R b/R/mask_spatialPoly.R index d52b89e18..851d2e66f 100644 --- a/R/mask_spatialPoly.R +++ b/R/mask_spatialPoly.R @@ -1,23 +1,54 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# mask_spatialPoly.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title mask_spatialPoly -#' @description x +#' @description Upload user-provided shapefile for masking #' -#' @details -#' x +#' @details This function provides a spatialpolygon from a shapefile for masking +#' a continuous or binary range prediction (sdm) based on the path and name of +#' a user-provided shapefile. The shapefile must fall within the extent of the +#' range prediction. Any part of the range prediction (sdm) outside of the polygon +#' will be removed ("masked" out). #' -#' @param bgShp_path Path to the user provided shapefile -#' @param bgShp_name Name of the user provided shapefile -#' @param sdm x +#' @param bgShp_path Path to the user-provided shapefile for masking +#' @param bgShp_name Name of the user-provided shapefile for masking +#' @param sdm A rasterlayer of a continuous or binary range prediction to be masked by shape #' @param logger stores all notification messages to be displayed in the Log Window of Wallace GUI. insert the logger reactive list here for running in shiny, #' otherwise leave the default NULL -#' @param spN x -# @keywords - -# @keywords +#' @param spN character. Used to obtain species name for logger messages #' -#' @return x +#' @examples +#' \dontrun{ +#' ### Set parameters +#' bgShp_path <- list.files(path = system.file("extdata/shp", package = "wallace"),full.names = TRUE) +#' bgShp_name <- list.files(path = system.file("extdata/shp", package = "wallace"),full.names = FALSE) +#' sdm <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif",package = "wallace")) +#' ### Run function +#' spatialMask <- mask_spatialPoly(bgShp_path,bgShp_name,sdm,logger = NULL,spN = NULL) +#' } +#' @return A SpatialPolygonsDataFrame for masking #' @author Gonzalo E. Pinilla-Buitrago < gpinillabuitrago@@gradcenter.cuny.edu> -# @note - +#' @author Bethany A. Johnson #' @export mask_spatialPoly <- function(bgShp_path, bgShp_name, sdm, @@ -47,15 +78,15 @@ mask_spatialPoly <- function(bgShp_path, bgShp_name, sdm, } else { logger %>% writeLog(type = 'error', - 'Please enter shapefile (.shp, .shx, .dbf).') + paste0('Please enter shapefile: .shp, .shx, & .dbf.')) return() } if (is.na(raster::crs(polyData, asText = TRUE))) { logger %>% writeLog( type = 'warning', hlSpp(spN), - "Projection not found for shapefile. It is assume that shapefile datum ", - "is WGS84 (**)" + "Projection not found for shapefile. It is assumed that shapefile datum ", + "is WGS84. " ) } @@ -65,7 +96,7 @@ mask_spatialPoly <- function(bgShp_path, bgShp_name, sdm, if (!sf::st_intersects(sdm_sfc, polyData_sfc, sparse = FALSE)[1,1]) { logger %>% writeLog( type = 'error', hlSpp(spN), - "Shapefile does not match with SDM extent. Please specify a new polygon. " + "Shapefile must fall within the SDM extent. Please specify a new polygon. " ) return() } @@ -98,8 +129,8 @@ mask_spatialPoly <- function(bgShp_path, bgShp_name, sdm, logger %>% writeLog( type = 'warning', hlSpp(spN), paste("The polygon selected included some cells with NA values.", - "You cannot changes the predictions (suitable or unsuitable),", - "in these cells.(**)") + "You cannot change the predictions (suitable or unsuitable),", + "in these cells. ") ) } sf::st_crs(polyData) <- sf::st_crs(polR) diff --git a/R/mask_tempAnnotate.R b/R/mask_tempAnnotate.R index eb7532276..ad7074b4f 100644 --- a/R/mask_tempAnnotate.R +++ b/R/mask_tempAnnotate.R @@ -1,16 +1,59 @@ - +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# mask_tempAnnotate.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title mask_tempAnnotate -#' @description Obtain temporal matched values -#' @param occs Occurrences -#' @param env Stack of raster -#' @param envDates String with the years of rasters -#' @param logger logger +#' @description Obtain temporally matched values +#' @details Annotate point data (e.g., occurrences) with raster values (e.g., +#' env data) based on matching years. Function returns the quantiles of values +#' for use in selecting a threshold value for masking. +#' @param occs Dataframe of occurrence/point data. Must include years +#' @param env Rasterstack of annual environmental data +#' @param envDates String with the years corresponding to the rasters +#' @param logger Stores all notification messages to be displayed in the Log +#' Window of Wallace GUI. Insert the logger reactive list here for running in +#' shiny, otherwise leave the default NULL. +#' @examples +#' \dontrun{ +#' ### Set parameters +#' occs <- read.csv(system.file("extdata/Bassaricyon_alleni.csv", package = "wallace")) +#' # assigning dummy dates, but ideally the occ data would have years +#' dates <- sample(2000:2019,35, replace=T) +#' occs$year <- dates +#' env <- list.files(path = system.file('extdata/MODIS', package = "wallace"),full.names = TRUE) +#' env <- raster::stack(env) +#' envDates <- c(2005,2006,2008,2009,2010) +#' ### Run function +#' bounds <- mask_tempAnnotate(occs, env, envDates, logger = NULL) +#' } +#' @return Numeric. Returns the quantiles #' @author Gonzalo E. Pinilla-Buitrago +#' @author Bethany A. Johnson +#' @seealso \code{\link[maskRangeR]{annotate}}, \code{\link{mask_tempExtract}} #' @export #' mask_tempAnnotate <- function(occs, env, envDates, logger = NULL) { # this should be a formal date object of class "POSIXct" "POSIXt" - smartProgress(logger, message = "Annotate ... (**)", { + smartProgress(logger, message = "Annotating ... ", { envDates <- lubridate::parse_date_time(envDates, orders = c("Y", "Ym")) datedOccs <- occs datedOccs$date <- lubridate::parse_date_time(datedOccs$year, orders = c("Y", "Ym")) diff --git a/R/mask_tempExtract.R b/R/mask_tempExtract.R index 48811cef5..d8b4486f0 100644 --- a/R/mask_tempExtract.R +++ b/R/mask_tempExtract.R @@ -1,20 +1,63 @@ - +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# mask_tempExtract.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title mask_tempExtract #' @description To mask prediction by temporal thresholds. -#' @param lowerInp Lower bound value -#' @param upperInp Upper bound value -#' @param maskRaster Masking raster -#' @param pred Prediction -#' @param logger logger -#' @param spN Species name. +#' @details Mask a range prediction (e.g., an SDM prediction) with an +#' environmental raster. Set the upper and lower bounds to remove areas +#' above/below those values in the masking raster from the prediction. The upper +#' and lower bounds can be determined from tempAnnotate. Anything area in the +#' masking raster with values below the lower bound and above the upper bound +#' will be removed from the range prediction. +#' @param lowerInp numeric. Lower bound value +#' @param upperInp numeric. Upper bound value +#' @param maskRaster RasterLayer. The masking raster +#' @param pred RasterLayer. The range prediction to be masked +#' @param logger stores all notification messages to be displayed in the Log +#' Window of Wallace GUI. insert the logger reactive list here for running in +#' shiny, otherwise leave the default NULL +#' @param spN character. Used to obtain species name for logger messages +#' @examples +#' \dontrun{ +#' ### Set parameters +#' lowerInp <- 50 +#' upperInp <- 100 +#' maskRaster <- raster::raster(system.file("extdata/MODIS/2010_olinguito_Modis.tif", package = "wallace")) +#' pred <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif", package = "wallace")) +#' ### Run function +#' postPred <- mask_tempExtract(lowerInp, upperInp, maskRaster, pred, logger = NULL, spN = NULL) +#' } +#' @return Returns a RasterLayer of the masked range prediction #' @author Gonzalo E. Pinilla-Buitrago +#' @author Bethany A. Johnson +#' @seealso \code{\link{mask_tempAnnotate}} #' @export #' mask_tempExtract <- function(lowerInp, upperInp, maskRaster, pred, logger = NULL, spN = NULL) { if (is.na(lowerInp) & is.na(upperInp)) { - logger %>% writeLog(type = 'error', hlSpp(spN), "Please, provide bounds (**)") + logger %>% writeLog(type = 'error', hlSpp(spN), "Please provide bounds for masking. ") return() } # compare prediction and mask Raster @@ -22,12 +65,13 @@ mask_tempExtract <- function(lowerInp, upperInp, maskRaster, pred, pred <- terra::rast(pred) maskRaster <- terra::rast(maskRaster) pred <- terra::resample(pred, maskRaster, "near") - sameExt <- terra::compareGeom(maskRaster, pred, ext = FALSE, - rowcol = FALSE, crs = TRUE, res = TRUE) - if (sameExt == FALSE) { + sameExt <- tryCatch(expr =terra::compareGeom(maskRaster, pred, ext = FALSE, + rowcol = FALSE, crs = TRUE, res = TRUE), + error = function(e) NULL) + if (is.null(sameExt)) { logger %>% writeLog(type = 'warning', hlSpp(spN), - "Rasters don't have the same resolution, crs or origin. (**)") + "Rasters don't have the same resolution, CRS, and/or origin. ") return() } maskRaster <- terra::crop(maskRaster, pred) diff --git a/R/mask_userSDM.R b/R/mask_userSDM.R index 2d0017980..a80d53936 100644 --- a/R/mask_userSDM.R +++ b/R/mask_userSDM.R @@ -1,27 +1,59 @@ -#' +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# mask_userSDM.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title mask_userSDM #' @description Upload user-specified SDM prediction #' -#' @details -#' See Examples. +#' @details This function uploads a raster of a species' range prediction to be +#' used in Wallace EcoMod. The file name needs to named in Genus_species format +#' (Ex: Bassaricyon_neblina.tif) to have Wallace functionality. The raster can +#' be binary or continuous, but may need to be binary for some further analyses +#' in Wallace. This function returns a list of the range prediction raster as +#' well as a spatial polygon of the extent of the range prediction. #' -#' @param rasPath character of path to rasters, must be the full path including file name and extension. +#' @param rasPath character of path to raster, must be the full path including file name and extension. #' Filename need to be name with genus_species format. -#' @param rasName character vector of raster names to be assigned to loaded rasters +#' @param rasName character vector of raster names to be assigned to loaded raster #' @param logger stores all notification messages to be displayed in the Log Window of Wallace GUI. insert the logger reactive list here for running in shiny, #' otherwise leave the default NULL #' @param spN Species name -# @keywords -#' -# @examples #' +#' @examples +#' \dontrun{ +#' ### Set parameters +#' rasPath <- system.file("extdata/Bassaricyon_neblina.tif",package = "wallace") +#' rasName <- "Bassaricyon_neblina.tif" +#' ### Run function +#' sdm <- mask_userSDM(rasPath, rasName, logger = NULL, spN = NULL) +#' } #' -# @return +#' @return A list of two: the prediction rasterlayer and a spatialpolygon of the extent #' @author Gonzalo E. Pinilla-Buitrago #' @author Jamie Kass +#' @author Bethany A. Johnson +#' +# @keywords # @note - -# @seealso # @references # @aliases - a list of additional topic names that will be mapped to # this documentation when the user looks them up from the command @@ -43,7 +75,7 @@ mask_userSDM <- function(rasPath, rasName, logger = NULL, spN = NULL) { 'See guidance text in this module for more details.') return() } - smartProgress(logger, message = "Uploading user-specified SDM (**)...", { + smartProgress(logger, message = "Uploading user-specified SDM...", { r <- raster::trim(r) names(r) <- fileNameNoExt(rasName) extPoly <- raster::extent(r) @@ -51,7 +83,7 @@ mask_userSDM <- function(rasPath, rasName, logger = NULL, spN = NULL) { extPoly@ymin < -90 | extPoly@ymax > 90) { logger %>% writeLog( - type = "error", "Wrong extent projection. '", rasName,"' cannot be uploaded. (**)") + type = "error", "Wrong extent projection. '", rasName,"' cannot be uploaded. ") return() } extPoly <- methods::as(extPoly, 'SpatialPolygons') diff --git a/R/occs_biomodelos.R b/R/occs_biomodelos.R index fb9e1c7ca..0b1a1366a 100644 --- a/R/occs_biomodelos.R +++ b/R/occs_biomodelos.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# occs_biomodelos.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# #' @title `occs_biomodelos` query biomodelos database #' @description #' query BioModelos database and returns the complete list of data, data with coordinates, and data with no duplicates @@ -16,7 +39,16 @@ #' @return A list of 2 dataframes. First dataframe is the original dowloaded dataset, second data frame without duplicates and with appropriate fields for analyses #' @author Gonzalo E. Pinilla-Buitrago < gpinillabuitrago@@gradcenter.cuny.edu> -#' @author Peter Ersts? +#' @author Bethany A. Johnson +#' @author Peter Ersts +#' @examples +#' \dontrun{ +#' ### Set parameters +#' spN <- "Bassaricyon neblina" +#' bioKey <- 12345 +#' ### Run function +#' occs <- occs_biomodelos(spN, bioKey, logger = NULL) +#' } #' @export occs_biomodelos <- function(spN, bioKey, logger = NULL) { @@ -26,7 +58,7 @@ occs_biomodelos <- function(spN, bioKey, logger = NULL) { # if two names not entered, throw error and return if (nameSplit != 2) { logger %>% writeLog(type = 'error', - 'Please input both genus and species names of ONE species. (**)') + 'Please input both genus and species names of ONE species. ') return() } spN <- paste0(toupper(substring(spN, 1, 1)), @@ -35,15 +67,25 @@ occs_biomodelos <- function(spN, bioKey, logger = NULL) { spN <- gsub(pattern = " ", replacement = "_", x = spN) urlSearch <- paste0('https://api-biomodelos.humboldt.org.co/v2/species/search/', bioName) - respSearch <- httr::GET(urlSearch, + respSearch <- tryCatch(expr = httr::GET(urlSearch, httr::add_headers(host = 'api-biomodelos.humboldt.org.co', - authorization = paste0('apiKey ', bioKey))) - jsonSearch <- httr::content(respSearch, 'parsed') + authorization = paste0('apiKey ', bioKey))), + error= function(e) NULL) + #trycatch error + if (is.null(respSearch)) { + logger %>% writeLog( + type = "error", + paste0("Unable to retrieve data from BioModelos. + Server may be down. ")) + return() + } else { + jsonSearch <- httr::content(respSearch, 'parsed') + } if (length(jsonSearch) == 0) { logger %>% writeLog( type = 'error', - hlSpp(spN), "Species name not found, please check the spelling") + hlSpp(spN), "Species name not found, please check the spelling. ") return() } @@ -67,7 +109,7 @@ occs_biomodelos <- function(spN, bioKey, logger = NULL) { if (nrow(geo) == 0) { logger %>% writeLog( type = 'error', - hlSpp(spN), "Species without records on BioModelos") + hlSpp(spN), "Species without records on BioModelos. ") return() } diff --git a/README.md b/README.md index fc691aa4a..5a3565f7a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![R-CMD-check](https://github.com/wallaceEcoMod/wallace/workflows/R-CMD-check/badge.svg)](https://github.com/wallaceEcoMod/wallace/actions) [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![CRAN version](http://www.r-pkg.org/badges/version/wallace)](https://CRAN.R-project.org/package=wallace) [![downloads](https://cranlogs.r-pkg.org:443/badges/grand-total/wallace?color=orange)](https://cranlogs.r-pkg.org:443/badges/grand-total/wallace?color=orange) -# Wallace (v2024.08.02) +# Wallace (v2024.09.18) *Wallace* is a modular platform for reproducible modeling of species niches and distributions, written in R. The application guides users through a complete analysis, from the acquisition of data to visualizing model predictions on an interactive map, thus bundling complex workflows into a single, streamlined interface. Install *Wallace* via CRAN and run the application with the following R code. @@ -26,7 +26,7 @@ run_wallace() Please make sure you have installed the latest versions of both R (Mac OS, Windows) and RStudio (Mac OS / Windows: choose the free version). #### How to run Maxent with maxent.jar -*Wallace* v.2024.02.23 includes two options to run Maxent models: maxnet and maxent.jar. The former, which is an R implementation and fits the model with the package `glmnet`, is now the default and does not require the package `rJava` (see Phillips et al. 2017). The latter, which is the Java implementation, runs the `maxent()` function in the package `dismo`. This function requires the user to place the `maxent.jar` file in the `/java` directory of the `dismo` package root folder. You can download Maxent here, and locate `maxent.jar`, which is the Maxent program itself, in the downloaded folder. You can find the directory path to `dismo/java` by running `system.file('java', package="dismo")` at the R console. Simply copy `maxent.jar` and paste it into this folder. If you try to run Maxent in *Wallace* without the file in place, you will get a warning message in the log window and Maxent will not run. +*Wallace* v.2024.09.18 includes two options to run Maxent models: maxnet and maxent.jar. The former, which is an R implementation and fits the model with the package `glmnet`, is now the default and does not require the package `rJava` (see Phillips et al. 2017). The latter, which is the Java implementation, runs the `maxent()` function in the package `dismo`. This function requires the user to place the `maxent.jar` file in the `/java` directory of the `dismo` package root folder. You can download Maxent here, and locate `maxent.jar`, which is the Maxent program itself, in the downloaded folder. You can find the directory path to `dismo/java` by running `system.file('java', package="dismo")` at the R console. Simply copy `maxent.jar` and paste it into this folder. If you try to run Maxent in *Wallace* without the file in place, you will get a warning message in the log window and Maxent will not run. ### Potential Issues diff --git a/inst/extdata/B_neblina_WCEA.tif b/inst/extdata/B_neblina_WCEA.tif new file mode 100644 index 000000000..c4a67b706 Binary files /dev/null and b/inst/extdata/B_neblina_WCEA.tif differ diff --git a/inst/extdata/Bassaricyon_neblina.tif b/inst/extdata/Bassaricyon_neblina.tif new file mode 100755 index 000000000..a6593764a Binary files /dev/null and b/inst/extdata/Bassaricyon_neblina.tif differ diff --git a/inst/extdata/MODIS/2005_olinguito_Modis.tif b/inst/extdata/MODIS/2005_olinguito_Modis.tif new file mode 100755 index 000000000..7aaf6b292 Binary files /dev/null and b/inst/extdata/MODIS/2005_olinguito_Modis.tif differ diff --git a/inst/extdata/MODIS/2006_olinguito_Modis.tif b/inst/extdata/MODIS/2006_olinguito_Modis.tif new file mode 100755 index 000000000..077ff8991 Binary files /dev/null and b/inst/extdata/MODIS/2006_olinguito_Modis.tif differ diff --git a/inst/extdata/MODIS/2008_olinguito_Modis.tif b/inst/extdata/MODIS/2008_olinguito_Modis.tif new file mode 100755 index 000000000..60d4155ca Binary files /dev/null and b/inst/extdata/MODIS/2008_olinguito_Modis.tif differ diff --git a/inst/extdata/MODIS/2009_olinguito_Modis.tif b/inst/extdata/MODIS/2009_olinguito_Modis.tif new file mode 100755 index 000000000..930d19767 Binary files /dev/null and b/inst/extdata/MODIS/2009_olinguito_Modis.tif differ diff --git a/inst/extdata/MODIS/2010_olinguito_Modis.tif b/inst/extdata/MODIS/2010_olinguito_Modis.tif new file mode 100755 index 000000000..930d19767 Binary files /dev/null and b/inst/extdata/MODIS/2010_olinguito_Modis.tif differ diff --git a/inst/extdata/wc/proj/no_projection.tif b/inst/extdata/wc/proj/no_projection.tif deleted file mode 100644 index b57937f6d..000000000 Binary files a/inst/extdata/wc/proj/no_projection.tif and /dev/null differ diff --git a/inst/extdata/wdpa/WDPA_COL_olinguito.dbf b/inst/extdata/wdpa/WDPA_COL_olinguito.dbf new file mode 100755 index 000000000..b6158fc93 Binary files /dev/null and b/inst/extdata/wdpa/WDPA_COL_olinguito.dbf differ diff --git a/inst/extdata/wdpa/WDPA_COL_olinguito.shp b/inst/extdata/wdpa/WDPA_COL_olinguito.shp new file mode 100755 index 000000000..2ef2caa47 Binary files /dev/null and b/inst/extdata/wdpa/WDPA_COL_olinguito.shp differ diff --git a/inst/extdata/wdpa/WDPA_COL_olinguito.shx b/inst/extdata/wdpa/WDPA_COL_olinguito.shx new file mode 100755 index 000000000..4a8d807ba Binary files /dev/null and b/inst/extdata/wdpa/WDPA_COL_olinguito.shx differ diff --git a/inst/shiny/Rmd/text_about.Rmd b/inst/shiny/Rmd/text_about.Rmd index ac9187593..bc5a84041 100644 --- a/inst/shiny/Rmd/text_about.Rmd +++ b/inst/shiny/Rmd/text_about.Rmd @@ -6,7 +6,7 @@ output: html_document ### **What is *Wallace*?** logo -Welcome to *Wallace*, a flexible application for reproducible ecological modeling, built for community expansion. The current version of *Wallace* (v2024.08.02) steps the user through a full niche/distribution modeling analysis, from data acquisition to visualizing results. +Welcome to *Wallace*, a flexible application for reproducible ecological modeling, built for community expansion. The current version of *Wallace* (v2024.09.18) steps the user through a full niche/distribution modeling analysis, from data acquisition to visualizing results. The application is written in `R` with the web app development package `shiny`. Please find the stable version of *Wallace* on CRAN, and the development version on Github. We also maintain a *Wallace* website that has some basic info, links, and will be updated with tutorial materials in the near future. diff --git a/inst/shiny/Rmd/text_intro_tab.Rmd b/inst/shiny/Rmd/text_intro_tab.Rmd index dc5b4d212..591536c20 100644 --- a/inst/shiny/Rmd/text_intro_tab.Rmd +++ b/inst/shiny/Rmd/text_intro_tab.Rmd @@ -5,7 +5,7 @@ output: html_document #### WORKFLOW -*Wallace* (v2024.08.02) currently includes ten components, or steps of a possible workflow. Each component includes two or more modules, which are possible analyses for that step. +*Wallace* (v2024.09.18) currently includes ten components, or steps of a possible workflow. Each component includes two or more modules, which are possible analyses for that step. **Components:** diff --git a/inst/shiny/Rmd/userReport_intro.Rmd b/inst/shiny/Rmd/userReport_intro.Rmd index 5439139b5..36608db7b 100644 --- a/inst/shiny/Rmd/userReport_intro.Rmd +++ b/inst/shiny/Rmd/userReport_intro.Rmd @@ -10,7 +10,7 @@ knit_engines$set(asis = function(options) { knitr::opts_chunk$set(message = FALSE, warning = FALSE, eval = FALSE) ``` -Please find below the R code history from your *Wallace* v2024.08.02 session. +Please find below the R code history from your *Wallace* v2024.09.18 session. You can reproduce your session results by running this R Markdown file in RStudio. diff --git a/inst/shiny/custom_modules/occs_biomodelos.R b/inst/shiny/custom_modules/occs_biomodelos.R index 8f623d453..c16a868df 100644 --- a/inst/shiny/custom_modules/occs_biomodelos.R +++ b/inst/shiny/custom_modules/occs_biomodelos.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# occs_biomodelos.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# occs_biomodelos_module_ui <- function(id) { ns <- shiny::NS(id) tagList( @@ -34,6 +57,8 @@ occs_biomodelos_module_server <- function(input, output, session, common) { occsCleaned = occs), rmm = rangeModelMetadata::rmmTemplate(), rmd = list()) + # REFERENCES #### + knitcitations::citep(citation("httr")) # METADATA #### spp[[sp]]$rmm$data$occurrence$taxon <- sp diff --git a/inst/shiny/custom_modules/occs_biomodelos.yml b/inst/shiny/custom_modules/occs_biomodelos.yml index 5cf91491f..aee3e7bd2 100644 --- a/inst/shiny/custom_modules/occs_biomodelos.yml +++ b/inst/shiny/custom_modules/occs_biomodelos.yml @@ -1,5 +1,5 @@ component: "occs" short_name: "Query BioModelos" long_name: "Query BioModelos" -authors: "GEPB (**)" -package: [] +authors: "GEPB, Bethany A. Johnson" +package: [httr] diff --git a/inst/shiny/custom_modules/rep_biomodelos.R b/inst/shiny/custom_modules/rep_biomodelos.R index 85092681f..544b299bc 100644 --- a/inst/shiny/custom_modules/rep_biomodelos.R +++ b/inst/shiny/custom_modules/rep_biomodelos.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# rep_biomodelos.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# rep_biomodelos_module_ui <- function(id) { ns <- shiny::NS(id) tagList( diff --git a/inst/shiny/modules/diver_endemism.R b/inst/shiny/modules/diver_endemism.R index 7430da8e1..e7e64b36e 100644 --- a/inst/shiny/modules/diver_endemism.R +++ b/inst/shiny/modules/diver_endemism.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# diver_endemism.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# diver_endemism_module_ui <- function(id) { ns <- shiny::NS(id) tagList( @@ -140,10 +163,18 @@ diver_endemism_module_server <- function(input, output, session, common) { # FUNCTION CALL #### req(endemism) logger %>% writeLog("Species endemism calculated.") + # LOAD INTO SPP #### multi.sp$endemism <- endemism multi.sp$sppEndemism <- curSp() common$update_component(tab = "Map") + + # REFERENCES #### + knitcitations::citep(citation("raster")) + knitcitations::citep(citation("changeRangeR")) + + # METADATA #### + # add metadata }) output$result <- renderPrint({ diff --git a/inst/shiny/modules/diver_endemism.Rmd b/inst/shiny/modules/diver_endemism.Rmd index a1c6db3de..86f7a91aa 100644 --- a/inst/shiny/modules/diver_endemism.Rmd +++ b/inst/shiny/modules/diver_endemism.Rmd @@ -1,5 +1,6 @@ ```{asis, echo = {{diver_endemism_knit}}, eval = {{diver_endemism_knit}}, include = {{diver_endemism_knit}}} -# +### Calculate endemism +Write something here about what is going on... ``` ```{r, echo = {{diver_endemism_knit}}, include = {{diver_endemism_knit}}} diff --git a/inst/shiny/modules/diver_richness.R b/inst/shiny/modules/diver_richness.R index 7c63f6a69..4c7dc51f4 100644 --- a/inst/shiny/modules/diver_richness.R +++ b/inst/shiny/modules/diver_richness.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# diver_richness.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# diver_richness_module_ui <- function(id) { ns <- shiny::NS(id) tagList( @@ -140,10 +163,17 @@ diver_richness_module_server <- function(input, output, session, common) { req(richness) logger %>% writeLog("Species richness calculated.") + # LOAD INTO SPP #### multi.sp$richness <- richness multi.sp$sppRichness <- curSp() common$update_component(tab = "Map") + + # REFERENCES #### + knitcitations::citep(citation("raster")) + + # METADATA #### + #add metadata }) return(list( diff --git a/inst/shiny/modules/diver_richness.yml b/inst/shiny/modules/diver_richness.yml index 36984cf1f..7b4eb7407 100644 --- a/inst/shiny/modules/diver_richness.yml +++ b/inst/shiny/modules/diver_richness.yml @@ -1,5 +1,5 @@ component: "diver" short_name: "Calculate Richness" long_name: "Calculate Richness" -authors: "Andrea Paz" +authors: "Andrea Paz, Bethany A. Johnson" package: [raster] diff --git a/inst/shiny/modules/indic_overlap.R b/inst/shiny/modules/indic_overlap.R index 83cc90427..16e50de8f 100644 --- a/inst/shiny/modules/indic_overlap.R +++ b/inst/shiny/modules/indic_overlap.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# indic_overlap.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# indic_overlap_module_ui <- function(id) { ns <- shiny::NS(id) tagList( @@ -175,7 +198,7 @@ indic_overlap_module_server <- function(input, output, session, common) { mask = "Masked SDM", eoo = "Extent of Occurrence (EOO)", aoo = "Area of Ocupancy (AOO)"), - " selected for overlap analysis (**)")) + " selected for overlap analysis.")) # LOAD TO SPP spp[[curSp()]]$indic$overlapSourcePoly <- rangeMap spp[[curSp()]]$indic$overlapSource <- selOverlapSource() @@ -198,7 +221,7 @@ indic_overlap_module_server <- function(input, output, session, common) { if (input$indicOverlap == 'shapefile') { # ERROR if (is.null(input$indicOverlapShp$datapath)) { - logger %>% writeLog(type = 'error', "Specified filepath(s).") + logger %>% writeLog(type = 'error', "Specify filepath(s).") return() } inputOverlap <- indic_inputPoly(input$indicOverlapShp$datapath, @@ -259,7 +282,7 @@ indic_overlap_module_server <- function(input, output, session, common) { shinyWidgets::pickerInput("overlapCat", label = "Select Category", choices = category, - multiple = TRUE, + multiple = FALSE, #BAJ 09/10/24: bug in cRR (#12). change to TRUE when fixed selected = category, options = list(`actions-box` = TRUE)) }) @@ -310,6 +333,13 @@ indic_overlap_module_server <- function(input, output, session, common) { spp[[curSp()]]$indic$overlapFields <- overlapF spp[[curSp()]]$indic$overlapCat <- overlapC common$update_component(tab = "Results") + + # REFERENCES #### + knitcitations::citep(citation("raster")) + knitcitations::citep(citation("changeRangeR")) + + # METADATA #### + # add metadata }) output$result <- renderUI({ diff --git a/inst/shiny/modules/indic_overlap.yml b/inst/shiny/modules/indic_overlap.yml index 60a4838eb..dc3bbe157 100644 --- a/inst/shiny/modules/indic_overlap.yml +++ b/inst/shiny/modules/indic_overlap.yml @@ -1,5 +1,5 @@ component: "indic" short_name: "Calculate Ratio Overlap" long_name: "Calculate Ratio Overlap" -authors: "Andrea Paz" +authors: "Andrea Paz, Bethany A. Johnson" package: [raster, changeRangeR] diff --git a/inst/shiny/modules/indic_range.R b/inst/shiny/modules/indic_range.R index 49732f3dc..1fbe0ecc1 100644 --- a/inst/shiny/modules/indic_range.R +++ b/inst/shiny/modules/indic_range.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# indic_range.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# indic_range_module_ui <- function(id) { ns <- shiny::NS(id) tagList( @@ -220,6 +243,13 @@ indic_range_module_server <- function(input, output, session, common) { spp[[curSp()]]$flags$indicAreaMap <- "aoo" common$update_component(tab = "Map") } + + # REFERENCES #### + knitcitations::citep(citation("raster")) + knitcitations::citep(citation("changeRangeR")) + + # METADATA #### + # add metadata }) output$areas <- renderText({ diff --git a/inst/shiny/modules/indic_range.yml b/inst/shiny/modules/indic_range.yml index f38c33b06..8d9b8e5b1 100644 --- a/inst/shiny/modules/indic_range.yml +++ b/inst/shiny/modules/indic_range.yml @@ -1,5 +1,5 @@ component: "indic" short_name: "Calculate Area Metrics" long_name: "Calculate Area Metrics" -authors: "Andrea Paz" +authors: "Andrea Paz, Bethany A. Johnson" package: [raster, changeRangeR] diff --git a/inst/shiny/modules/indic_time.R b/inst/shiny/modules/indic_time.R index f51880083..5c2049c80 100644 --- a/inst/shiny/modules/indic_time.R +++ b/inst/shiny/modules/indic_time.R @@ -1,8 +1,31 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# indic_time.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# indic_time_module_ui <- function(id) { ns <- shiny::NS(id) tagList( ##inputs must be: SDM so step 1 remains - #Environmental variables (e g forest thorugh time as rasters (multiple)) + #Environmental variables (e.g., forest through time as rasters (multiple)) #Threshold numeric input #years used (numeric input?) span("Step 1:", class = "step"), @@ -156,6 +179,12 @@ indic_time_module_server <- function(input, output, session, common) { } rangeMap <- sf::st_as_sf(rangeMap) } + # BAJ is this needed here or in wallace/R/inidic_time.R? + # if ("SpatRaster"%in% class(range)) { + # range[range == 0] <- NA + # range <- terra::as.polygons(range) + # range <- sf::st_as_sf(range) + # } req(rangeMap) logger %>% writeLog(hlSpp(curSp()), @@ -258,6 +287,8 @@ indic_time_module_server <- function(input, output, session, common) { "No range map is selected for the calculations.") return() } + # BAJ 9/25/2024: should the rangeMap match the envs, or the envs match the rangeMap? + # See the cRR example for indic_time where it is the opposite- the envs are changed to match the range rangeMap <- sf::as_Spatial(spp[[curSp()]]$indic$timeRange) %>% raster::rasterize(spp[[curSp()]]$indic$indicEnvs[[1]]) rangeArea <- indic_time(range = rangeMap, @@ -270,6 +301,13 @@ indic_time_module_server <- function(input, output, session, common) { spp[[curSp()]]$indic$areaTime <- rangeArea spp[[curSp()]]$indic$years <- years common$update_component(tab = "Results") + + # REFERENCES #### + knitcitations::citep(citation("raster")) + knitcitations::citep(citation("changeRangeR")) + + # METADATA #### + # add metadata }) output$timeAreas <- renderUI({ diff --git a/inst/shiny/modules/indic_time.yml b/inst/shiny/modules/indic_time.yml index 42cbd74c7..fd9e34cad 100644 --- a/inst/shiny/modules/indic_time.yml +++ b/inst/shiny/modules/indic_time.yml @@ -1,5 +1,5 @@ component: "indic" short_name: "Calculate Change Over Time" long_name: "Calculate Change Over Time" -authors: "Andrea Paz" +authors: "Andrea Paz, Bethany A. Johnson" package: [raster, changeRangeR] diff --git a/inst/shiny/modules/mask_expPoly.R b/inst/shiny/modules/mask_expPoly.R index 8e6b2144e..dfeac6cb6 100644 --- a/inst/shiny/modules/mask_expPoly.R +++ b/inst/shiny/modules/mask_expPoly.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# mask_expPoly.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# mask_expPoly_module_ui <- function(id) { ns <- shiny::NS(id) tagList( @@ -299,6 +322,12 @@ mask_expPoly_module_server <- function(input, output, session, common) { type = "error", hlSpp(curSp()), "The polygon was already used. Define a new one (**)") } + + # REFERENCES #### + knitcitations::citep(citation("raster")) + + # METADATA #### + #add metadata }) # Reset prediction diff --git a/inst/shiny/modules/mask_expPoly.yml b/inst/shiny/modules/mask_expPoly.yml index 643d09685..b675018a0 100644 --- a/inst/shiny/modules/mask_expPoly.yml +++ b/inst/shiny/modules/mask_expPoly.yml @@ -1,5 +1,5 @@ component: "mask" short_name: "Mask by Drawn Polygon" long_name: "Mask by Drawn Polygon" -authors: "Gonzalo E. Pinilla-Buitrago (**)" +authors: "Gonzalo E. Pinilla-Buitrago, Bethany A. Johnson" package: [raster] diff --git a/inst/shiny/modules/mask_spatial.R b/inst/shiny/modules/mask_spatial.R index f1cc14db4..8dfe96b3c 100644 --- a/inst/shiny/modules/mask_spatial.R +++ b/inst/shiny/modules/mask_spatial.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# mask_spatial.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# mask_spatial_module_ui <- function(id) { ns <- shiny::NS(id) tagList( @@ -190,7 +213,12 @@ mask_spatial_module_server <- function(input, output, session, common) { logger %>% writeLog( hlSpp(curSp()), "Spatial Masked (**)") + # REFERENCES #### + knitcitations::citep(citation("sp")) + knitcitations::citep(citation("sf")) + # METADATA #### + #add metadata }) # Reset prediction diff --git a/inst/shiny/modules/mask_spatial.yml b/inst/shiny/modules/mask_spatial.yml index 4646ceac3..e3c39c5ed 100644 --- a/inst/shiny/modules/mask_spatial.yml +++ b/inst/shiny/modules/mask_spatial.yml @@ -1,5 +1,5 @@ component: "mask" short_name: "Mask by Shapefile" long_name: "Mask by Shapefile" -authors: "Gonzalo E. Pinilla-Buitrago (**)" -package: [sp] +authors: "Gonzalo E. Pinilla-Buitrago, Bethany A. Johnson" +package: [sp, sf] diff --git a/inst/shiny/modules/mask_temp.R b/inst/shiny/modules/mask_temp.R index ea24027eb..5d260f70a 100644 --- a/inst/shiny/modules/mask_temp.R +++ b/inst/shiny/modules/mask_temp.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# mask_temp.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# mask_temp_module_ui <- function(id) { ns <- shiny::NS(id) tagList( @@ -274,6 +297,10 @@ mask_temp_module_server <- function(input, output, session, common) { } common$update_component(tab = "Map") + # REFERENCES #### + knitcitations::citep(citation("maskRangeR")) + + # METADATA #### }) # Reset prediction diff --git a/inst/shiny/modules/mask_temp.yml b/inst/shiny/modules/mask_temp.yml index afbc55b85..a1a8cad88 100644 --- a/inst/shiny/modules/mask_temp.yml +++ b/inst/shiny/modules/mask_temp.yml @@ -1,5 +1,5 @@ component: "mask" short_name: "Temporal Extract" long_name: "Temporal Extract" -authors: "Gonzalo E. Pinilla-Buitrago (**)" +authors: "Gonzalo E. Pinilla-Buitrago, Bethany A. Johnson" package: [maskRangeR] diff --git a/inst/shiny/modules/mask_userSDM.R b/inst/shiny/modules/mask_userSDM.R index bc66846df..2725ffa89 100644 --- a/inst/shiny/modules/mask_userSDM.R +++ b/inst/shiny/modules/mask_userSDM.R @@ -1,3 +1,26 @@ +# Wallace EcoMod: a flexible platform for reproducible modeling of +# species niches and distributions. +# +# mask_userSDM.R +# File author: Wallace EcoMod Dev Team. 2023. +# -------------------------------------------------------------------------- +# This file is part of the Wallace EcoMod application +# (hereafter “Wallace”). +# +# Wallace is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Wallace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Wallace. If not, see . +# -------------------------------------------------------------------------- +# mask_userSDM_module_ui <- function(id) { ns <- shiny::NS(id) tagList( @@ -61,8 +84,13 @@ mask_userSDM_module_server <- function(input, output, session, common) { spp[[sppName]]$mask$userPolyExt <- userSDMs$extSdm logger %>% writeLog(hlSpp(sppName), "User SDM prediction loaded") + # REFERENCES #### + knitcitations::citep(citation("raster")) + # METADATA #### spp[[sppName]]$rmm$code$wallace$userSDM <- TRUE + spp[[sppName]]$rmm$code$wallace$rasPath <- input$sdmFile$datapath + spp[[sppName]]$rmm$code$wallace$rasName <- input$sdmFile$name } common$update_component(tab = "Map") }) @@ -128,10 +156,10 @@ mask_userSDM_module_map <- function(map, common) { mask_userSDM_module_rmd <- function(species) { # Variables used in the module's Rmd code - # list( - # mask_userSDM_knit = FALSE - # var1 = species$rmm$code$wallace$someSetting1, - # var2 = species$rmm$code$wallace$someSetting2 - # ) + list( + mask_userSDM_knit = species$rmm$code$wallace$userSDM == TRUE, + rasPath_rmd = species$rmm$code$wallace$rasPath, + rasName_rmd = species$rmm$code$wallace$rasName, + ) } diff --git a/inst/shiny/modules/mask_userSDM.Rmd b/inst/shiny/modules/mask_userSDM.Rmd index 34d23d450..4825bc3cf 100644 --- a/inst/shiny/modules/mask_userSDM.Rmd +++ b/inst/shiny/modules/mask_userSDM.Rmd @@ -1,7 +1,12 @@ ```{asis, echo = {{mask_userSDM_knit}}, eval = {{mask_userSDM_knit}}, include = {{mask_userSDM_knit}}} -# +### Upload a User SDM +Uploading a user-specified SDM range prediction" ``` ```{r, echo = {{mask_userSDM_knit}}, include = {{mask_userSDM_knit}}} -# +# Upload SDM +sdm_{{spAbr}} <- mask_userSDM({{rasPath_rmd}}, {{rasName_rmd}}) +#Define colors and legend +rasCols <- c("#2c7bb6", "#abd9e9", "#ffffbf", "#fdae61", "#d7191c") +#Map SDM ``` diff --git a/inst/shiny/modules/mask_userSDM.yml b/inst/shiny/modules/mask_userSDM.yml index 81900717c..bd8f41406 100644 --- a/inst/shiny/modules/mask_userSDM.yml +++ b/inst/shiny/modules/mask_userSDM.yml @@ -1,5 +1,5 @@ component: "mask" short_name: "Upload User Prediction" long_name: "Upload User Prediction" -authors: "Gonzalo E. Pinilla-Buitrago" +authors: "Gonzalo E. Pinilla-Buitrago, Bethany A. Johnson" package: [raster] diff --git a/man/indic_aoo.Rd b/man/indic_aoo.Rd index 9c00aaa4b..16c56a4ae 100644 --- a/man/indic_aoo.Rd +++ b/man/indic_aoo.Rd @@ -11,7 +11,7 @@ indic_aoo( lat = NULL, wktFrom, wktTo, - logger + logger = NULL ) } \arguments{ @@ -34,9 +34,48 @@ to calculate area.} Window of Wallace GUI. Insert the logger reactive list here for running in shiny, otherwise leave the default NULL} } +\value{ +A list of two elements: area and AOOraster. The first is the numeric +value of the area (in km^2). The second is a RasterLayer of the extent +(in WCEA & 2x2 km resolution). +} \description{ Calculate AOO. +} +\details{ +The function calculates the area of occupancy (AOO) from a thresholded +prediction raster or a data.frame of occurrence records. +} +\examples{ + \dontrun{ + ### Set parameters + # binary raster + r <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif", + package = "wallace")) + # occurrences + + ### Run function + # aoo from raster + aoo_r <- indic_aoo(r, + occs = NULL, + lon = NULL, + lat = NULL, + wktFrom = getWKT("wgs84"), + wktTo = getWKT("wcea"), + logger = NULL) + # aoo from occs + aoo_occs <- indic_aoo(r <- NULL, + occs, + lon = "longitude", + lat = "latitude", + wktFrom = getWKT("wgs84"), + wktTo = getWKT("wcea"), + logger = NULL) + } + } \author{ Gonzalo E. Pinilla-Buitrago + +Bethany A. Johnson } diff --git a/man/indic_area.Rd b/man/indic_area.Rd index 24cd73f70..59b2a3a5b 100644 --- a/man/indic_area.Rd +++ b/man/indic_area.Rd @@ -16,9 +16,24 @@ to calculate area.} Window of Wallace GUI. insert the logger reactive list here for running in shiny, otherwise leave the default NULL} } +\value{ +Numeric value +} \description{ Calculate Range size in square kilometers. } +\details{ +Calculate the geographic range size of a thresholded raster. The units are in square kilometers. +} +\examples{ +\dontrun{ +r <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif",package = "wallace")) +wkt <- getWKT("wcea") +areaRange <- indic_area(r, wkt, logger = NULL) +} +} \author{ Gonzalo E. Pinilla-Buitrago + +Bethany A. Johnson } diff --git a/man/indic_eoo.Rd b/man/indic_eoo.Rd index 038da75cb..22d78c1f6 100644 --- a/man/indic_eoo.Rd +++ b/man/indic_eoo.Rd @@ -4,7 +4,7 @@ \alias{indic_eoo} \title{indic_eoo} \usage{ -indic_eoo(r = NULL, occs = NULL, lon = NULL, lat = NULL, wkt, logger) +indic_eoo(r = NULL, occs = NULL, lon = NULL, lat = NULL, wkt, logger = NULL) } \arguments{ \item{r}{raster. Thresholded prediction raster. It could be NULL if occs provided.} @@ -23,11 +23,33 @@ to calculate area.} Window of Wallace GUI. Insert the logger reactive list here for running in shiny, otherwise leave the default NULL} } +\value{ +A list of two elements: area and eooPoly. area is a numeric value and eooPoly is a SpatialPolygon. +} \description{ Calculate EOO. +} +\details{ +Calculate extent of occurrence (EOO) based on a binary raster or occurrence points. +} +\examples{ +\dontrun{ +# binary raster +r <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif",package = "wallace")) +# occurrences +occs <- read.csv(system.file("extdata/Bassaricyon_neblina.csv",package = "wallace")) +# wcea +wkt <- getWKT("wcea") + +eoo_r <- indic_eoo(r, occs = NULL, lon = NULL, lat = NULL, wkt, logger = NULL) +eoo_o <- indic_eoo(r = NULL, occs, lon = "longitude", lat = "latitude", wkt, logger = NULL) +} + } \author{ Andrea Paz Gonzalo E. Pinilla-Buitrago + +Bethany A. Johnson } diff --git a/man/indic_inputPoly.Rd b/man/indic_inputPoly.Rd index 695af6e94..77fb996da 100644 --- a/man/indic_inputPoly.Rd +++ b/man/indic_inputPoly.Rd @@ -2,31 +2,65 @@ % Please edit documentation in R/indic_inputPoly.R \name{indic_inputPoly} \alias{indic_inputPoly} -\title{indic_inputPoly} +\title{indic_inputPoly user-provided shapefile for ratio overlap calculations} \usage{ -indic_inputPoly(bgShp_path, bgShp_name, overlapArea, logger = NULL, spN = NULL) +indic_inputPoly( + ovShp_path, + ovShp_name, + overlapRange, + logger = NULL, + spN = NULL +) } \arguments{ -\item{bgShp_path}{Path to the user provided shapefile} +\item{ovShp_path}{Path to the user provided shapefile} -\item{bgShp_name}{Name of the user provided shapefile} +\item{ovShp_name}{Name of the user provided shapefile} -\item{overlapArea}{x. An sf object.} +\item{overlapRange}{sf object. The source polygon for ratio overlap calculations} \item{logger}{stores all notification messages to be displayed in the Log Window of Wallace GUI. insert the logger reactive list here for running in shiny, otherwise leave the default NULL} -\item{spN}{x} +\item{spN}{character. Used to obtain species name for logger messages} } \value{ -x +An sf object to be used for calculating ratio overlap } \description{ -x +This function allows the user to upload a shapefile to be used in ratio overlap calculations } \details{ -x +This function is used in the Calculate Indicators component. Here, the user + provides the path and name of a shapefile to be used with the source polygon + to calculate the ratio of overlap between the polygons. The source polygon + is a polygonized raster of a range map from: a Wallace SDM (prediction, + transfer, or masked), EOO, or AOO. The user shapefile and source polygon must + intercept. The function returns an sf object to be used in the indic_overlap() + function. +} +\examples{ +\dontrun{ +# Overlap polygon +ovShp_path <- list.files(path = system.file("extdata/wdpa", package = "wallace"), full.names = TRUE) +ovShp_name <- list.files(path = system.file("extdata/wdpa", package = "wallace"), full.names = FALSE) + +# Source polygon +overlapRange <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif", package = "wallace")) +overlapRange[overlapRange == 0] <- NA +overlapRange <- terra::as.polygons(overlapRange) +overlapRange <- sf::st_as_sf(overlapRange) + +# Run function +polyData <- indic_inputPoly(ovShp_path, ovShp_name, overlapRange, logger = NULL, spN = NULL) +} + +} +\seealso{ +\code{\link{indic_overlap}} } \author{ -Gonzalo E. Pinilla-Buitrago < gpinillabuitrago@gradcenter.cuny.edu> +Gonzalo E. Pinilla-Buitrago + +Bethany A. Johnson } diff --git a/man/indic_overlap.Rd b/man/indic_overlap.Rd index ee8bf63f1..32c863167 100644 --- a/man/indic_overlap.Rd +++ b/man/indic_overlap.Rd @@ -14,25 +14,60 @@ indic_overlap( ) } \arguments{ -\item{rangeMap}{sf polygon. A polygon with the range map.} +\item{rangeMap}{sf object representing a binary range map.} -\item{inputOverlap}{sf polygon or raster. A feature to apply overlap.} +\item{inputOverlap}{sf polygon or continuous raster. A feature to apply overlap.} \item{field}{character. Name of the field to select categories/attributes. -NULL is inputOverlap is a raster.} +NULL if inputOverlap is a raster.} \item{category}{character. String with names of the categories/attributes -selected to overlap with range map. NULL is inputOverlap is a raster.} +selected to overlap with range map. NULL if inputOverlap is a raster.} -\item{logger}{logger} +\item{logger}{stores all notification messages to be displayed in the Log +Window of Wallace GUI. insert the logger reactive list here for running in +shiny, otherwise leave the default NULL} \item{spN}{species name} } +\value{ +A list of 2: a polygon of the overlap and the ratio overlap statistics. +} \description{ -Overlap range map with shapefile or raster +Overlap a binary range map with shapefile or raster +} +\details{ +This function calculates the overlap between a range map and a +supplied shape or continuous raster. If the inputOverlap is a continuous raster, the +function returns a polygon of the overlap and the proportion of range: +below 25%, 25-50%, 50-75%, and 75-100%. If the inputOverlap is a polygon, the +function returns a polygon of the overlap and the percentage of the range +contained within the shape. +} +\examples{ +\dontrun{ +### Set parameters +# range map +rangeMap <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif", package = "wallace")) +rangeMap[rangeMap == 0] <- NA +rangeMap <- terra::as.polygons(rangeMap) +rangeMap <- sf::st_as_sf(rangeMap) +# input overlap raster +inputRaster <- raster::raster(nrows=108, ncols=108, xmn=-80, xmx=-75) +raster::values(inputRaster)<- runif(n = (108*108)) + +### Run function +overlap_r <- indic_overlap(rangeMap, inputOverlap = inputRaster, field = NULL, category = NULL, logger = NULL, spN = NULL) +} + +} +\seealso{ +\code{\link{indic_raster}}, \code{\link{indic_inputPoly}}, \code{\link[changeRangeR]{ratioOverlap}} } \author{ Andrea Paz Gonzalo E. Pinilla-Buitrago + +Bethany A. Johnson } diff --git a/man/indic_raster.Rd b/man/indic_raster.Rd index 9a47a2762..2c05ba89c 100644 --- a/man/indic_raster.Rd +++ b/man/indic_raster.Rd @@ -7,11 +7,11 @@ indic_raster(rasPath, rasName, overlapArea, logger = NULL, spN = NULL) } \arguments{ -\item{rasPath}{character of path to rasters, must be the full path including +\item{rasPath}{character of path to raster, must be the full path including file name and extension.} -\item{rasName}{character vector of raster names to be assigned to loaded -rasters.} +\item{rasName}{character vector of raster name to be assigned to loaded +raster.} \item{overlapArea}{x. An sf object.} @@ -21,11 +21,43 @@ running in shiny, otherwise leave the default NULL.} \item{spN}{Species name} } +\value{ +A rasterlayer +} \description{ Upload user-specified SDM prediction } +\details{ +This function uploads a user-specified raster to be used in the calculate ratio +overlap module. It checks to make sure the raster intersects the overlapping object(an sf object; +a range map, EOO, AOO, masked map, etc) for calculating ratio overlap +} +\examples{ +\dontrun{ +#raster +rasPath <- system.file("extdata/Bassaricyon_neblina.tif",package = "wallace") +rasName <- "Bassaricyon_neblina.tif" +#overlapArea +rangeMap <- raster::raster(nrows=108, ncols=108, xmn=-79, xmx=-73) +raster::values(rangeMap)<- runif(n = (108*108)) +##convert to sf +rangeMap <- terra::rast(rangeMap) +rangeMap[rangeMap == 0] <- NA +rangeMap <- terra::as.polygons(rangeMap) +rangeMap <- sf::st_as_sf(rangeMap) + +# Run function +r <- indic_raster(rasPath, rasName, overlapArea = rangeMap, logger = NULL, spN = NULL) +} + +} +\seealso{ +\code{\link{indic_overlap}} +} \author{ Gonzalo E. Pinilla-Buitrago Jamie Kass + +Bethany A. Johnson } diff --git a/man/indic_time.Rd b/man/indic_time.Rd index 7d88e55fa..28580bdc0 100644 --- a/man/indic_time.Rd +++ b/man/indic_time.Rd @@ -7,11 +7,11 @@ indic_time(range, envs, thrh, bound, logger = NULL, spN = NULL) } \arguments{ -\item{range}{sf polygon. A polygon with the range map.} +\item{range}{sf polygon. A polygon with the range map. Extent must match envs.} -\item{envs}{rasterStack. Environmental variables.} +\item{envs}{rasterStack. Environmental variables. Extent must match range.} -\item{thrh}{interger. Threshold of where envs layers +\item{thrh}{integer. Threshold of where envs layers should be thresholded} \item{bound}{character. character string characterizing the way the threshold @@ -20,15 +20,53 @@ human footprint). "lower" removes values below the threshold (e.g., minimum forest cover). "neither" does not threshold at any point. "both" thresholds at both threshold values (if provided; e.g., minimum and maximum temperature).} -\item{logger}{logger} +\item{logger}{stores all notification messages to be displayed in the Log +Window of Wallace GUI. insert the logger reactive list here for running in +shiny, otherwise leave the default NULL} \item{spN}{species name} } +\value{ +a matrix array of the area calculations through time +} \description{ Calculate change in range area through time } +\details{ +This function calls on the changeRangeR::envchange() to calculate +the change in range area over time. It calculates the area of polygon of a +binary range, a masked range, EOO, or AOO, over time based on environmental +variables uploaded by the user and a selected threshold. The bounds of the +threshold are selected: "upper" removes values above the threshold (e.g., +maximum human footprint), "lower" removes values below the threshold (e.g., +minimum forest cover), "neither" does not threshold at any point, & finally +"both" thresholds at both threshold values (if provided; e.g., minimum and +maximum temperature). +} +\examples{ +\dontrun{ +### Set parameters +# rasterstack of envs +pathRast <- list.files(system.file("extdata/MODIS", package = "wallace"), pattern = ".tif$", full.names = TRUE) +envs <- raster::stack(pathRast) +# range map +range <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif",package = "wallace")) +# match projections +projected_range <- raster::projectRaster(range, envs, method = 'bilinear') +# threshold & bounds +thrh <- 20 +bound <- "lower" +### Run function +envChangeArea <- indic_time(projected_range, envs, thrh, bound, logger = NULL, spN = NULL) +} +} +\seealso{ +\code{\link[changeRangeR]{envChange}} +} \author{ Andrea Paz Gonzalo E. Pinilla-Buitrago + +Bethany A. Johnson } diff --git a/man/mask_expPoly.Rd b/man/mask_expPoly.Rd index 10c3d094a..b5d9bf87b 100644 --- a/man/mask_expPoly.Rd +++ b/man/mask_expPoly.Rd @@ -16,19 +16,46 @@ mask_expPoly( \arguments{ \item{polyMask}{Polygon in shapefile} -\item{prediction}{Raster prediction} +\item{prediction}{Raster prediction, of which to add/remove polyMask.} -\item{polyExt}{Polygon of background extent} +\item{polyExt}{Polygon of the prediction background extent} -\item{rem}{Remove areas of polygon from prediction} +\item{rem}{Remove areas of polygon from prediction or add them to prediction. (TRUE = remove, FALSE = add)} -\item{logger}{logger} +\item{logger}{stores all notification messages to be displayed in the Log +Window of Wallace GUI. insert the logger reactive list here for running in +shiny, otherwise leave the default NULL} \item{spN}{species name} } +\value{ +A list of two elements: the masked prediction and the extent +} \description{ Remove or add polygon to prediction } +\details{ +Mask a range prediction by removing or adding a polygon. The polygon +must fall partly within the extent of the prediction. If the prediction is +continuous, only remove polygon will work. +} +\examples{ +\dontrun{ +### Set parameters +# range prediction +prediction <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif", package = "wallace")) +# bg extent +polyExt <- terra::ext(prediction) +polyExt <- terra::as.polygons(polyExt) +polyExt <-sf::st_as_sf(polyExt) +#poly for masking +polyMask <- sf::st_read(system.file("extdata/wdpa/WDPA_COL_olinguito.shp", package = "wallace")) +### Run function +expertRast <- mask_expPoly(polyMask, prediction, polyExt, rem = TRUE, logger = NULL, spN = NULL) +} +} \author{ Gonzalo E. Pinilla-Buitrago + +Bethany A. Johnson } diff --git a/man/mask_spatialPoly.Rd b/man/mask_spatialPoly.Rd index 00daa26e5..607779eb5 100644 --- a/man/mask_spatialPoly.Rd +++ b/man/mask_spatialPoly.Rd @@ -7,26 +7,42 @@ mask_spatialPoly(bgShp_path, bgShp_name, sdm, logger = NULL, spN = NULL) } \arguments{ -\item{bgShp_path}{Path to the user provided shapefile} +\item{bgShp_path}{Path to the user-provided shapefile for masking} -\item{bgShp_name}{Name of the user porvided shapefile} +\item{bgShp_name}{Name of the user-provided shapefile for masking} -\item{sdm}{x} +\item{sdm}{A rasterlayer of a continuous or binary range prediction to be masked by shape} \item{logger}{stores all notification messages to be displayed in the Log Window of Wallace GUI. insert the logger reactive list here for running in shiny, otherwise leave the default NULL} -\item{spN}{x} +\item{spN}{character. Used to obtain species name for logger messages} } \value{ -x +A SpatialPolygonsDataFrame for masking } \description{ -x +Upload user-provided shapefile for masking } \details{ -x +This function provides a spatialpolygon from a shapefile for masking + a continuous or binary range prediction (sdm) based on the path and name of + a user-provided shapefile. The shapefile must fall within the extent of the + range prediction. Any part of the range prediction (sdm) outside of the polygon + will be removed ("masked" out). +} +\examples{ +\dontrun{ +### Set parameters +bgShp_path <- list.files(path = system.file("extdata/shp", package = "wallace"),full.names = TRUE) +bgShp_name <- list.files(path = system.file("extdata/shp", package = "wallace"),full.names = FALSE) +sdm <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif",package = "wallace")) +### Run function +spatialMask <- mask_spatialPoly(bgShp_path,bgShp_name,sdm,logger = NULL,spN = NULL) +} } \author{ Gonzalo E. Pinilla-Buitrago < gpinillabuitrago@gradcenter.cuny.edu> + +Bethany A. Johnson } diff --git a/man/mask_tempAnnotate.Rd b/man/mask_tempAnnotate.Rd index adff78859..cac7bcec1 100644 --- a/man/mask_tempAnnotate.Rd +++ b/man/mask_tempAnnotate.Rd @@ -7,17 +7,46 @@ mask_tempAnnotate(occs, env, envDates, logger = NULL) } \arguments{ -\item{occs}{Occurrences} +\item{occs}{Dataframe of occurrence/point data. Must include years} -\item{env}{Stack of raster} +\item{env}{Rasterstack of annual environmental data} -\item{envDates}{String with the years of rasters} +\item{envDates}{String with the years corresponding to the rasters} -\item{logger}{logger} +\item{logger}{Stores all notification messages to be displayed in the Log +Window of Wallace GUI. Insert the logger reactive list here for running in +shiny, otherwise leave the default NULL.} +} +\value{ +Numeric. Returns the quantiles } \description{ -Obtain temporal matched values +Obtain temporally matched values +} +\details{ +Annotate point data (e.g., occurrences) with raster values (e.g., +env data) based on matching years. Function returns the quantiles of values +for use in selecting a threshold value for masking. +} +\examples{ +\dontrun{ +### Set parameters +occs <- read.csv(system.file("extdata/Bassaricyon_alleni.csv", package = "wallace")) +# assigning dummy dates, but ideally the occ data would have years +dates <- sample(2000:2019,35, replace=T) +occs$year <- dates +env <- list.files(path = system.file('extdata/MODIS', package = "wallace"),full.names = TRUE) +env <- raster::stack(env) +envDates <- c(2005,2006,2008,2009,2010) +### Run function +bounds <- mask_tempAnnotate(occs, env, envDates, logger = NULL) +} +} +\seealso{ +\code{\link[maskRangeR]{annotate}}, \code{\link{mask_tempExtract}} } \author{ Gonzalo E. Pinilla-Buitrago + +Bethany A. Johnson } diff --git a/man/mask_tempExtract.Rd b/man/mask_tempExtract.Rd index 7432474ac..21e69e50e 100644 --- a/man/mask_tempExtract.Rd +++ b/man/mask_tempExtract.Rd @@ -14,21 +14,50 @@ mask_tempExtract( ) } \arguments{ -\item{lowerInp}{Lower bound value} +\item{lowerInp}{numeric. Lower bound value} -\item{upperInp}{Upper bound value} +\item{upperInp}{numeric. Upper bound value} -\item{maskRaster}{Masking raster} +\item{maskRaster}{RasterLayer. The masking raster} -\item{pred}{Prediction} +\item{pred}{RasterLayer. The range prediction to be masked} -\item{logger}{logger} +\item{logger}{stores all notification messages to be displayed in the Log +Window of Wallace GUI. insert the logger reactive list here for running in +shiny, otherwise leave the default NULL} -\item{spN}{Species name.} +\item{spN}{character. Used to obtain species name for logger messages} +} +\value{ +Returns a RasterLayer of the masked range prediction } \description{ To mask prediction by temporal thresholds. } +\details{ +Mask a range prediction (e.g., an SDM prediction) with an +environmental raster. Set the upper and lower bounds to remove areas +above/below those values in the masking raster from the prediction. The upper +and lower bounds can be determined from tempAnnotate. Anything area in the +masking raster with values below the lower bound and above the upper bound +will be removed from the range prediction. +} +\examples{ +\dontrun{ +### Set parameters +lowerInp <- 50 +upperInp <- 100 +maskRaster <- raster::raster(system.file("extdata/MODIS/2010_olinguito_Modis.tif", package = "wallace")) +pred <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif", package = "wallace")) +### Run function +postPred <- mask_tempExtract(lowerInp, upperInp, maskRaster, pred, logger = NULL, spN = NULL) +} +} +\seealso{ +\code{\link{mask_tempAnnotate}} +} \author{ Gonzalo E. Pinilla-Buitrago + +Bethany A. Johnson } diff --git a/man/mask_userSDM.Rd b/man/mask_userSDM.Rd index bb0fa024a..541ae5fbd 100644 --- a/man/mask_userSDM.Rd +++ b/man/mask_userSDM.Rd @@ -7,24 +7,44 @@ mask_userSDM(rasPath, rasName, logger = NULL, spN = NULL) } \arguments{ -\item{rasPath}{character of path to rasters, must be the full path including file name and extension. +\item{rasPath}{character of path to raster, must be the full path including file name and extension. Filename need to be name with genus_species format.} -\item{rasName}{character vector of raster names to be assigned to loaded rasters} +\item{rasName}{character vector of raster names to be assigned to loaded raster} \item{logger}{stores all notification messages to be displayed in the Log Window of Wallace GUI. insert the logger reactive list here for running in shiny, otherwise leave the default NULL} \item{spN}{Species name} } +\value{ +A list of two: the prediction rasterlayer and a spatialpolygon of the extent +} \description{ Upload user-specified SDM prediction } \details{ -See Examples. +This function uploads a raster of a species' range prediction to be +used in Wallace EcoMod. The file name needs to named in Genus_species format +(Ex: Bassaricyon_neblina.tif) to have Wallace functionality. The raster can +be binary or continuous, but may need to be binary for some further analyses +in Wallace. This function returns a list of the range prediction raster as +well as a spatial polygon of the extent of the range prediction. +} +\examples{ +\dontrun{ +### Set parameters +rasPath <- system.file("extdata/Bassaricyon_neblina.tif",package = "wallace") +rasName <- "Bassaricyon_neblina.tif" +### Run function +sdm <- mask_userSDM(rasPath, rasName, logger = NULL, spN = NULL) +} + } \author{ Gonzalo E. Pinilla-Buitrago Jamie Kass + +Bethany A. Johnson } diff --git a/man/occs_biomodelos.Rd b/man/occs_biomodelos.Rd index 5b4e35fb4..c11b94fba 100644 --- a/man/occs_biomodelos.Rd +++ b/man/occs_biomodelos.Rd @@ -25,8 +25,19 @@ This function is called by the module occs_biomodelos to query the BioModelos da species occurrence records. It removes records with duplicate coordinates, and select some columns with fields appropriate to studies in biogeography. } +\examples{ +\dontrun{ +### Set parameters +spN <- "Bassaricyon neblina" +bioKey <- 12345 +### Run function +occs <- occs_biomodelos(spN, bioKey, logger = NULL) +} +} \author{ Gonzalo E. Pinilla-Buitrago < gpinillabuitrago@gradcenter.cuny.edu> -Peter Ersts? +Bethany A. Johnson + +Peter Ersts } diff --git a/tests/testthat/extdata/wc/proj/no_projection.tif b/tests/testthat/extdata/wc/proj/no_projection.tif deleted file mode 100644 index b57937f6d..000000000 Binary files a/tests/testthat/extdata/wc/proj/no_projection.tif and /dev/null differ diff --git a/tests/testthat/test_envs_userEnvs.R b/tests/testthat/test_envs_userEnvs.R index f1c1efb7d..8e434c37c 100755 --- a/tests/testthat/test_envs_userEnvs.R +++ b/tests/testthat/test_envs_userEnvs.R @@ -39,6 +39,7 @@ userEnvs_stack <- envs_userEnvs(rasPath = Path, rasName = Name, # fixed = TRUE) # }) # BAJ (2024-02-14) rgdal has been retired and removed. this test may be added back? +# BAJ (2024-08-07): I deleted no_projection.tif ### test output features test_that("output type checks", { diff --git a/tests/testthat/test_indic_aoo.R b/tests/testthat/test_indic_aoo.R new file mode 100644 index 000000000..f8e90151c --- /dev/null +++ b/tests/testthat/test_indic_aoo.R @@ -0,0 +1,97 @@ +#### COMPONENT indic: Calculate Indicators +#### MODULE: Calculate Area Metrics +context("aoo") + +### Set parameters +# binary raster +r <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif", + package = "wallace")) +# occurrences +occs <- read.csv(system.file("extdata/Bassaricyon_neblina.csv", + package = "wallace")) + +### Run function +# aoo from raster +aoo_r <- indic_aoo(r, + occs = NULL, + lon = NULL, + lat = NULL, + wktFrom = getWKT("wgs84"), + wktTo = getWKT("wcea"), + logger = NULL) +# aoo from occs +aoo_occs <- indic_aoo(r <- NULL, + occs, + lon = "longitude", + lat = "latitude", + wktFrom = getWKT("wgs84"), + wktTo = getWKT("wcea"), + logger = NULL) + + +################ tests #################################### +### test if the error messages appear when they are supposed to +test_that("error checks", { + # lat and lon are not set + expect_error(indic_aoo(r <- NULL, + occs, + #lon = "longitude", + #lat = "latitude", + wktFrom = getWKT("wgs84"), + wktTo = getWKT("wcea"), + logger = NULL), + paste0('No longitude and/or latitude name provided.')) + + # lat and lon are set, but not correctly + expect_error(indic_aoo(r <- NULL, + occs, + lon = "lon", + lat = "lat", + wktFrom = getWKT("wgs84"), + wktTo = getWKT("wcea"), + logger = NULL), + paste0('Longitude and/or latitude names not found.')) + + # both r and occs are null + expect_error(indic_aoo(r <- NULL, + occs <- NULL, + lon = "longitude", + lat = "latitude", + wktFrom = getWKT("wgs84"), + wktTo = getWKT("wcea"), + logger = NULL), + paste0('Provide occurrences or raster.')) + }) + +### test if the warning messages appear when they are supposed to +# test_that("warnings checks", { +# # user's input does not have coordinates +# expect_warning( +# indic_aoo(), +# paste0("")) +# }) + + +### test output features +test_that("output checks", { + # output is a list + expect_is(aoo_r, "list") + expect_is(aoo_occs, "list") + # the list has two elements + expect_equal(length(aoo_r), 2) + expect_equal(length(aoo_occs),2) + # the elements "area" and "AOOraster" + expect_equal(c("area", "AOOraster"), names(aoo_r)) + expect_equal(c("area", "AOOraster"), names(aoo_occs)) + # element within the output list are: + # numeric + expect_is(aoo_r$area, "numeric") + expect_is(aoo_occs$area, "numeric") + # a RasterLayer + expect_is(aoo_r$AOOraster, "RasterLayer") + expect_is(aoo_occs$AOOraster, "RasterLayer") +}) + +### test function steps + + diff --git a/tests/testthat/test_indic_area.R b/tests/testthat/test_indic_area.R new file mode 100644 index 000000000..0cbf0b28f --- /dev/null +++ b/tests/testthat/test_indic_area.R @@ -0,0 +1,28 @@ +#### COMPONENT indic: Calculate Indicators +#### MODULE: Calculate Area Metrics +context("area") + +### Set parameters +# binary raster +r <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif",package = "wallace")) +# set wkt to wcea +wkt <- getWKT("wcea") #wcea + +### Run function +areaRange <- indic_area(r, wkt, logger = NULL) + +################ Tests #################################### + +### test if the error messages appear when they are supposed to +# No error messages + +### test if the warning messages appear when they are supposed to +# No warning messages + +### test output features +test_that("output checks", { + # numeric + expect_is(areaRange, "numeric") +}) + +### test function steps diff --git a/tests/testthat/test_indic_eoo.R b/tests/testthat/test_indic_eoo.R new file mode 100644 index 000000000..ede1363fa --- /dev/null +++ b/tests/testthat/test_indic_eoo.R @@ -0,0 +1,54 @@ +#### COMPONENT indic: Calculate Indicators +#### MODULE: Calculate Area Metrics +context("eoo") + +### Set parameters +# binary raster +r <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif", + package = "wallace")) +# occurrences +occs <- read.csv(system.file("extdata/Bassaricyon_neblina.csv", + package = "wallace")) +# wcea +wkt <- getWKT("wcea") + + +### Run function +eoo_r <- indic_eoo(r, occs = NULL, lon = NULL, lat = NULL, wkt, logger = NULL) +eoo_o <- indic_eoo(r = NULL, occs, lon = "longitude", lat = "latitude", wkt, logger = NULL) + +################ Tests #################################### +### test if the error messages appear when they are supposed to +test_that("error checks", { + # when using occs, but lon and lat are not set + expect_error(indic_eoo(r = NULL, occs, lon = NULL, lat = NULL, wkt, logger = NULL), + "No longitude and/or latitude name provided.") + # when using occs, lon and lat are set but do not match + expect_error(indic_eoo(r = NULL, occs, lon = "lon", lat = "lat", wkt, logger = NULL), + "Longitude and/or latitude names not found.") + # r and occs both null + expect_error(indic_eoo(r = NULL, occs = NULL, lon = NULL, lat = NULL, wkt, logger = NULL), + "Provide occurrences or raster.") + }) + +### test if the warning messages appear when they are supposed to +# No warning messages + +### test output features +test_that("output checks", { + # the output is a list + expect_is(eoo_r, "list") + expect_is(eoo_o, "list") + # the list has two elements + expect_equal(length(eoo_r), 2) + expect_equal(length(eoo_o), 2) + # the elements are: + ## numeric + expect_is(eoo_r$area, "numeric") + expect_is(eoo_o$area, "numeric") + ## spatialpolygon + expect_is(eoo_r$eooPoly, "SpatialPolygons") + expect_is(eoo_o$eooPoly, "SpatialPolygons") +}) + +### test function steps diff --git a/tests/testthat/test_indic_inputPoly.R b/tests/testthat/test_indic_inputPoly.R new file mode 100644 index 000000000..7a0604ae1 --- /dev/null +++ b/tests/testthat/test_indic_inputPoly.R @@ -0,0 +1,98 @@ +#### COMPONENT indic: Calculate Indicators +#### MODULE: Calculate Ratio Overlap +context("inputPoly") + +### Set parameters +# Overlap polygon +ovShp_path <- list.files(path = system.file("extdata/wdpa", package = "wallace"), full.names = TRUE) +ovShp_name <- list.files(path = system.file("extdata/wdpa", package = "wallace"), full.names = FALSE) + +# Source polygon +overlapRange <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif", package = "wallace")) +overlapRange[overlapRange == 0] <- NA +overlapRange <- terra::as.polygons(overlapRange) +overlapRange <- sf::st_as_sf(overlapRange) + +# Run function +suppressWarnings(polyData <- indic_inputPoly(ovShp_path, ovShp_name, overlapRange, logger = NULL, spN = NULL)) +# warning msg suppressed: Projection not found for shapefile. It is assumed that shapefile datum is WGS84. + +# generate wrong parameters (to test error messages) +## shp file error +ovShp_error <- "Bassaricyon_neblina.prj" + +## shapefile that doesn't overlap +overlap_OutofRange <- raster::raster(nrows=108, ncols=108, xmn=-29, xmx=-23) +raster::values(overlap_OutofRange)<- runif(n = (108*108)) +overlap_OutofRange <- terra::rast(overlap_OutofRange) +overlap_OutofRange[overlap_OutofRange == 0] <- NA +overlap_OutofRange <- terra::as.polygons(overlap_OutofRange) +overlap_OutofRange <- sf::st_as_sf(overlap_OutofRange) + +## shapefile with crs not wgs84 +### add a shape not in 4326 to test + + +################ Tests #################################### + +### test if the error messages appear when they are supposed to + test_that("error checks", { + # .shp, .shx, or .dbf missing + expect_error(indic_inputPoly(ovShp_path[1:2], + ovShp_name[1:2], + overlapRange, + logger = NULL, + spN = NULL), + paste0("If entering a shapefile, please select all the following files: .shp, .shx, .dbf.")) + + # shapefile not entered + expect_error(indic_inputPoly(ovShp_path, + ovShp_error, + overlapArea, + logger = NULL, + spN = NULL), + fixed = TRUE, + "Please enter shapefile (.shp, .shx, .dbf)." + ) + + # Shapefile does not intersect the area to overlap. + expect_error(suppressWarnings(indic_inputPoly(ovShp_path, + ovShp_name, + overlap_OutofRange, + logger = NULL, + spN = NULL)), + paste0("Shapefile does not intersect the area to overlap. Please specify a new polygon.") + ) + # warning about shapefile projection suppressed, unless there is a way to expect error AND warning? + }) + +### test if the warning messages appear when they are supposed to + test_that("warnings checks", { + ## shapefile has no projection + expect_warning(indic_inputPoly(ovShp_path, ovShp_name, overlapRange, logger = NULL, spN = NULL), + paste0("Projection not found for shapefile. It is assumed that shapefile datum is WGS84.") + ) + + ## shapefile projection is not WGS84 +# ###sf::st_crs(polyData)$input != "EPSG:4326") +# expect_warning(indic_inputPoly(), +# paste0("Original coordinate reference system (CRS) is not WGS84 (EPSG:4326). ", +# "Shapefile was reprojected to this CRS.")) + #BAJ 09/17/2024: need to add a shape not in 4326 to add this test. +# + }) + + +### test output features +test_that("output checks", { + # sf object + expect_is(polyData, "sf") + # list of 6 + expect_equal(length(polyData),6) + # the names are correct + expect_equal(names(polyData), c("NAME", "ORIG_NAME", "DESIG", "DESIG_ENG", "DESIG_TYPE", "geometry")) + # overlap values > 0 + expect_equal(sum(lengths(sf::st_intersects(polyData, overlapRange))), 584) +}) + +### test function steps diff --git a/tests/testthat/test_indic_overlap.R b/tests/testthat/test_indic_overlap.R new file mode 100644 index 000000000..2650cb61b --- /dev/null +++ b/tests/testthat/test_indic_overlap.R @@ -0,0 +1,87 @@ +#### COMPONENT indic: Calculate Indicators +#### MODULE: Calculate Ratio Overlap +context("overlap") + +### Set parameters +# range map +rangeMap <- terra::rast(system.file("extdata/Bassaricyon_neblina.tif", package = "wallace")) +rangeMap[rangeMap == 0] <- NA +rangeMap <- terra::as.polygons(rangeMap) +rangeMap <- sf::st_as_sf(rangeMap) + +# input overlap obj +## raster +inputRaster <- raster::raster(nrows=108, ncols=108, xmn=-80, xmx=-75) +raster::values(inputRaster)<- runif(n = (108*108)) + +## shapefile +###BAJ testing with shapefile is commented because of a bug in cRR & test failing +ovShp_path <- list.files(path = system.file("extdata/wdpa", package = "wallace"), full.names = TRUE) +ovShp_name <- list.files(path = system.file("extdata/wdpa", package = "wallace"), full.names = FALSE) +suppressWarnings(inputPoly <- indic_inputPoly(ovShp_path, ovShp_name, + overlapRange = rangeMap, + logger = NULL, spN = NULL)) +#field +# NULL if inputOverlap is a raster +fields <- names(inputPoly) +fields <- fields[!(fields %in% "geometry")] +fields <- setNames(as.list(fields), fields) +overlapF <- fields$DESIG_ENG + +#category +## NULL if inputOverlap is a raster +category <- unique(inputPoly$DESIG_ENG) +category <- setNames(as.list(category), category) +overlapC <- category$`Regional Natural Parks` + + +### Run function +# for raster +overlap_r <- indic_overlap(rangeMap, + inputOverlap = inputRaster, + field = NULL, + category = NULL, + logger = NULL, + spN = NULL) + + +# for shapefile +suppressWarnings(overlap_shp <- indic_overlap(rangeMap, + inputOverlap = inputPoly, + field = overlapF, + category = overlapC, + logger = NULL, spN = NULL)) +# warning message suppressed: attribute variables are assumed to be spatially constant throughout all geometries + +################ Tests #################################### + +### test if the error messages appear when they are supposed to +# No error messages + +### test if the warning messages appear when they are supposed to +# No warning messages +#attribute variables are assumed to be spatially constant throughout all geometries + +### test output features +test_that("output checks", { + # list + expect_is(overlap_r, "list") + expect_is(overlap_shp, "list") + # list of 2 + expect_equal(2, length(overlap_r)) + expect_equal(2, length(overlap_shp)) + # list names + expect_equal(names(overlap_r), c("overlapPolygon", "overlapRatio")) + expect_equal(names(overlap_shp), c("overlapPolygon", "overlapRatio")) + # overlapPolygon + expect_is(overlap_r$overlapPolygon, "sfc_MULTIPOLYGON") + expect_is(overlap_shp$overlapPolygon, "sfc_MULTIPOLYGON") + #overlap ratio + expect_is(overlap_r$overlapRatio, "matrix") + expect_is(overlap_shp$overlapRatio, "character") + #length of 4 or 1 + expect_equal(4, length(overlap_r$overlapRatio)) + expect_equal(1, length(overlap_shp$overlapRatio)) +}) + +### test function steps diff --git a/tests/testthat/test_indic_raster.R b/tests/testthat/test_indic_raster.R new file mode 100644 index 000000000..8402df977 --- /dev/null +++ b/tests/testthat/test_indic_raster.R @@ -0,0 +1,69 @@ +#### COMPONENT indic: Calculate Indicators +#### MODULE: Calculate Ratio Overlap +context("raster") + +### Set parameters +#rasPath +rasPath <- system.file("extdata/Bassaricyon_neblina.tif", + package = "wallace") +#rasName +rasName <- "Bassaricyon_neblina.tif" + +#overlapArea +rangeMap <- raster::raster(nrows=108, ncols=108, xmn=-79, xmx=-73) +raster::values(rangeMap)<- runif(n = (108*108)) +##convert to sf object +rangeMap <- terra::rast(rangeMap) +rangeMap[rangeMap == 0] <- NA +rangeMap <- terra::as.polygons(rangeMap) +rangeMap <- sf::st_as_sf(rangeMap) + +### Run function +r <- indic_raster(rasPath, + rasName, + overlapArea = rangeMap, + logger = NULL, + spN = NULL) + +### for error checks +#overlapArea ERROR +rangeFAIL <- raster::raster(nrows=108, ncols=108, xmn=-50, xmx=50) +raster::values(rangeFAIL)<- runif(n = (108*108)) +rangeFAIL <- terra::rast(rangeFAIL) +rangeFAIL[rangeFAIL == 0] <- NA +rangeFAIL <- terra::as.polygons(rangeFAIL) +rangeFAIL <- sf::st_as_sf(rangeFAIL) +#wrong crs +rasPathFAIL <- system.file("extdata/B_neblina_WCEA.tif", + package = "wallace") + +################ Tests #################################### + +### test if the error messages appear when they are supposed to +test_that("error checks", { + # if the raster is in the wrong projection + expect_error(indic_raster(rasPathFAIL, + rasName, + overlapArea = rangeMap, + logger = NULL, spN = NULL), + "Wrong extent projection. 'Bassaricyon_neblina' cannot be uploaded.") + + # do not intersect + expect_error(indic_raster(rasPath, + rasName, + overlapArea = rangeFAIL, + logger = NULL, + spN = NULL), + "Overlap raster does not match with range map extent. Please specify a new raster.") +}) + +### test if the warning messages appear when they are supposed to +# No warning messages + +### test output features +test_that("output checks", { + # r is a rasterlayer + expect_is(r, "RasterLayer") +}) + +### test function steps diff --git a/tests/testthat/test_indic_time.R b/tests/testthat/test_indic_time.R new file mode 100644 index 000000000..b91d42d2d --- /dev/null +++ b/tests/testthat/test_indic_time.R @@ -0,0 +1,43 @@ +#### COMPONENT indic: Calculate Indicators +#### MODULE: Calculate Change Over Time +context("indic_time") + +### Set parameters +# rasterstack of envs +pathRast <- list.files(system.file("extdata/MODIS", package = "wallace"), + pattern = ".tif$", full.names = TRUE) +envs <- raster::stack(pathRast) + +# range map +range <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif", + package = "wallace")) +# match projections +projected_range <- raster::projectRaster(range, envs, method = 'bilinear') +# alternative- see note from BAJ in indic_time.R from 9/25/2024. +#projected_envs <- raster::projectRaster(envs, range, method = 'bilinear') + +# threshold & bounds +thrh <- 20 +bound <- "lower" + +### Run function +envChangeArea <- indic_time(projected_range, envs, thrh, bound, + logger = NULL, spN = NULL) + +################ Tests #################################### + +### test if the error messages appear when they are supposed to +# No error messages + +### test if the warning messages appear when they are supposed to +# No warning messages + +### test output features +test_that("output checks", { + # matrix array + expect_is(envChangeArea, "matrix") + # length of 5 + expect_equal(length(envChangeArea), 5) +}) + +### test function steps diff --git a/tests/testthat/test_mask_expPoly.R b/tests/testthat/test_mask_expPoly.R new file mode 100644 index 000000000..2eed2ae3b --- /dev/null +++ b/tests/testthat/test_mask_expPoly.R @@ -0,0 +1,64 @@ +#### COMPONENT mask: Mask Prediction +#### MODULE: Mask by Drawn Polygon +context("expPoly") + +### Set parameters +# range prediction +prediction <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif", + package = "wallace")) +# bg extent +polyExt <- terra::ext(prediction) +polyExt <- terra::as.polygons(polyExt) +polyExt <-sf::st_as_sf(polyExt) +#poly for masking +polyMask <- sf::st_read(system.file("extdata/wdpa/WDPA_COL_olinguito.shp", + package = "wallace")) + +### Run function +suppressWarnings(expertRast <- mask_expPoly(polyMask, prediction, polyExt, + rem = TRUE, logger = NULL, spN = NULL)) + +### for tests +# nonoverlapping extent +badprediction <- raster::raster(nrows=108, ncols=108, xmn=-85, xmx=-80) +raster::values(badprediction)<- runif(n = (108*108)) + +################ Tests #################################### + +### test if the error messages appear when they are supposed to +test_that("error checks", { + # extents do not overlap + expect_error(mask_expPoly(polyMask, badprediction, polyExt, + rem = TRUE, logger = NULL, spN = NULL), + paste("The polygon only included NA values.", + "Please select a polygon that intersects the model prediction. ") + ) + }) + +## test if the warning messages appear when they are supposed to +#contains NA values +test_that("warnings checks", { + expect_warning(mask_expPoly(polyMask, prediction, polyExt, + rem = TRUE, logger = NULL, spN = NULL), + paste0("The polygon selected includes some cells with NA values. You cannot change the prediction (suitable or unsuitable) in these cells. "), + fixed = TRUE) + }) + +### test output features +test_that("output checks", { + # list + expect_is(expertRast, "list") + # list of two + expect_equal(length(expertRast), 2) + # pred & ext + expect_equal(names(expertRast), c("pred", "ext")) + # pred should be a rasterlayer + expect_is(expertRast$pred, "RasterLayer") + # ext should be a... + expect_is(expertRast$ext, "data.frame") + # it should be an sf dataframe that includes the sfc_polygon of the bg extent + # the extents should be the same + expect_equal(raster::extent(polyExt), raster::extent(expertRast$ext)) +}) + +### test function steps diff --git a/tests/testthat/test_mask_spatialPoly.R b/tests/testthat/test_mask_spatialPoly.R new file mode 100644 index 000000000..33f82f960 --- /dev/null +++ b/tests/testthat/test_mask_spatialPoly.R @@ -0,0 +1,112 @@ +#### COMPONENT mask: Mask Prediction +#### MODULE: Mask by Shapefile +context("spatialPoly") + +### Set parameters +bgShp_path <- list.files(path = system.file("extdata/shp", package = "wallace"), + full.names = TRUE) +bgShp_name <- list.files(path = system.file("extdata/shp", package = "wallace"), + full.names = FALSE) +sdm <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif", + package = "wallace")) + +### Run function +suppressWarnings(spatialMask <- mask_spatialPoly(bgShp_path, bgShp_name, sdm, + logger = NULL,spN = NULL)) + +# error messages +bgShp_path_error <- list.files(path = system.file("extdata/wdpa", package = "wallace"), + full.names = TRUE) +bgShp_name_error <- list.files(path = system.file("extdata/wdpa", package = "wallace"), + full.names = FALSE) +sdm_error <- raster::raster(nrows=108, ncols=108, xmn=-50, xmx=50) +raster::values(sdm_error)<- runif(n = (108*108)) + +################ Tests #################################### + +### test if the error messages appear when they are supposed to +test_that("error checks", { + + # didnt include all files; .shp, .shx, or .dbf missing + expect_error(mask_spatialPoly(bgShp_path[1:2], + bgShp_name[1:2], + sdm, + logger = NULL, + spN = NULL), + paste0('If entering a shapefile, please select all the ', + 'following files: .shp, .shx, .dbf.')) + + # file wasn't a shapefile + expect_error(mask_spatialPoly(bgShp_path[1:1], + bgShp_name[1:1], + sdm, + logger = NULL, + spN = NULL), + paste0("Please enter shapefile: .shp, .shx, & .dbf.")) + + # shapefile doesnt intersect sdm + expect_error(suppressWarnings(mask_spatialPoly(bgShp_path_error, + bgShp_name_error, + sdm, + logger = NULL, + spN = NULL)), + paste0("Shapefile must fall within the SDM extent. Please specify a new polygon. ")) + + # the shapefile intersects, but only for NA values + expect_error(suppressWarnings(mask_spatialPoly(bgShp_path, + bgShp_name, + sdm_error, + logger = NULL, + spN = NULL)), + paste("Shapefile must fall within the SDM extent. Please specify a new polygon.")) +}) + +### test if the warning messages appear when they are supposed to +test_that("warnings checks", { + + # no crs + expect_warning(mask_spatialPoly(bgShp_path, + bgShp_name, + sdm, + logger = NULL, + spN = NULL), + paste0("Projection not found for shapefile. It is assumed that shapefile datum ", + "is WGS84. ")) + + # includes NA values + expect_warning(mask_spatialPoly(bgShp_path, + bgShp_name, + sdm, + logger = NULL, + spN = NULL), + paste0("Projection not found for shapefile. It is assumed that shapefile datum ", + "is WGS84. "), + paste0("The polygon selected included some cells with NA values.", + "You cannot change the predictions (suitable or unsuitable),", + "in these cells. ")) + + # warning from sf pkg + expect_warning(mask_spatialPoly(bgShp_path, + bgShp_name, + sdm, + logger = NULL, + spN = NULL), + paste0("Projection not found for shapefile. It is assumed that shapefile datum ", + "is WGS84. "), + paste0("The polygon selected included some cells with NA values.", + "You cannot change the predictions (suitable or unsuitable),", + "in these cells. "), + paste0("attribute variables are assumed to be spatially constant throughout all geometries ") + ) + +}) + +### test output features +test_that("output checks", { + # spatial poly + expect_is(spatialMask, "SpatialPolygonsDataFrame") + # crs set to wgs84/to match sdm + expect_equal(raster::crs(sdm), raster::crs(spatialMask)) +}) + +### test function steps diff --git a/tests/testthat/test_mask_tempAnnotate.R b/tests/testthat/test_mask_tempAnnotate.R new file mode 100644 index 000000000..f485fb72e --- /dev/null +++ b/tests/testthat/test_mask_tempAnnotate.R @@ -0,0 +1,37 @@ +#### COMPONENT mask: Mask Prediction +#### MODULE: Temporal +context("tempAnnotate") + +### Set parameters +occs <- read.csv(system.file("extdata/Bassaricyon_alleni.csv", + package = "wallace")) +# assigning dummy dates, but ideally the occ data would have years +#BAJ 10/4/2024: replace Bassaricyon_alleni.csv with one that includes dates & remove this +dates <- sample(2000:2019,35, replace=T) +occs$year <- dates + +env <- list.files(path = system.file('extdata/MODIS', package = "wallace"), + full.names = TRUE) +env <- raster::stack(env) + +envDates <- c(2005,2006,2008,2009,2010) +### Run function +bounds <- mask_tempAnnotate(occs, env, envDates, logger = NULL) + +################ Tests #################################### + +### test if the error messages appear when they are supposed to +# No error messages + +### test if the warning messages appear when they are supposed to +# No warning messages + +### test output features +test_that("output checks", { + # numeric + expect_is(bounds, "numeric") + # quantiled are correctly set + expect_equal(names(bounds), c("0%", "2.5%", "25%", "50%", "75%", "97.5%", "100%")) +}) + +### test function steps diff --git a/tests/testthat/test_mask_tempExtract.R b/tests/testthat/test_mask_tempExtract.R new file mode 100644 index 000000000..96b41e597 --- /dev/null +++ b/tests/testthat/test_mask_tempExtract.R @@ -0,0 +1,55 @@ +#### COMPONENT mask: Mask Prediction +#### MODULE: Calculate Change Over Time +context("tempExtract") + +### Set parameters +lowerInp <- 50 +upperInp <- 100 +maskRaster <- raster::raster(system.file("extdata/MODIS/2010_olinguito_Modis.tif", + package = "wallace")) +pred <- raster::raster(system.file("extdata/Bassaricyon_neblina.tif", + package = "wallace")) +### Run function +postPred <- mask_tempExtract(lowerInp, upperInp, + maskRaster, pred, + logger = NULL, spN = NULL) + +### for testing errors & warnings +lowerInp_na <- NA +upperInp_na <- NA +wkt <- getWKT("wcea") +mask_wrong <- terra::project(terra::rast(maskRaster), wkt) +pred <- terra::rast(pred) +mask_wrong <- raster::raster(mask_wrong) + +################ Tests #################################### + +### test if the error messages appear when they are supposed to +test_that("error checks", { + # Please provide bounds for masking. + expect_error(mask_tempExtract(lowerInp_na, upperInp_na, maskRaster, + pred, logger = NULL, spN = NULL), + paste0("Please provide bounds for masking. ")) +}) + + +### test if the warning messages appear when they are supposed to +test_that("warnings checks", { + # Rasters don't have the same resolution, CRS, or origin. + expect_warning(mask_tempExtract(lowerInp, upperInp,mask_wrong, + pred,logger = NULL, spN = NULL), + paste0("Rasters don't have the same resolution, CRS, and/or origin. ")) +}) + + +### test output features +test_that("output checks", { + # numeric + expect_is(postPred, "RasterLayer") + # length 164920 + expect_equal(length(postPred), 164920) + # 1 layer + expect_equal(raster::nlayers(postPred), 1) +}) + +### test function steps diff --git a/tests/testthat/test_mask_userSDM.R b/tests/testthat/test_mask_userSDM.R new file mode 100644 index 000000000..6d32d18f8 --- /dev/null +++ b/tests/testthat/test_mask_userSDM.R @@ -0,0 +1,51 @@ +#### COMPONENT mask: Calculate Indicators +#### MODULE: Upload user-specified SDM prediction +context("userSDM") + +### Set parameters +rasPath <- system.file("extdata/Bassaricyon_neblina.tif",package = "wallace") +rasName <- "Bassaricyon_neblina.tif" + +### Run function +sdm <- mask_userSDM(rasPath, rasName, logger = NULL, spN = NULL) + +# to test errors +rasPath_error <- system.file("extdata/B_neblina_WCEA.tif",package = "wallace") +#rasPath_error2 <- system.file("something with the wrong extent. see note below") + +################ Tests #################################### + +### test if the error messages appear when they are supposed to +test_that("error checks", { + # unspecified CRS + expect_error(mask_userSDM(rasPath_error, rasName, logger = NULL, spN = NULL), + paste0("Input rasters have undefined coordinate reference system (CRS). Mapping functionality will not work. Please define their projections and upload again. See guidance text in this module for more details."), + fixed = TRUE) + + # extents do not overlap + # BAJ 10/10/2024: need to upload a raster with xmax > 180 and xmin < -180 to get this error + # expect_error(mask_userSDM(rasPath_error2, rasName, logger = NULL, spN = NULL), + # paste0("Wrong extent projection. '", rasName,"' cannot be uploaded. ")) +}) + + +### test if the warning messages appear when they are supposed to +# No warning messages + +### test output features +test_that("output checks", { + # list + expect_is(sdm, "list") + # list of 2 + expect_equal(length(sdm),2) + # two items should be sdm$sdm & sdm$extSdm + expect_equal(names(sdm), c("sdm", "extSdm")) + # sdm$sdm should be a rasterlayer + expect_is(sdm$sdm, "RasterLayer") + # sdm$extSdm should be a spatialpolygon + expect_is(sdm$extSdm, "SpatialPolygons") + # same extents + expect_equal(raster::extent(sdm$sdm), raster::extent(sdm$extSdm)) +}) + +### test function steps diff --git a/tests/testthat/test_occs_biomodelos.R b/tests/testthat/test_occs_biomodelos.R new file mode 100644 index 000000000..0fd99a6d5 --- /dev/null +++ b/tests/testthat/test_occs_biomodelos.R @@ -0,0 +1,49 @@ +# #### COMPONENT occs: Obtain Occurrence Data +# #### MODULE: Query BioModelos Database +# context("biomodelos") +# +# ### Set parameters +# spN <- "Bassaricyon neblina" +# bioKey <- 12345 +# +# ### Run function +# occs <- occs_biomodelos(spN, bioKey, logger = NULL) +# +# ### for error tests +# spN_error <- c("Bassaricyon neblina", "Bassaricyon alleni") +# spN_error2 <- "Neblina bassaricyon" +# spN_error3 <- "species" +# +# ################ Tests #################################### +# +# ### test if the error messages appear when they are supposed to +# test_that("error checks", { +# # More than one species entered +# expect_error(occs_biomodelos(spN_error, bioKey, logger = NULL), +# 'Please input both genus and species names of ONE species. ') +# # trycatch error +# #"Unable to retrieve data from BioModelos. Server may be down. " +# # Species name not found +# # this test won't trigger the correct error msg without a working api key +# # expect_error(occs_biomodelos(spN_error2, bioKey, logger = NULL), +# # 'Species name not found, please check the spelling. ') +# # No records on BioModelos +# # this test won't trigger the correct error msg without a working api key +# # expect_error(occs_biomodelos(spN_error3, bioKey, logger = NULL), +# # 'Species without records on BioModelos. ') +# # API key is not working. +# expect_error(occs_biomodelos(spN, bioKey, logger = NULL), +# 'API key is not working.') +# }) +# +# ### test if the warning messages appear when they are supposed to +# # No warning messages +# +# ### test output features +# #output will not work without functional bioKey (BioModelos API key) +# # test_that("output checks", { +# # # numeric +# # expect_is(occs, "list") +# # }) +# +# ### test function steps