Skip to content

Commit

Permalink
Merge pull request #97 from sigmafelix/0.8.0
Browse files Browse the repository at this point in the history
0.8.0
  • Loading branch information
kyle-messier authored Sep 4, 2024
2 parents 683e7f5 + ac99f3b commit b85fc25
Show file tree
Hide file tree
Showing 27 changed files with 1,096 additions and 363 deletions.
7 changes: 0 additions & 7 deletions .github/workflows/test-coverage-local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,3 @@ jobs:
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}

# - name: Upload artifacts
# if: always()
# uses: actions/upload-artifact@v4
# with:
# name: test-outputs
# path: ${{ github.workspace }}/**
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: chopin
Title: Computation of Spatial Data by Hierarchical and Objective Partitioning of Inputs for Parallel Processing
Version: 0.7.8.20240817
Version: 0.8.0.20240903
Authors@R: c(
person("Insang", "Song", , "geoissong@gmail.com", role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-8732-3256")),
Expand Down
124 changes: 69 additions & 55 deletions R/check.R
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,15 @@ setMethod(

}

#' Check package name for outcome class definition
#' @keywords internal
#' @noRd
.check_pkgname <- function(out) {
if (!out %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
}



## .check_vector ####
Expand Down Expand Up @@ -584,9 +593,7 @@ setMethod(
signature(input = "character", input_id = "ANY",
extent = "NULL", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

cli::cli_inform(
c("i" =
Expand Down Expand Up @@ -622,9 +629,7 @@ setMethod(
signature(input = "character", input_id = "ANY",
extent = "numeric", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

cli::cli_inform(
c("i" =
Expand Down Expand Up @@ -659,9 +664,7 @@ setMethod(
signature(input = "character", input_id = "ANY",
extent = "sf", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra.\n"))
}
.check_pkgname(out = out_class)

cli::cli_inform(
c("i" =
Expand Down Expand Up @@ -696,9 +699,7 @@ setMethod(
signature(input = "character", input_id = "ANY",
extent = "SpatVector", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

cli::cli_inform(
c("i" =
Expand Down Expand Up @@ -734,9 +735,7 @@ setMethod(
signature(input = "character", input_id = "ANY",
extent = "SpatExtent", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

cli::cli_inform(
c("i" =
Expand Down Expand Up @@ -770,9 +769,7 @@ setMethod(
signature(input = "sf", input_id = "ANY",
extent = "NULL", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)
input <- .check_id(input, input_id)

if (out_class == "terra") {
Expand Down Expand Up @@ -805,12 +802,12 @@ setMethod(
signature(input = "sf", input_id = "ANY",
extent = "numeric", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

input <- .check_id(input, input_id)

if (out_class == "terra") {
input <- terra::vect(input)
extent <- terra::ext(extent)
input <- input[extent, ]
}
Expand All @@ -836,9 +833,8 @@ setMethod(
signature(input = "sf", input_id = "ANY",
extent = "SpatExtent", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

input <- .check_id(input, input_id)

if (out_class == "sf") {
Expand All @@ -865,9 +861,8 @@ setMethod(
signature(input = "sf", input_id = "ANY",
extent = "sf", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

input <- .check_id(input, input_id)

if (!terra::same.crs(terra::crs(input), terra::crs(extent))) {
Expand All @@ -892,17 +887,16 @@ setMethod(
signature(input = "sf", input_id = "ANY",
extent = "SpatVector", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

input <- .check_id(input, input_id)

if (!is.null(extent)) {
if (!terra::same.crs(terra::crs(input), terra::crs(extent))) {
extent <- reproject_std(extent, terra::crs(input))
}
input <- input[extent, ]
if (!terra::same.crs(terra::crs(input), terra::crs(extent))) {
extent <- reproject_std(extent, terra::crs(input))
}
extent <- sf::st_as_sf(extent)
input <- input[extent, ]

if (out_class == "terra") {
input <- terra::vect(input)
}
Expand All @@ -920,9 +914,8 @@ setMethod(
signature(input = "SpatVector", input_id = "ANY",
extent = "SpatExtent", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

input <- .check_id(input, input_id)

input <- input[extent, ]
Expand All @@ -943,9 +936,8 @@ setMethod(
signature(input = "SpatVector", input_id = "ANY",
extent = "ANY", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

input <- .check_id(input, input_id)

if (out_class == "sf") {
Expand All @@ -965,9 +957,8 @@ setMethod(
signature(input = "SpatVector", input_id = "ANY",
extent = "NULL", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

input <- .check_id(input, input_id)

if (out_class == "sf") {
Expand All @@ -987,9 +978,7 @@ setMethod(
signature(input = "SpatVector", input_id = "NULL",
extent = "NULL", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
}
.check_pkgname(out = out_class)

if (out_class == "sf") {
input <- dep_switch(input)
Expand All @@ -1008,17 +997,42 @@ setMethod(
signature(input = "SpatVector", input_id = "ANY",
extent = "SpatVector", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
if (!out_class %in% c("sf", "terra")) {
cli::cli_abort(c("out_class should be one of sf or terra."))
.check_pkgname(out = out_class)

input <- .check_id(input, input_id)

if (!terra::same.crs(terra::crs(input), terra::crs(extent))) {
extent <- reproject_std(extent, terra::crs(input))
}
input <- input[extent, ]

if (out_class == "sf") {
input <- dep_switch(input)
}
return(input)
}
)


#' @keywords internal
#' @name .check_vector
#' @rdname .check_vector
#' @noRd
setMethod(
".check_vector",
signature(input = "SpatVector", input_id = "ANY",
extent = "sf", out_class = "character"),
function(input, input_id, extent, out_class, ...) {
.check_pkgname(out = out_class)

input <- .check_id(input, input_id)

if (!is.null(extent)) {
if (!terra::same.crs(terra::crs(input), terra::crs(extent))) {
extent <- reproject_std(extent, terra::crs(input))
}
input <- input[extent, ]
if (!terra::same.crs(terra::crs(input), terra::crs(extent))) {
extent <- reproject_std(extent, terra::crs(input))
}
extent <- terra::vect(extent)
input <- input[extent, ]

if (out_class == "sf") {
input <- dep_switch(input)
}
Expand Down Expand Up @@ -1141,7 +1155,7 @@ setMethod(
where = getNamespace(x)
)[[1]]
),
error = function(e){
error = function(e) {
"error"
}
)
Expand Down
45 changes: 45 additions & 0 deletions R/chopin-package.R
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,51 @@
#' .debug = TRUE
#' )
#' ```
#'
#' @section Function selection guide for `par_*()`:
#' We provide two flowcharts to help users choose the right function for
#' parallel processing. The raster-oriented flowchart is for users who
#' want to start with raster data, and the vector-oriented flowchart
#' is for users with large vector data.
#'
#' In **raster-oriented selection**, we suggest four factors to consider:
#'
#' - Number of raster files: for multiple files, `par_multirasters` is recommended. When there are multiple rasters that share the same extent and resolution, consider stacking the rasters into multilayer SpatRaster object by calling `terra::rast(filenames)`.
#' - Raster resolution: We suggest 100 meters as a threshold. Rasters with resolution coarser than 100 meters and a few layers would be better for the direct call of `exactextractr::exact_extract()`.
#' - Raster extent: Using `SpatRaster` in `exactextractr::exact_extract()` is often minimally affected by the raster extent.
#' - Memory size: `max_cells_in_memory` argument value of `exactextractr::exact_extract()`, raster resolution, and the number of layers in `SpatRaster` are multiplicatively related to the memory usage.
#'
#' For **vector-oriented selection**, we suggest three factors to consider:
#' - Number of features: When the number of features is over 100,000, consider using `par_grid` or `par_hierarchy` to split the data into smaller chunks.
#' - Hierarchical structure: If the data has a hierarchical structure, consider using `par_hierarchy` to parallelize the operation.
#' - Data grouping: If the data needs to be grouped in similar sizes, consider using `par_pad_balanced` or `par_pad_grid` with `mode = "grid_quantile"`.
#'
#'
#' @section Caveats:
#' **Why parallelization is slower than the ordinary function run?**
#' Parallelization may underperform when the datasets are too small
#' to take advantage of divide-and-compute approach, where
#' parallelization overhead is involved. Overhead here refers to
#' the required amount of computational resources for transferring
#' objects to multiple processes. Since the demonstrations above
#' use quite small datasets, the advantage of parallelization was not
#' as noticeable as it was expected. Should a large amount of
#' data (spatial/temporal resolution or number of files,
#' for example) be processed, users could find the efficiency of this
#' package. A vignette in this package demonstrates use cases
#' extracting various climate/weather datasets.
#'
#' **Notes on data restrictions**
#'
#' `chopin` works best with **two-dimensional** (**planar**) geometries.
#' Users should disable `s2` spherical geometry mode in `sf` by setting.
#' Running any `chopin` functions at spherical or three-dimensional
#' (e.g., including M/Z dimensions) geometries
#' may produce incorrect or unexpected results.
#'
#' ```r
#' sf::sf_use_s2(FALSE)
#' ```
## usethis namespace: end
"_PACKAGE"
#nolint end
11 changes: 6 additions & 5 deletions R/gridding.R
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,15 @@ par_pad_grid <-


#' Extension of par_make_balanced for padded grids
#' @description This function is an extension of `par_make_balanced`
#' to be compatible with `par_make_grid`, for which a set of padded grids
#' of the extent of input point subsets
#' @description This function utilizes [anticlust::balanced_clustering()]
#' to split the input into equal size subgroups then transform the data
#' to be compatible with the output of [`par_pad_grid`], for which
#' a set of padded grids of the extent of input point subsets
#' (as recorded in the field named `"CGRIDID"`)
#' is generated out of input points along with the output of
#' `par_make_balanced`.
#' is generated out of input points.
#' @family Parallelization
#' @param points_in `sf` or `SpatVector` object. Point geometries.
#' Default is NULL.
#' @param ngroups integer(1). The number of groups.
#' @param padding numeric(1). A extrusion factor to make buffer to
#' clip actual datasets. Depending on the length unit of the CRS of input.
Expand Down
7 changes: 5 additions & 2 deletions R/preprocessing.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#' @param pnts One of sf or SpatVector object. Target points of computation.
#' @param radius numeric(1). Buffer radius. It is assumed to be in meters
#' @param extrusion numeric(1). The extent extrusion factor.
#' Default is 1.1, meaning that the actual padding is 10 percent
#' wider than `radius`.
#' @returns A `terra::ext` or sfc_POLYGON object of the computation extent.
#' @examples
#' \dontrun{
Expand Down Expand Up @@ -123,8 +125,9 @@ clip_vec_ext <- function(
#' @param y `sf` or `SpatVector` object
#' @param radius numeric(1). buffer radius.
#' This value will be automatically multiplied by `extrusion`
#' @param nqsegs integer(1). the number of points per a quarter circle
#' @param extrusion numeric(1). Extrusion factor for the extent. Default is 1.1
#' @param nqsegs integer(1). the number of points per a quarter circle.
#' Default is 180L.
#' @param extrusion numeric(1). Extrusion factor for the extent. Default is 1.1.
#' @returns A clipped `SpatRaster` object.
#' @author Insang Song
#' @importFrom terra vect crop
Expand Down
3 changes: 3 additions & 0 deletions R/processing.R
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ kernelfunction <-
#' @param y `sf`/`SpatVector` object or file path.
#' @param id character(1). Unique identifier of each point.
#' @param func function taking one numeric vector argument.
#' Default is `"mean"` for all supported signatures in arguments
#' `x` and `y`.
#' @param extent numeric(4) or SpatExtent. Extent of clipping vector.
#' It only works with `points` of character(1) file path.
#' @param radius numeric(1). Buffer radius.
Expand All @@ -249,6 +251,7 @@ kernelfunction <-
#' One of `"uniform"`, `"triweight"`, `"quartic"`, and `"epanechnikov"`
#' @param kernel_func function.
#' Kernel function to apply to the extracted values.
#' Default is [`stats::weighted.mean()`]
#' @param bandwidth numeric(1). Kernel bandwidth.
#' @param max_cells integer(1). Maximum number of cells in memory.
#' @param .standalone logical(1). Default is `TRUE`, which means that
Expand Down
4 changes: 3 additions & 1 deletion R/zzz.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# nocov start
#' @importFrom utils packageVersion
#' @noRd
.onAttach <- function(libname, pkgname) {
if (interactive()) {
packageStartupMessage(pkgname, " ", packageVersion(pkgname))
}
}
}
# nocov end
Loading

0 comments on commit b85fc25

Please sign in to comment.