From a5fe9ee7e0418e259c92a1cc47c4a8402653a661 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Wed, 20 Sep 2023 10:44:51 -0400 Subject: [PATCH 01/21] version and apptainer test --- containers/apptainer_rocker | 18 ++++++++++++++++++ slurm_test/terra_runs_Rcode_file copy.sh | 13 +++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 containers/apptainer_rocker create mode 100755 slurm_test/terra_runs_Rcode_file copy.sh diff --git a/containers/apptainer_rocker b/containers/apptainer_rocker new file mode 100644 index 00000000..438dcc4e --- /dev/null +++ b/containers/apptainer_rocker @@ -0,0 +1,18 @@ +BootStrap: docker +From: rocker/geospatial:latest + +%post + apt-get -y update + +%environment + export LC_ALL=C + export DDN_MOUNT=/ddn/gs1/group/ + +%files + + +%runscript + + +%labels + Insang Song \ No newline at end of file diff --git a/slurm_test/terra_runs_Rcode_file copy.sh b/slurm_test/terra_runs_Rcode_file copy.sh new file mode 100755 index 00000000..e5db2858 --- /dev/null +++ b/slurm_test/terra_runs_Rcode_file copy.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +#SBATCH --job-name=calc_merra_subset_scomps.r +#SBATCH --error=terra.climate.local.error +#SBATCH --mail-user=songi2@nih.gov +#SBATCH --mail-type=NONE +#SBATCH --ntasks=1 +#SBATCH --cpus-per-task=1 +#SBATCH --partition=highmem + +## Run R: +/ddn/gs1/biotools/R/bin/Rscript -e "sessionInfo()" +/ddn/gs1/biotools/R421/bin/Rscript -e "sessionInfo()" From cab904e23e087a87df9b49459c01318cb266f046 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Mon, 2 Oct 2023 17:34:02 -0400 Subject: [PATCH 02/21] Integrating testthat - Packaging is based on litr markdown: tests.R has all tests - Will edit test file names after all tests are added --- .Rbuildignore | 1 + scomps/DESCRIPTION | 12 ++-- scomps/tests/testthat.R | 12 ++++ scomps/tests/testthat/tests.R | 34 +++++++++ scomps_rmarkdown_litr.html | 66 ++++++++++++++++-- scomps_rmarkdown_litr.rmd | 42 ++++++++++- .../scomps_0.0.1.09032023.tar.gz | Bin .../scomps_0.0.2.09152023.tar.gz | Bin .../scomps_0.0.2.09192023.tar.gz | Bin tarballs/scomps_0.0.2.10022023.tar.gz | Bin 0 -> 22366 bytes 10 files changed, 155 insertions(+), 12 deletions(-) create mode 100644 .Rbuildignore create mode 100644 scomps/tests/testthat.R create mode 100644 scomps/tests/testthat/tests.R rename scomps_0.0.1.09032023.tar.gz => tarballs/scomps_0.0.1.09032023.tar.gz (100%) rename scomps_0.0.2.09152023.tar.gz => tarballs/scomps_0.0.2.09152023.tar.gz (100%) rename scomps_0.0.2.09192023.tar.gz => tarballs/scomps_0.0.2.09192023.tar.gz (100%) create mode 100644 tarballs/scomps_0.0.2.10022023.tar.gz diff --git a/.Rbuildignore b/.Rbuildignore new file mode 100644 index 00000000..eb97a3c9 --- /dev/null +++ b/.Rbuildignore @@ -0,0 +1 @@ +rds$ diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index ace15212..58d77a8a 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -1,6 +1,6 @@ Package: scomps Title: Scalable R geospatial computation -Version: 0.0.2.09192023 +Version: 0.0.2.10022023 Authors@R: person("Insang", "Song", , "geoissong@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-8732-3256")) @@ -12,18 +12,22 @@ Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 Imports: + covr, dplyr, future, future.apply, rlang, sf, - terra + terra, + testthat Suggests: future.batchtools, igraph, knitr, logr, - rmarkdown + rmarkdown, + withr VignetteBuilder: knitr +Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: b4b4b1780f36a343cb1320d63dc814b9 +LitrId: 820777ef4091f4dab083c17458b45127 diff --git a/scomps/tests/testthat.R b/scomps/tests/testthat.R new file mode 100644 index 00000000..b465b524 --- /dev/null +++ b/scomps/tests/testthat.R @@ -0,0 +1,12 @@ +# This file is part of the standard setup for testthat. +# It is recommended that you do not modify it. +# +# Where should you do additional test configuration? +# Learn more about the roles of various files in: +# * https://r-pkgs.org/testing-design.html#sec-tests-files-overview +# * https://testthat.r-lib.org/articles/special-files.html + +library(testthat) +library(scomps) + +test_check("scomps") diff --git a/scomps/tests/testthat/tests.R b/scomps/tests/testthat/tests.R new file mode 100644 index 00000000..35965382 --- /dev/null +++ b/scomps/tests/testthat/tests.R @@ -0,0 +1,34 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand +testthat::test_that("What package does the input object belong?", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + + packbound_stars = check_packbound(bcsd_stars) + sprast_bcsd = terra::rast(bcsd_path) + packbound_terra = check_packbound(sprast_bcsd) + + testthat::expect_equal(packbound_stars, "sf") + testthat::expect_equal(packbound_terra, "terra") +}) + + +testthat::test_that("What package does the input object belong?", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + data(stars_sentinel2) + nc = system.file(package = "sf", "shape/nc.shp") + nc = sf::read_sf(nc) + + datatype_stars = check_datatype(stars_sentinel2) + datatype_sf = check_datatype(nc) + + testthat::expect_equal(datatype_stars, "raster") + testthat::expect_equal(datatype_sf, "vector") +}) + diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index 040d4379..974a9d21 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -368,7 +368,7 @@

Package setup

path = ".", fields = list( Package = params$package_name, - Version = "0.0.2.09192023", + Version = "0.0.2.10022023", Title = "Scalable R geospatial computation", Description = "A package for scalable geospatial computation for environmental health research", `Authors@R` = person( @@ -386,10 +386,13 @@

Package setup

# usethis::use_package("stars") # Default is "Imports" usethis::use_package("terra") # Default is "Imports" usethis::use_package("rlang") # Default is "Imports" +usethis::use_package("testthat") usethis::use_package("logr", "Suggests") # Default is "Imports" usethis::use_package("future") # Default is "Imports" usethis::use_package("future.apply") # Default is "Imports" usethis::use_package("igraph", "Suggests") # Default is "Imports" +usethis::use_package("withr", "Suggests") +usethis::use_package("covr") usethis::use_package("future.batchtools", "Suggests") # Default is "Imports" # usethis::use_gpl3_license() @@ -438,6 +441,41 @@

Create functions

return("raster") } } +
testthat::test_that("What package does the input object belong?",
+{
+    withr::local_package("stars")
+    withr::local_package("terra")
+    withr::local_options(list(sf_use_s2 = FALSE))
+    bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc")
+    bcsd_stars = stars::read_stars(bcsd_path)
+
+    packbound_stars = check_packbound(bcsd_stars)
+    sprast_bcsd = terra::rast(bcsd_path)
+    packbound_terra = check_packbound(sprast_bcsd)
+
+    testthat::expect_equal(packbound_stars, "sf")
+    testthat::expect_equal(packbound_terra, "terra")
+})
+
+
+testthat::test_that("What package does the input object belong?",
+{
+    withr::local_package("stars")
+    withr::local_package("terra")
+    withr::local_options(list(sf_use_s2 = FALSE))
+    data(stars_sentinel2)
+    nc = system.file(package = "sf", "shape/nc.shp")
+    nc = sf::read_sf(nc)
+
+    datatype_stars = check_datatype(stars_sentinel2)
+    datatype_sf = check_datatype(nc)
+
+    testthat::expect_equal(datatype_stars, "raster")
+    testthat::expect_equal(datatype_sf, "vector")
+})
+
## pr, tas, 
+## Test passed
+
## Test passed
#' @title Switch spatial data class
 #' @description Convert stars into SpatRaster and vice versa; sf into SpatVector and vice versa.
 #' @author Insang Song
@@ -1263,7 +1301,7 @@ 

Documenting the package and building

the package. It may also be a good idea to check the package from within this file.

litr::document() # <-- use instead of devtools::document()
-
+devtools::test()
 devtools::build()
 devtools::install(build_vignettes = TRUE, dependencies = F)
 # devtools::check(document = FALSE)
@@ -1299,6 +1337,15 @@ 

Documenting the package and building

## Writing 'sp_indexing.Rd' ## Writing 'switch_packbound.Rd' ## Writing 'validate_and_repair_vectors.Rd'
+
## ℹ Testing scomps
+
## ✔ | F W S  OK | Context
+## 
+## ⠏ |         0 | tests                                                           pr, tas, 
+## 
+## ✔ |         4 | tests
+## 
+## ══ Results ═════════════════════════════════════════════════════════════════════
+## [ FAIL 0 | WARN 0 | SKIP 0 | PASS 4 ]
## ── R CMD build ─────────────────────────────────────────────────────────────────
 ## * checking for file ‘/Users/songi2/Documents/GitHub/Scalable_GIS/scomps/DESCRIPTION’ ... OK
 ## * preparing ‘scomps’:
@@ -1314,11 +1361,17 @@ 

Documenting the package and building

## * checking for LF line-endings in source and make files and shell scripts ## * checking for empty or unneeded directories ## Removed empty directory ‘scomps/build’ -## * building ‘scomps_0.0.2.09192023.tar.gz’ +## * building ‘scomps_0.0.2.10022023.tar.gz’ ## Warning: invalid uid value replaced by that for user 'nobody' ## Warning: invalid gid value replaced by that for user 'nobody'
-
## [1] "/Users/songi2/Documents/GitHub/Scalable_GIS/scomps_0.0.2.09192023.tar.gz"
+
## [1] "/Users/songi2/Documents/GitHub/Scalable_GIS/scomps_0.0.2.10022023.tar.gz"
+
## curl (5.0.2 -> 5.1.0) [CRAN]
+
## Installing 1 packages: curl
+## Installing package into '/Users/songi2/Library/R/arm64/4.3/library'
+## (as 'lib' is unspecified)
## 
+## The downloaded binary packages are in
+##  /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpLf04ac/downloaded_packages
 ## ── R CMD build ─────────────────────────────────────────────────────────────────
 ## * checking for file ‘/Users/songi2/Documents/GitHub/Scalable_GIS/scomps/DESCRIPTION’ ... OK
 ## * preparing ‘scomps’:
@@ -1334,18 +1387,19 @@ 

Documenting the package and building

## * checking for LF line-endings in source and make files and shell scripts ## * checking for empty or unneeded directories ## Removed empty directory ‘scomps/build’ -## * building ‘scomps_0.0.2.09192023.tar.gz’ +## * building ‘scomps_0.0.2.10022023.tar.gz’ ## Warning: invalid uid value replaced by that for user 'nobody' ## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpP7s4LX/scomps_0.0.2.09192023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpLf04ac/scomps_0.0.2.10022023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... ## ** using staged installation ## ** R ## ** inst +## ** tests ## ** byte-compile and prepare package for lazy loading ## ** help ## *** installing help indices diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index 5cc40fed..f3767faf 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -21,7 +21,7 @@ usethis::create_package( path = ".", fields = list( Package = params$package_name, - Version = "0.0.2.09192023", + Version = "0.0.2.10022023", Title = "Scalable R geospatial computation", Description = "A package for scalable geospatial computation for environmental health research", `Authors@R` = person( @@ -39,10 +39,13 @@ usethis::use_package("sf") # Default is "Imports" # usethis::use_package("stars") # Default is "Imports" usethis::use_package("terra") # Default is "Imports" usethis::use_package("rlang") # Default is "Imports" +usethis::use_package("testthat") usethis::use_package("logr", "Suggests") # Default is "Imports" usethis::use_package("future") # Default is "Imports" usethis::use_package("future.apply") # Default is "Imports" usethis::use_package("igraph", "Suggests") # Default is "Imports" +usethis::use_package("withr", "Suggests") +usethis::use_package("covr") usethis::use_package("future.batchtools", "Suggests") # Default is "Imports" # usethis::use_gpl3_license() @@ -103,6 +106,41 @@ check_datatype <- function(input) { } ``` +```{r} +testthat::test_that("What package does the input object belong?", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + + packbound_stars = check_packbound(bcsd_stars) + sprast_bcsd = terra::rast(bcsd_path) + packbound_terra = check_packbound(sprast_bcsd) + + testthat::expect_equal(packbound_stars, "sf") + testthat::expect_equal(packbound_terra, "terra") +}) + + +testthat::test_that("What package does the input object belong?", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + data(stars_sentinel2) + nc = system.file(package = "sf", "shape/nc.shp") + nc = sf::read_sf(nc) + + datatype_stars = check_datatype(stars_sentinel2) + datatype_sf = check_datatype(nc) + + testthat::expect_equal(datatype_stars, "raster") + testthat::expect_equal(datatype_sf, "vector") +}) +``` + ```{r} #' @title Switch spatial data class #' @description Convert stars into SpatRaster and vice versa; sf into SpatVector and vice versa. @@ -1015,7 +1053,7 @@ We finish by running commands that will document, build, and install the package ```{r} litr::document() # <-- use instead of devtools::document() - +devtools::test() devtools::build() devtools::install(build_vignettes = TRUE, dependencies = F) # devtools::check(document = FALSE) diff --git a/scomps_0.0.1.09032023.tar.gz b/tarballs/scomps_0.0.1.09032023.tar.gz similarity index 100% rename from scomps_0.0.1.09032023.tar.gz rename to tarballs/scomps_0.0.1.09032023.tar.gz diff --git a/scomps_0.0.2.09152023.tar.gz b/tarballs/scomps_0.0.2.09152023.tar.gz similarity index 100% rename from scomps_0.0.2.09152023.tar.gz rename to tarballs/scomps_0.0.2.09152023.tar.gz diff --git a/scomps_0.0.2.09192023.tar.gz b/tarballs/scomps_0.0.2.09192023.tar.gz similarity index 100% rename from scomps_0.0.2.09192023.tar.gz rename to tarballs/scomps_0.0.2.09192023.tar.gz diff --git a/tarballs/scomps_0.0.2.10022023.tar.gz b/tarballs/scomps_0.0.2.10022023.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..51ae9e2314f70c20edddb53a404d328ec16182c2 GIT binary patch literal 22366 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 Date: Tue, 3 Oct 2023 11:51:03 -0400 Subject: [PATCH 03/21] Function restructuring - functions are reorganized in a fewer R files - workflow yaml extension fix - Added one test, fixed errors in previous tests --- ...check-standard.yml => check-standard.yaml} | 0 .github/workflows/codecov.yaml | 18 +- scomps/DESCRIPTION | 4 +- scomps/R/aw_covariates.R | 68 ---- scomps/R/calculate_sedc.R | 48 --- scomps/R/check.R | 139 +++++++ scomps/R/check_bbox.R | 34 -- scomps/R/check_crs.R | 27 -- scomps/R/check_crs2.R | 29 -- scomps/R/check_packbound.R | 26 -- scomps/R/check_within_reference.R | 27 -- scomps/R/clip_as_extent.R | 37 -- scomps/R/clip_as_extent_ras.R | 20 - scomps/R/clip_as_extent_ras2.R | 20 - scomps/R/distribute_process.R | 39 -- scomps/R/extract_with.R | 33 -- scomps/R/extract_with_buffer.R | 50 --- scomps/R/extract_with_buffer.flat.R | 23 -- scomps/R/extract_with_buffer.kernel.R | 27 -- scomps/R/extract_with_polygons.R | 55 --- scomps/R/{sp_indexing.R => indexing.R} | 0 ...ons.R => interpret_computational_domain.R} | 38 ++ scomps/R/{initate_log.R => logging.R} | 0 .../R/{set_clip_extent.R => preprocessing.R} | 11 + scomps/R/processing.R | 372 ++++++++++++++++++ scomps/R/rast_short.R | 12 - .../R/{switch_packbound.R => switch_format.R} | 0 ...lidate_and_repair_vectors.R => validate.R} | 0 scomps/tests/testthat/tests.R | 35 +- scomps_rmarkdown_litr.html | 100 +++-- scomps_rmarkdown_litr.rmd | 83 ++-- tarballs/scomps_0.0.2.10032023.tar.gz | Bin 0 -> 21871 bytes 32 files changed, 727 insertions(+), 648 deletions(-) rename .github/workflows/{check-standard.yml => check-standard.yaml} (100%) delete mode 100644 scomps/R/aw_covariates.R delete mode 100644 scomps/R/calculate_sedc.R create mode 100644 scomps/R/check.R delete mode 100644 scomps/R/check_bbox.R delete mode 100644 scomps/R/check_crs.R delete mode 100644 scomps/R/check_crs2.R delete mode 100644 scomps/R/check_packbound.R delete mode 100644 scomps/R/check_within_reference.R delete mode 100644 scomps/R/clip_as_extent.R delete mode 100644 scomps/R/clip_as_extent_ras.R delete mode 100644 scomps/R/clip_as_extent_ras2.R delete mode 100644 scomps/R/distribute_process.R delete mode 100644 scomps/R/extract_with.R delete mode 100644 scomps/R/extract_with_buffer.R delete mode 100644 scomps/R/extract_with_buffer.flat.R delete mode 100644 scomps/R/extract_with_buffer.kernel.R delete mode 100644 scomps/R/extract_with_polygons.R rename scomps/R/{sp_indexing.R => indexing.R} (100%) rename scomps/R/{get_computational_regions.R => interpret_computational_domain.R} (83%) rename scomps/R/{initate_log.R => logging.R} (100%) rename scomps/R/{set_clip_extent.R => preprocessing.R} (77%) create mode 100644 scomps/R/processing.R delete mode 100644 scomps/R/rast_short.R rename scomps/R/{switch_packbound.R => switch_format.R} (100%) rename scomps/R/{validate_and_repair_vectors.R => validate.R} (100%) create mode 100644 tarballs/scomps_0.0.2.10032023.tar.gz diff --git a/.github/workflows/check-standard.yml b/.github/workflows/check-standard.yaml similarity index 100% rename from .github/workflows/check-standard.yml rename to .github/workflows/check-standard.yaml diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 260f7f27..30ba6e81 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -1,12 +1,12 @@ -name: R Package CI +on: + push: + branches: + - main + pull_request: + branches: + - main -#on: -# push: -# branches: -# - main -# pull_request: -# branches: -# - main +name: R Package CI jobs: build: @@ -27,7 +27,7 @@ jobs: path: | ~/.cache/R ~/.local/share/R - key: dependencies-${{ runner.os }}-${{ hashFiles('**/DESCRIPTION') }} + key: dependencies-${{ runner.os }}-${{ hashFiles('**/scomps/DESCRIPTION') }} restore-keys: | dependencies-${{ runner.os }}- diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index 58d77a8a..2f72afbd 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -1,6 +1,6 @@ Package: scomps Title: Scalable R geospatial computation -Version: 0.0.2.10022023 +Version: 0.0.2.10032023 Authors@R: person("Insang", "Song", , "geoissong@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-8732-3256")) @@ -30,4 +30,4 @@ Suggests: VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: 820777ef4091f4dab083c17458b45127 +LitrId: 7c9484dd9127c939a90d433ec83cd305 diff --git a/scomps/R/aw_covariates.R b/scomps/R/aw_covariates.R deleted file mode 100644 index 118c041a..00000000 --- a/scomps/R/aw_covariates.R +++ /dev/null @@ -1,68 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Computing area weighted covariates using two polygon sf or SpatVector objects -#' @param poly_in A sf/SpatVector object at weighted means will be calculated. -#' @param poly_weight A sf/SpatVector object from which weighted means will be calculated. -#' @param id_poly_in character(1). The unique identifier of each polygon in poly_in -#' @return A data.frame with all numeric fields of area-weighted means. -#' @description When poly_in and poly_weight are different classes, poly_weight will be converted to the class of poly_in. -#' @author Insang Song \email{geoissong@@gmail.com} -#' @examples -#' # package -#' library(sf) -#' library(tictoc) -#' -#' # run -#' nc = st_read(system.file("shape/nc.shp", package="sf")) -#' nc = st_transform(nc, 5070) -#' pp = st_sample(nc, size = 300) -#' pp[["id"]] = seq(1,nrow(pp)) -#' st_crs(pp) = "EPSG:5070" -#' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) -#' -#' tic() -#' ppb_nc_aw = aw_covariates(ppb, nc, 'id') -#' toc() -#' summary(ppb_nc_aw) -#' #### Example of aw_covariates ends #### -#' @export -aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { - stopifnot("Inputs have invalid classes.\n" = - is(poly_in, "sf") || is(poly_weight, "sf") || is(poly_in, "SpatVector") || is(poly_weight, "SpatVector")) - #check_crs() - aw_covariates.terra = function(poly_in, poly_weight, id_poly_in = id_poly_in) { - - poly_intersected = terra::intersect(poly_in, poly_weight) - poly_intersected[["area_segment_"]] = terra::expanse(poly_intersected) - poly_intersected = data.frame(poly_intersected) |> - dplyr::group_by(!!rlang::sym(id_poly_in)) |> - dplyr::summarize(across(is.numeric, - ~weighted.mean(., w = area_segment_))) |> - dplyr::ungroup() - return(poly_intersected) - } - - class_poly_in = check_packbound(poly_in) - class_poly_weight = check_packbound(poly_weight) - - if (class_poly_in != class_poly_weight) { - class_poly_weight = as(class_poly_weight, class(class_poly_in)[1]) - } - - switch(class_poly_in, - sf = sf::st_interpolate_aw(poly_weight, poly_in, extensive = FALSE), - terra = aw_covariates.terra(poly_in, poly_weight, id_poly_in = id_poly_in)) - -} - -# ncbuf = terra::intersect(vect(ppb), vect(nc)) -# ncbuf_a = ncbuf -# ncbuf_a$segarea = expanse(ncbuf_a) -# ncbuf_k = data.frame(ncbuf_a) |> -# dplyr::group_by(id) |> -# dplyr::summarize(across(is.numeric, -# ~weighted.mean(., w = segarea))) |> -# dplyr::ungroup() - -#ncbufagg = terra::aggregate(ncbuf, by = 'id', fun = weighted.mean, w = ncbuf_a$segarea) - diff --git a/scomps/R/calculate_sedc.R b/scomps/R/calculate_sedc.R deleted file mode 100644 index 6aed8d49..00000000 --- a/scomps/R/calculate_sedc.R +++ /dev/null @@ -1,48 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Calculate SEDC covariates -#' @param point_from SpatVector object. Locations where the sum of SEDCs are calculated. -#' @param point_to SpatVector object. Locations where each SEDC is calculated. -#' @param sdec_bandwidth numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 %) -#' @param threshold numeric(1). For computational efficiency, the nearest points in threshold will be selected -#' @param target_fields character(varying). Field names in characters. -#' @description NOTE: sf implementation is pending. Only available for terra. -#' @author Insang Song -#' @export -calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, target_fields) { - # define sources, set SEDC exponential decay range - len_point_from = seq_len(nrow(point_from)) - len_point_to = seq_len(nrow(point_to)) - - point_from$from_id = len_point_from - # select egrid_v only if closer than 3e5 meters from each aqs - point_from_buf = terra::buffer(point_from_buf, threshold = threshold, quadsegs = 90) - point_to = point_to[point_from_buf,] - point_to$to_id = len_point_to - - # near features with distance argument: only returns integer indices - near_from_to = terra::nearby(point_from, point_to, distance = threshold) - # attaching actual distance - dist_near_to = terra::distance(point_from, point_to) - dist_near_to_df = as.vector(dist_near_to) - # adding integer indices - dist_near_to_tdf = expand.grid(from_id = len_point_from, to_id = len_point_to) - dist_near_to_df = cbind(dist_near_to_tdf, dist = dist_near_to_df) - - # summary - near_from_to = near_from_to |> - as_tibble() |> - left_join(data.frame(point_from)) |> - left_join(data.frame(point_to)) |> - left_join(dist_near_to_df) |> - # per the definition in https://mserre.sph.unc.edu/BMElab_web/SEDCtutorial/index.html - # exp(-3) is about 0.05 - mutate(w_sedc = exp((-3 * dist) / sedc_bandwidth)) |> - group_by(!!sym(id)) |> - summarize(across(all_of(target_fields), list(sedc = ~sum(w_sedc * ., na.rm = TRUE)))) |> - ungroup() - - invisible(near_from_to) - -} - diff --git a/scomps/R/check.R b/scomps/R/check.R new file mode 100644 index 00000000..3fed02f7 --- /dev/null +++ b/scomps/R/check.R @@ -0,0 +1,139 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' @title Return the package the input object is based on +#' @description Detect whether the input object is sf or Spat* object. +#' @author Insang Song +#' @param input Spat* in terra or sf object. +#' @return A character object; one of 'terra' and 'sf' +#' @export +check_packbound <- function(input) { + # cl_inobj = class(input)[1] + stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) + if (is(input, "SpatVector") || is(input, "SpatRaster")) { + return("terra") + } + return("sf") +} + +check_datatype <- function(input) { + stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) + if (any(is(input, "SpatVector"), is(input, "sf"))) { + return("vector") + } + if (any(is(input, "SpatRaster"), is(input, "stars"))) { + return("raster") + } +} + +#' @title check_crs2: Coordinate system checker +#' @description The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179. +#' @param input Input object one of sf or terra::Spat* object +#' @return A (reprojected) sf or SpatVector object. +#' @export +check_crs2 <- function(input, crs_standard = "EPSG:4326") { + check_crs.sf <- function(input){ + if (is.na(st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} + if (sf::st_crs(input)$epsg == crs_standard ) { + return(input) + } + input_transformed <- sf::st_transform(input, sf::st_crs(crs_standard)) + return(input_transformed) + } + + check_crs.terra <- function(input) { + if (terra::crs(input, describe = TRUE)$code == crs_standard) { + return(input) + } + input_transformed = terra::project(input, terra::crs(crs_standard)) + return(input_transformed) + } + detected = check_packbound(input) + switch(detected, + terra = check_crs.terra(input), + sf = check_crs.sf(input)) + } + +#' Check if the data extent is inside the reference bounding box +#' +#' @description One of the most common errors in spatial computation is rooted in the entirely or partly incomparable spatial extents of input datasets. This function returns whether your data is inside the target computational extent. It is assumed that you know and have the exact computational region. This function will return TRUE if the reference region completely contains your data's extent and FALSE otherwise. +#' @param data_query sf*/stars/SpatVector/SpatRaster object. +#' @param reference sf*/stars/SpatVector/SpatRaster object or a named numeric vector with four names (xmin, ymin, xmax, and ymax). +#' @param reference_crs Well-known-text-formatted or EPSG code of the reference's coordinate system. Only required when a named numeric vector is passed to reference. +#' @return TRUE (the queried data extent is completely within the reference bounding box) or FALSE +#' @author Insang Song \email{geoissong@@gmail.com} +#' +#' @export +check_bbox <- function( + data_query, reference, reference_crs = NULL +) { + if (is.numeric(reference) && is.null(reference_crs)) { + stop("CRS should be entered when the reference extent is a vector.\n") + } + if (is.numeric(reference) && !is.null(reference_crs)) { + reference = sf::st_as_sfc(sf::st_bbox(reference), crs = reference_crs) + } + query_crs = check_crs(data_query) + ref_crs = check_crs(reference) + if (is.na(query_crs) || is.null(query_crs)) { + stop("The dataset you queried has no CRS. Please make sure your dataset has the correct CRS.\n") + } + + # ... + + check_result + return(check_result) +} + + + +#' Check Coordinate Reference System +#' @param x sf/stars/SpatVector/SpatRaster object. +#' @return A st_crs or crs object. +#' @description +#' @author Insang Song \email{geoissong@@gmail.com} +#' @examples +#' # data +#' install.packages('spData') +#' library(spData) +#' data(us_states) +#' check_crs(us_states) +#' +#' @export +check_crs <- function(x) { + stopifnot("Input is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) + + if (is(x, "sf") || is(x, "stars")) { + crs_wkt = sf::st_crs(x) + } else { + crs_wkt = terra::crs(x) + } + + stopifnot("No CRS is defined in the input. Please consult the metadata or the data source.\n" = !is.na(crs_wkt) || crs_wkt != "") + return(crs_wkt) +} + +#' Check if the boundary of the vector/raster object is inside the reference +#' @param input_object sf/stars/SpatVector/SpatRaster object. +#' @param reference sf/stars/SpatVector/SpatRaster object. +#' @return logical +#' @author Insang Song \email{geoissong@@gmail.com} +#' @export +check_within_reference <- function(input_object, reference) { + stopifnot("Input is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) + stopifnot("Reference is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) + + bbox_input <- input_object + sf::st_bbox() |> + sf::st_as_sfc() + + bbox_reference = reference |> + sf::st_bbox() |> + sf::st_as_sfc() + + iswithin = sf::st_covered_by(bbox_input, bbox_reference) + iswithin = length(iswithin[[1]]) + iswithin = (iswithin == 1) + invisible(iswithin) +} + + diff --git a/scomps/R/check_bbox.R b/scomps/R/check_bbox.R deleted file mode 100644 index 5f823688..00000000 --- a/scomps/R/check_bbox.R +++ /dev/null @@ -1,34 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Check if the data extent is inside the reference bounding box -#' -#' @description One of the most common errors in spatial computation is rooted in the entirely or partly incomparable spatial extents of input datasets. This function returns whether your data is inside the target computational extent. It is assumed that you know and have the exact computational region. This function will return TRUE if the reference region completely contains your data's extent and FALSE otherwise. -#' @param data_query sf*/stars/SpatVector/SpatRaster object. -#' @param reference sf*/stars/SpatVector/SpatRaster object or a named numeric vector with four names (xmin, ymin, xmax, and ymax). -#' @param reference_crs Well-known-text-formatted or EPSG code of the reference's coordinate system. Only required when a named numeric vector is passed to reference. -#' @return TRUE (the queried data extent is completely within the reference bounding box) or FALSE -#' @author Insang Song \email{geoissong@@gmail.com} -#' -#' @export -check_bbox <- function( - data_query, reference, reference_crs = NULL -) { - if (is.numeric(reference) && is.null(reference_crs)) { - stop("CRS should be entered when the reference extent is a vector.\n") - } - if (is.numeric(reference) && !is.null(reference_crs)) { - reference = sf::st_as_sfc(sf::st_bbox(reference), crs = reference_crs) - } - query_crs = check_crs(data_query) - ref_crs = check_crs(reference) - if (is.na(query_crs) || is.null(query_crs)) { - stop("The dataset you queried has no CRS. Please make sure your dataset has the correct CRS.\n") - } - - # ... - - check_result - return(check_result) -} - - diff --git a/scomps/R/check_crs.R b/scomps/R/check_crs.R deleted file mode 100644 index 6a31ba76..00000000 --- a/scomps/R/check_crs.R +++ /dev/null @@ -1,27 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Check Coordinate Reference System -#' @param x sf/stars/SpatVector/SpatRaster object. -#' @return A st_crs or crs object. -#' @description -#' @author Insang Song \email{geoissong@@gmail.com} -#' @examples -#' # data -#' install.packages('spData') -#' library(spData) -#' data(us_states) -#' check_crs(us_states) -#' -#' @export -check_crs <- function(x) { - stopifnot("Input is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) - - if (is(x, "sf") || is(x, "stars")) { - crs_wkt = sf::st_crs(x) - } else { - crs_wkt = terra::crs(x) - } - - stopifnot("No CRS is defined in the input. Please consult the metadata or the data source.\n" = !is.na(crs_wkt) || crs_wkt != "") - return(crs_wkt) -} diff --git a/scomps/R/check_crs2.R b/scomps/R/check_crs2.R deleted file mode 100644 index 2852796a..00000000 --- a/scomps/R/check_crs2.R +++ /dev/null @@ -1,29 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' @title check_crs2: Coordinate system checker -#' @description The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179. -#' @param input Input object one of sf or terra::Spat* object -#' @return A (reprojected) sf or SpatVector object. -#' @export -check_crs2 <- function(input, crs_standard = "EPSG:4326") { - check_crs.sf <- function(input){ - if (is.na(st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} - if (sf::st_crs(input)$epsg == crs_standard ) { - return(input) - } - input_transformed <- sf::st_transform(input, sf::st_crs(crs_standard)) - return(input_transformed) - } - - check_crs.terra <- function(input) { - if (terra::crs(input, describe = TRUE)$code == crs_standard) { - return(input) - } - input_transformed = terra::project(input, terra::crs(crs_standard)) - return(input_transformed) - } - detected = check_packbound(input) - switch(detected, - terra = check_crs.terra(input), - sf = check_crs.sf(input)) - } diff --git a/scomps/R/check_packbound.R b/scomps/R/check_packbound.R deleted file mode 100644 index 4de77af7..00000000 --- a/scomps/R/check_packbound.R +++ /dev/null @@ -1,26 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' @title Return the package the input object is based on -#' @description Detect whether the input object is sf or Spat* object. -#' @author Insang Song -#' @param input Spat* in terra or sf object. -#' @return A character object; one of 'terra' and 'sf' -#' @export -check_packbound <- function(input) { - # cl_inobj = class(input)[1] - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) - if (is(input, "SpatVector") || is(input, "SpatRaster")) { - return("terra") - } - return("sf") -} - -check_datatype <- function(input) { - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) - if (any(is(input, "SpatVector"), is(input, "sf"))) { - return("vector") - } - if (any(is(input, "SpatRaster"), is(input, "stars"))) { - return("raster") - } -} diff --git a/scomps/R/check_within_reference.R b/scomps/R/check_within_reference.R deleted file mode 100644 index 2df7c63c..00000000 --- a/scomps/R/check_within_reference.R +++ /dev/null @@ -1,27 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Check if the boundary of the vector/raster object is inside the reference -#' @param input_object sf/stars/SpatVector/SpatRaster object. -#' @param reference sf/stars/SpatVector/SpatRaster object. -#' @return logical -#' @author Insang Song \email{geoissong@@gmail.com} -#' @export -check_within_reference <- function(input_object, reference) { - stopifnot("Input is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) - stopifnot("Reference is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) - - bbox_input <- input_object - sf::st_bbox() |> - sf::st_as_sfc() - - bbox_reference = reference |> - sf::st_bbox() |> - sf::st_as_sfc() - - iswithin = sf::st_covered_by(bbox_input, bbox_reference) - iswithin = length(iswithin[[1]]) - iswithin = (iswithin == 1) - invisible(iswithin) -} - - diff --git a/scomps/R/clip_as_extent.R b/scomps/R/clip_as_extent.R deleted file mode 100644 index 6cea0ca4..00000000 --- a/scomps/R/clip_as_extent.R +++ /dev/null @@ -1,37 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Extent clipping -#' @description Clip input vector by the expected maximum extent of computation. -#' @author Insang Song -#' @param pnts sf or SpatVector object -#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 -#' @param nqsegs integer(1). the number of points per a quarter circle; SOON TO BE DEPRECATED -#' @param target_input sf or SpatVector object to be clipped -#' @return A clipped sf or SpatVector object. -#' @export -clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input){ - if (any(sapply(list(pnts, buffer_r, target_input), is.null))) { - stop("One or more required arguments are NULL. Please check.\n") - } - detected_pnts = check_packbound(pnts) - detected_target = check_packbound(target_input) - - if (detected_pnts != detected_target) { - warning("Inputs are not the same class.\n") - target_input = switch(detected_target, - sf = terra::vect(target_input), - terra = sf::st_as_sf(target_input)) - } - - ext_input = set_clip_extent(pnts, buffer_r) - cat("Clip target features with the input feature extent...\n") - if (detected_pnts == "sf") { - cae = ext_input |> - sf::st_intersection(x = target_input) - } - if (detected_pnts == "terra") { - cae = terra::intersect(target_input, ext_input) - } - - return(cae) -} diff --git a/scomps/R/clip_as_extent_ras.R b/scomps/R/clip_as_extent_ras.R deleted file mode 100644 index 9ad93a61..00000000 --- a/scomps/R/clip_as_extent_ras.R +++ /dev/null @@ -1,20 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' @title clip_as_extent_ras: Clip input raster. -#' @description Clip input raster by the expected maximum extent of computation. -#' @author Insang Song -#' @param pnts sf or SpatVector object -#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 -#' @param nqsegs integer(1). the number of points per a quarter circle -#' @param ras SpatRaster object to be clipped -#' @export -clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras){ - if (any(sapply(list(pnts, buffer_r, ras), is.null))) { - stop("Any of required arguments are NULL. Please check.\n") - } - ext_input = set_clip_extent(pnts, buffer_r) |> - terra::ext() - - cae <- terra::crop(ras, ext_input, snap = 'out') - return(cae) -} diff --git a/scomps/R/clip_as_extent_ras2.R b/scomps/R/clip_as_extent_ras2.R deleted file mode 100644 index d6c6e2ff..00000000 --- a/scomps/R/clip_as_extent_ras2.R +++ /dev/null @@ -1,20 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' @title clip_as_extent_ras2: Clip input raster (version 2). -#' @description Clip input raster by the expected maximum extent of computation. -#' @author Insang Song -#' @param points_in sf or SpatVector object -#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 -#' @param nqsegs integer(1). the number of points per a quarter circle -#' @param ras SpatRaster object to be clipped -#' @export -clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras){ - if (any(sapply(list(points_in, buffer_r, ras), is.null))) { - stop("Any of required arguments are NULL. Please check.\n") - } - ext_input = set_clip_extent(points_in, buffer_r) |> - terra::ext() - - cae <- terra::crop(ras, ext_input, snap = 'out') - return(cae) -} diff --git a/scomps/R/distribute_process.R b/scomps/R/distribute_process.R deleted file mode 100644 index 2fc47eb4..00000000 --- a/scomps/R/distribute_process.R +++ /dev/null @@ -1,39 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' @title Process a given function in the entire or partial computational grids (under construction) -#' -#' @description Should -#' @param grids sf/SpatVector object. Computational grids. -#' @param grid_id character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. "id_from:id_to" format or c(unique(grid_id)[id_from], unique(grid_id)[id_to]) -#' @param fun function supported in scomps. -#' @param ... Arguments passed to fun. -#' @return a data.frame object with mean value -#' @author Insang Song \email{geoissong@@gmail.com} -#' -#' @export -distribute_process <- function(grids, grid_id = NULL, fun, ...) { - require(future.apply) - - # subset using grids and grid_id - if (!is.null(grid_id)) { - if (is.character(grid_id)) { - grid_id_parsed = strsplit(grid_id, ":", fixed = TRUE)[[1]] - grid_ids = c(which(unique(grids[["CGRIDID"]]) == grid_id_parsed[1]), - which(unique(grids[["CGRIDID"]]) == grid_id_parsed[2])) - } - if (is.numeric(grid_id)) { - grid_ids = unique(grids[["CGRIDID"]])[grid_id] - } - } - grids_target = grids[grid_ids,] - grids_target_list = split(grids_target, grids_target[["CGRIDID"]]) - - results_distributed = future.apply::future_lapply( - \(x, ...) { - fun(...) - }, grids_target_list, points_cutslist, SIMPLIFY = FALSE, - future.seed = TRUE) - results_distributed = do.call(rbind, results_distributed) - return(results_distributed) -} - diff --git a/scomps/R/extract_with.R b/scomps/R/extract_with.R deleted file mode 100644 index c1d4ad95..00000000 --- a/scomps/R/extract_with.R +++ /dev/null @@ -1,33 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Extract raster values with point buffers or polygons -#' -#' @param raster SpatRaster object. -#' @param vector SpatVector object. -#' @param id character(1). Unique identifier of each point. -#' @param func function taking one numeric vector argument. -#' @param mode one of "polygon" (generic polygons to extract raster values with) or "buffer" (point with buffer radius) -#' @param ... various. Passed to extract_with_buffer. See \code{?extract_with_buffer} for details. -#' @return -#' @author Insang Song \email{geoissong@@gmail.com} -#' @examples -#' # data -#' -#' # run -#' clip_with() -#' -#' @export -extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) { - if (!mode %in% c("polygon", "buffer")) { - stop("Argument 'mode' should be one of 'polygon' or 'buffer'.\n") - } - stopifnot(is.character(id)) - stopifnot(id %in% names(vector)) - - extracted = - switch(mode, - polygon = extract_with_polygons(vector, raster, id, func), - buffer = extract_with_buffer(vector, raster, id = id, func = func, ...)) - return(extracted) -} - diff --git a/scomps/R/extract_with_buffer.R b/scomps/R/extract_with_buffer.R deleted file mode 100644 index 05b79640..00000000 --- a/scomps/R/extract_with_buffer.R +++ /dev/null @@ -1,50 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' @title Extract summarized values from raster with points and a buffer radius (to be written) -#' -#' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. -#' @param points SpatVector object. Coordinates where buffers will be generated -#' @param surf SpatRaster object. A raster of whatnot a summary will be calculated -#' @param radius numeric(1). Buffer radius. here we assume circular buffers only -#' @param id character(1). Unique identifier of each point. -#' @param qsegs integer(1). Number of vertices at a quarter of a circle. Default is 90. -#' @param func a function taking a numeric vector argument. -#' @param kernel character(1). Name of a kernel function (yet to be implemented) -#' @param bandwidth numeric(1). Kernel bandwidth. -#' @return a data.frame object with mean value -#' @author Insang Song \email{geoissong@@gmail.com} -#' -#' @export -extract_with_buffer <- function( - points, surf, radius, id, qsegs = 90, func = mean, kernel = NULL, bandwidth = NULL - ) { - # type check - stopifnot("Check class of the input points.\n" = is(points, "SpatVector")) - stopifnot("Check class of the input radius.\n" = is.numeric(radius)) - stopifnot(is.character(id)) - stopifnot(is.integer(qsegs)) - - if (!is.null(kernel)) { - extracted = extract_with_buffer.flat(points = points, - surf = surf, - radius = radius, - id = id, - func = func, - qsegs = qsegs) - return(extracted) - } - - extracted = extract_with_buffer.kernel(points = points, - surf = surf, - radius = radius, - id = id, - func = func, - qsegs = qsegs, - kernel = kernel, - bandwidth = bandwidth) - return(extracted) - -} - - - diff --git a/scomps/R/extract_with_buffer.flat.R b/scomps/R/extract_with_buffer.flat.R deleted file mode 100644 index bcf81c57..00000000 --- a/scomps/R/extract_with_buffer.flat.R +++ /dev/null @@ -1,23 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Subfunction: extract with buffers (flat weight; simple mean) -#' -#' @export -extract_with_buffer.flat <- function( - points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL - ) { - # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) - # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) - # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = - surf_at_bufs |> - group_by(ID) |> - summarize(across(all_of(name_surf_val), ~mean, na.rm=T)) |> - ungroup() - return(surf_at_bufs_summary) -} diff --git a/scomps/R/extract_with_buffer.kernel.R b/scomps/R/extract_with_buffer.kernel.R deleted file mode 100644 index 3967965f..00000000 --- a/scomps/R/extract_with_buffer.kernel.R +++ /dev/null @@ -1,27 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Subfunction: extract with buffers (kernel weight; weighted mean) -#' -#' @export -extract_with_buffer.kernel <- function( - points, surf, radius, id, qsegs, func = mean, kernel, bandwidth - ) { - # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) - # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) - - # TODO: kernel implementation - - - # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = - surf_at_bufs |> - group_by(ID) |> - summarize(across(all_of(name_surf_val), ~mean, na.rm=T)) |> - ungroup() - return(surf_at_bufs_summary) -} diff --git a/scomps/R/extract_with_polygons.R b/scomps/R/extract_with_polygons.R deleted file mode 100644 index 4b37763a..00000000 --- a/scomps/R/extract_with_polygons.R +++ /dev/null @@ -1,55 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' @title Extract summarized values from raster with generic polygons -#' -#' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. -#' @param polys sf/SpatVector object. Polygons. -#' @param surf stars/SpatRaster object. A raster of whatnot a summary will be calculated -#' @param id character(1). Unique identifier of each point. -#' @param func a function taking one argument. For example, function(x) mean(x, na.rm = TRUE) or \(x) mode(x, na.rm = TRUE) -#' @param na.rm logical(1). NA values are omitted when summary is calculated. -#' @return a data.frame object with function value -#' @author Insang Song \email{geoissong@@gmail.com} -#' -#' @export -extract_with_polygons <- function( - polys, surf, id, func = mean, na.rm = TRUE - ) { - # type check - stopifnot("Check class of the input points.\n" = any(is(polys, "sf"), is(polys, "SpatVector"))) - stopifnot("Check class of the input raster.\n" = any(is(surf, "stars"), is(surf, "SpatRaster"))) - stopifnot(is.character(id)) - - cls_polys = check_packbound(polys) - cls_surf = check_packbound(surf) - - if (cls_polys != cls_surf) { - polys = switch_packbound(polys) - } - - extract_with_polygons.sf = function(polys, surf, id, func) { - extracted = stars::st_extract(x = surf, at = polys, FUN = func) - # extracted = extracted |> - # group_by(!!sym(id)) |> - # summarize(across(-!!sym(id), ~func)) |> - # ungroup() - return(extracted) - } - - extract_with_polygons.terra = function(polys, surf, id, func) { - extracted = terra::extract(surf, polys) - extracted = extracted |> - group_by(!!sym(id)) |> - summarize(across(-!!sym(id), ~func)) |> - ungroup() - return(extracted) - } - - extracted_poly = switch( - cls_surf, - sf = extract_with_polygons.sf(polys = polys, surf = surf, id = id, func = func), - terra = extract_with_polygons.terra(polys = polys, surf = surf, id = id, func = func) - ) - return(extracted_poly) -} - diff --git a/scomps/R/sp_indexing.R b/scomps/R/indexing.R similarity index 100% rename from scomps/R/sp_indexing.R rename to scomps/R/indexing.R diff --git a/scomps/R/get_computational_regions.R b/scomps/R/interpret_computational_domain.R similarity index 83% rename from scomps/R/get_computational_regions.R rename to scomps/R/interpret_computational_domain.R index bac913a5..757acf37 100644 --- a/scomps/R/get_computational_regions.R +++ b/scomps/R/interpret_computational_domain.R @@ -166,3 +166,41 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ + +#' @title Process a given function in the entire or partial computational grids (under construction) +#' +#' @description Should +#' @param grids sf/SpatVector object. Computational grids. +#' @param grid_id character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. "id_from:id_to" format or c(unique(grid_id)[id_from], unique(grid_id)[id_to]) +#' @param fun function supported in scomps. +#' @param ... Arguments passed to fun. +#' @return a data.frame object with mean value +#' @author Insang Song \email{geoissong@@gmail.com} +#' +#' @export +distribute_process <- function(grids, grid_id = NULL, fun, ...) { + require(future.apply) + + # subset using grids and grid_id + if (!is.null(grid_id)) { + if (is.character(grid_id)) { + grid_id_parsed = strsplit(grid_id, ":", fixed = TRUE)[[1]] + grid_ids = c(which(unique(grids[["CGRIDID"]]) == grid_id_parsed[1]), + which(unique(grids[["CGRIDID"]]) == grid_id_parsed[2])) + } + if (is.numeric(grid_id)) { + grid_ids = unique(grids[["CGRIDID"]])[grid_id] + } + } + grids_target = grids[grid_ids,] + grids_target_list = split(grids_target, grids_target[["CGRIDID"]]) + + results_distributed = future.apply::future_lapply( + \(x, ...) { + fun(...) + }, grids_target_list, points_cutslist, SIMPLIFY = FALSE, + future.seed = TRUE) + results_distributed = do.call(rbind, results_distributed) + return(results_distributed) +} + diff --git a/scomps/R/initate_log.R b/scomps/R/logging.R similarity index 100% rename from scomps/R/initate_log.R rename to scomps/R/logging.R diff --git a/scomps/R/set_clip_extent.R b/scomps/R/preprocessing.R similarity index 77% rename from scomps/R/set_clip_extent.R rename to scomps/R/preprocessing.R index 3a699be8..8f8f6cb8 100644 --- a/scomps/R/set_clip_extent.R +++ b/scomps/R/preprocessing.R @@ -22,3 +22,14 @@ set_clip_extent <- function(pnts, buffer_r) { } return(ext_input) } + +#' Quick call for SpatRaster with a window +#' +#' @param rasterpath character(1). Path to the raster file. +#' @param win Named integer vector (4) or terra::ext() results. +#' @param author Insang Song +#' @export +rast_short <- function(rasterpath, win) { + terra::rast(rasterpath, win = win) +} + diff --git a/scomps/R/processing.R b/scomps/R/processing.R new file mode 100644 index 00000000..c1c84a03 --- /dev/null +++ b/scomps/R/processing.R @@ -0,0 +1,372 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' Extent clipping +#' @description Clip input vector by the expected maximum extent of computation. +#' @author Insang Song +#' @param pnts sf or SpatVector object +#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 +#' @param nqsegs integer(1). the number of points per a quarter circle; SOON TO BE DEPRECATED +#' @param target_input sf or SpatVector object to be clipped +#' @return A clipped sf or SpatVector object. +#' @export +clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input){ + if (any(sapply(list(pnts, buffer_r, target_input), is.null))) { + stop("One or more required arguments are NULL. Please check.\n") + } + detected_pnts = check_packbound(pnts) + detected_target = check_packbound(target_input) + + if (detected_pnts != detected_target) { + warning("Inputs are not the same class.\n") + target_input = switch(detected_target, + sf = terra::vect(target_input), + terra = sf::st_as_sf(target_input)) + } + + ext_input = set_clip_extent(pnts, buffer_r) + cat("Clip target features with the input feature extent...\n") + if (detected_pnts == "sf") { + cae = ext_input |> + sf::st_intersection(x = target_input) + } + if (detected_pnts == "terra") { + cae = terra::intersect(target_input, ext_input) + } + + return(cae) +} + +#' @title clip_as_extent_ras: Clip input raster. +#' @description Clip input raster by the expected maximum extent of computation. +#' @author Insang Song +#' @param pnts sf or SpatVector object +#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 +#' @param nqsegs integer(1). the number of points per a quarter circle +#' @param ras SpatRaster object to be clipped +#' @export +clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras){ + if (any(sapply(list(pnts, buffer_r, ras), is.null))) { + stop("Any of required arguments are NULL. Please check.\n") + } + ext_input = set_clip_extent(pnts, buffer_r) |> + terra::ext() + + cae <- terra::crop(ras, ext_input, snap = 'out') + return(cae) +} + +#' @title clip_as_extent_ras2: Clip input raster (version 2). +#' @description Clip input raster by the expected maximum extent of computation. +#' @author Insang Song +#' @param points_in sf or SpatVector object +#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 +#' @param nqsegs integer(1). the number of points per a quarter circle +#' @param ras SpatRaster object to be clipped +#' @export +clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras){ + if (any(sapply(list(points_in, buffer_r, ras), is.null))) { + stop("Any of required arguments are NULL. Please check.\n") + } + ext_input = set_clip_extent(points_in, buffer_r) |> + terra::ext() + + cae <- terra::crop(ras, ext_input, snap = 'out') + return(cae) +} + +#' @title Extract summarized values from raster with generic polygons +#' +#' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. +#' @param polys sf/SpatVector object. Polygons. +#' @param surf stars/SpatRaster object. A raster of whatnot a summary will be calculated +#' @param id character(1). Unique identifier of each point. +#' @param func a function taking one argument. For example, function(x) mean(x, na.rm = TRUE) or \(x) mode(x, na.rm = TRUE) +#' @param na.rm logical(1). NA values are omitted when summary is calculated. +#' @return a data.frame object with function value +#' @author Insang Song \email{geoissong@@gmail.com} +#' +#' @export +extract_with_polygons <- function( + polys, surf, id, func = mean, na.rm = TRUE + ) { + # type check + stopifnot("Check class of the input points.\n" = any(is(polys, "sf"), is(polys, "SpatVector"))) + stopifnot("Check class of the input raster.\n" = any(is(surf, "stars"), is(surf, "SpatRaster"))) + stopifnot(is.character(id)) + + cls_polys = check_packbound(polys) + cls_surf = check_packbound(surf) + + if (cls_polys != cls_surf) { + polys = switch_packbound(polys) + } + + extract_with_polygons.sf = function(polys, surf, id, func) { + extracted = stars::st_extract(x = surf, at = polys, FUN = func) + # extracted = extracted |> + # group_by(!!sym(id)) |> + # summarize(across(-!!sym(id), ~func)) |> + # ungroup() + return(extracted) + } + + extract_with_polygons.terra = function(polys, surf, id, func) { + extracted = terra::extract(surf, polys) + extracted = extracted |> + group_by(!!sym(id)) |> + summarize(across(-!!sym(id), ~func)) |> + ungroup() + return(extracted) + } + + extracted_poly = switch( + cls_surf, + sf = extract_with_polygons.sf(polys = polys, surf = surf, id = id, func = func), + terra = extract_with_polygons.terra(polys = polys, surf = surf, id = id, func = func) + ) + return(extracted_poly) +} + + +#' Extract raster values with point buffers or polygons +#' +#' @param raster SpatRaster object. +#' @param vector SpatVector object. +#' @param id character(1). Unique identifier of each point. +#' @param func function taking one numeric vector argument. +#' @param mode one of "polygon" (generic polygons to extract raster values with) or "buffer" (point with buffer radius) +#' @param ... various. Passed to extract_with_buffer. See \code{?extract_with_buffer} for details. +#' @return +#' @author Insang Song \email{geoissong@@gmail.com} +#' @examples +#' # data +#' +#' # run +#' clip_with() +#' +#' @export +extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) { + if (!mode %in% c("polygon", "buffer")) { + stop("Argument 'mode' should be one of 'polygon' or 'buffer'.\n") + } + stopifnot(is.character(id)) + stopifnot(id %in% names(vector)) + + extracted = + switch(mode, + polygon = extract_with_polygons(vector, raster, id, func), + buffer = extract_with_buffer(vector, raster, id = id, func = func, ...)) + return(extracted) +} + + +#' Calculate SEDC covariates +#' @param point_from SpatVector object. Locations where the sum of SEDCs are calculated. +#' @param point_to SpatVector object. Locations where each SEDC is calculated. +#' @param sdec_bandwidth numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 %) +#' @param threshold numeric(1). For computational efficiency, the nearest points in threshold will be selected +#' @param target_fields character(varying). Field names in characters. +#' @description NOTE: sf implementation is pending. Only available for terra. +#' @author Insang Song +#' @export +calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, target_fields) { + # define sources, set SEDC exponential decay range + len_point_from = seq_len(nrow(point_from)) + len_point_to = seq_len(nrow(point_to)) + + point_from$from_id = len_point_from + # select egrid_v only if closer than 3e5 meters from each aqs + point_from_buf = terra::buffer(point_from_buf, threshold = threshold, quadsegs = 90) + point_to = point_to[point_from_buf,] + point_to$to_id = len_point_to + + # near features with distance argument: only returns integer indices + near_from_to = terra::nearby(point_from, point_to, distance = threshold) + # attaching actual distance + dist_near_to = terra::distance(point_from, point_to) + dist_near_to_df = as.vector(dist_near_to) + # adding integer indices + dist_near_to_tdf = expand.grid(from_id = len_point_from, to_id = len_point_to) + dist_near_to_df = cbind(dist_near_to_tdf, dist = dist_near_to_df) + + # summary + near_from_to = near_from_to |> + as_tibble() |> + left_join(data.frame(point_from)) |> + left_join(data.frame(point_to)) |> + left_join(dist_near_to_df) |> + # per the definition in https://mserre.sph.unc.edu/BMElab_web/SEDCtutorial/index.html + # exp(-3) is about 0.05 + mutate(w_sedc = exp((-3 * dist) / sedc_bandwidth)) |> + group_by(!!sym(id)) |> + summarize(across(all_of(target_fields), list(sedc = ~sum(w_sedc * ., na.rm = TRUE)))) |> + ungroup() + + invisible(near_from_to) + +} + + +#' Computing area weighted covariates using two polygon sf or SpatVector objects +#' @param poly_in A sf/SpatVector object at weighted means will be calculated. +#' @param poly_weight A sf/SpatVector object from which weighted means will be calculated. +#' @param id_poly_in character(1). The unique identifier of each polygon in poly_in +#' @return A data.frame with all numeric fields of area-weighted means. +#' @description When poly_in and poly_weight are different classes, poly_weight will be converted to the class of poly_in. +#' @author Insang Song \email{geoissong@@gmail.com} +#' @examples +#' # package +#' library(sf) +#' library(tictoc) +#' +#' # run +#' nc = st_read(system.file("shape/nc.shp", package="sf")) +#' nc = st_transform(nc, 5070) +#' pp = st_sample(nc, size = 300) +#' pp[["id"]] = seq(1,nrow(pp)) +#' st_crs(pp) = "EPSG:5070" +#' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +#' +#' tic() +#' ppb_nc_aw = aw_covariates(ppb, nc, 'id') +#' toc() +#' summary(ppb_nc_aw) +#' #### Example of aw_covariates ends #### +#' @export +aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { + stopifnot("Inputs have invalid classes.\n" = + is(poly_in, "sf") || is(poly_weight, "sf") || is(poly_in, "SpatVector") || is(poly_weight, "SpatVector")) + #check_crs() + aw_covariates.terra = function(poly_in, poly_weight, id_poly_in = id_poly_in) { + + poly_intersected = terra::intersect(poly_in, poly_weight) + poly_intersected[["area_segment_"]] = terra::expanse(poly_intersected) + poly_intersected = data.frame(poly_intersected) |> + dplyr::group_by(!!rlang::sym(id_poly_in)) |> + dplyr::summarize(across(is.numeric, + ~weighted.mean(., w = area_segment_))) |> + dplyr::ungroup() + return(poly_intersected) + } + + class_poly_in = check_packbound(poly_in) + class_poly_weight = check_packbound(poly_weight) + + if (class_poly_in != class_poly_weight) { + class_poly_weight = as(class_poly_weight, class(class_poly_in)[1]) + } + + switch(class_poly_in, + sf = sf::st_interpolate_aw(poly_weight, poly_in, extensive = FALSE), + terra = aw_covariates.terra(poly_in, poly_weight, id_poly_in = id_poly_in)) + +} + +# ncbuf = terra::intersect(vect(ppb), vect(nc)) +# ncbuf_a = ncbuf +# ncbuf_a$segarea = expanse(ncbuf_a) +# ncbuf_k = data.frame(ncbuf_a) |> +# dplyr::group_by(id) |> +# dplyr::summarize(across(is.numeric, +# ~weighted.mean(., w = segarea))) |> +# dplyr::ungroup() + +#ncbufagg = terra::aggregate(ncbuf, by = 'id', fun = weighted.mean, w = ncbuf_a$segarea) + + +#' Subfunction: extract with buffers (flat weight; simple mean) +#' +#' @export +extract_with_buffer.flat <- function( + points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL + ) { + # generate buffers + bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + # crop raster + bufs_extent = terra::ext(bufs) + surf_cropped = terra::crop(surf, bufs_extent) + name_surf_val = names(surf) + # extract raster values + surf_at_bufs = terra::extract(surf_cropped, bufs) + surf_at_bufs_summary = + surf_at_bufs |> + group_by(ID) |> + summarize(across(all_of(name_surf_val), ~mean, na.rm=T)) |> + ungroup() + return(surf_at_bufs_summary) +} + +#' Subfunction: extract with buffers (kernel weight; weighted mean) +#' +#' @export +extract_with_buffer.kernel <- function( + points, surf, radius, id, qsegs, func = mean, kernel, bandwidth + ) { + # generate buffers + bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + # crop raster + bufs_extent = terra::ext(bufs) + surf_cropped = terra::crop(surf, bufs_extent) + name_surf_val = names(surf) + + # TODO: kernel implementation + + + # extract raster values + surf_at_bufs = terra::extract(surf_cropped, bufs) + surf_at_bufs_summary = + surf_at_bufs |> + group_by(ID) |> + summarize(across(all_of(name_surf_val), ~mean, na.rm=T)) |> + ungroup() + return(surf_at_bufs_summary) +} + +#' @title Extract summarized values from raster with points and a buffer radius (to be written) +#' +#' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. +#' @param points SpatVector object. Coordinates where buffers will be generated +#' @param surf SpatRaster object. A raster of whatnot a summary will be calculated +#' @param radius numeric(1). Buffer radius. here we assume circular buffers only +#' @param id character(1). Unique identifier of each point. +#' @param qsegs integer(1). Number of vertices at a quarter of a circle. Default is 90. +#' @param func a function taking a numeric vector argument. +#' @param kernel character(1). Name of a kernel function (yet to be implemented) +#' @param bandwidth numeric(1). Kernel bandwidth. +#' @return a data.frame object with mean value +#' @author Insang Song \email{geoissong@@gmail.com} +#' +#' @export +extract_with_buffer <- function( + points, surf, radius, id, qsegs = 90, func = mean, kernel = NULL, bandwidth = NULL + ) { + # type check + stopifnot("Check class of the input points.\n" = is(points, "SpatVector")) + stopifnot("Check class of the input radius.\n" = is.numeric(radius)) + stopifnot(is.character(id)) + stopifnot(is.integer(qsegs)) + + if (!is.null(kernel)) { + extracted = extract_with_buffer.flat(points = points, + surf = surf, + radius = radius, + id = id, + func = func, + qsegs = qsegs) + return(extracted) + } + + extracted = extract_with_buffer.kernel(points = points, + surf = surf, + radius = radius, + id = id, + func = func, + qsegs = qsegs, + kernel = kernel, + bandwidth = bandwidth) + return(extracted) + +} + + + diff --git a/scomps/R/rast_short.R b/scomps/R/rast_short.R deleted file mode 100644 index 042d12f5..00000000 --- a/scomps/R/rast_short.R +++ /dev/null @@ -1,12 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Quick call for SpatRaster with a window -#' -#' @param rasterpath character(1). Path to the raster file. -#' @param win Named integer vector (4) or terra::ext() results. -#' @param author Insang Song -#' @export -rast_short <- function(rasterpath, win) { - terra::rast(rasterpath, win = win) -} - diff --git a/scomps/R/switch_packbound.R b/scomps/R/switch_format.R similarity index 100% rename from scomps/R/switch_packbound.R rename to scomps/R/switch_format.R diff --git a/scomps/R/validate_and_repair_vectors.R b/scomps/R/validate.R similarity index 100% rename from scomps/R/validate_and_repair_vectors.R rename to scomps/R/validate.R diff --git a/scomps/tests/testthat/tests.R b/scomps/tests/testthat/tests.R index 35965382..6efa4142 100644 --- a/scomps/tests/testthat/tests.R +++ b/scomps/tests/testthat/tests.R @@ -21,14 +21,45 @@ testthat::test_that("What package does the input object belong?", withr::local_package("stars") withr::local_package("terra") withr::local_options(list(sf_use_s2 = FALSE)) - data(stars_sentinel2) + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + nc = system.file(package = "sf", "shape/nc.shp") nc = sf::read_sf(nc) - datatype_stars = check_datatype(stars_sentinel2) + datatype_stars = check_datatype(bcsd_stars) datatype_sf = check_datatype(nc) testthat::expect_equal(datatype_stars, "raster") testthat::expect_equal(datatype_sf, "vector") }) + +testthat::test_that("Format is well converted", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + + # starts from sf/stars + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + nc = system.file(package = "sf", "shape/nc.shp") + nc = sf::read_sf(nc) + + stars_bcsd_tr = switch_packbound(bcsd_stars) + sf_nc_tr = switch_packbound(nc) + + testthat::expect_equal(check_packbound(stars_bcsd_tr), "terra") + testthat::expect_equal(check_packbound(sf_nc_tr), "terra") + + stars_bcsd_trb = switch_packbound(stars_bcsd_tr) + sf_nc_trb = switch_packbound(sf_nc_tr) + + testthat::expect_equal(check_packbound(stars_bcsd_trb), "sf") + testthat::expect_equal(check_packbound(sf_nc_trb), "sf") + +}) + + + diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index 974a9d21..240b4444 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -368,7 +368,7 @@

Package setup

path = ".", fields = list( Package = params$package_name, - Version = "0.0.2.10022023", + Version = "0.0.2.10032023", Title = "Scalable R geospatial computation", Description = "A package for scalable geospatial computation for environmental health research", `Authors@R` = person( @@ -463,11 +463,13 @@

Create functions

withr::local_package("stars") withr::local_package("terra") withr::local_options(list(sf_use_s2 = FALSE)) - data(stars_sentinel2) + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + nc = system.file(package = "sf", "shape/nc.shp") nc = sf::read_sf(nc) - datatype_stars = check_datatype(stars_sentinel2) + datatype_stars = check_datatype(bcsd_stars) datatype_sf = check_datatype(nc) testthat::expect_equal(datatype_stars, "raster") @@ -475,7 +477,8 @@

Create functions

})
## pr, tas, 
 ## Test passed
-
## Test passed
+
## pr, tas, 
+## Test passed
#' @title Switch spatial data class
 #' @description Convert stars into SpatRaster and vice versa; sf into SpatVector and vice versa.
 #' @author Insang Song
@@ -499,6 +502,36 @@ 

Create functions

invisible(switched) }
+

+testthat::test_that("Format is well converted",
+{
+    withr::local_package("stars")
+    withr::local_package("terra")
+    withr::local_options(list(sf_use_s2 = FALSE))
+
+    # starts from sf/stars
+    bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc")
+    bcsd_stars = stars::read_stars(bcsd_path)
+    nc = system.file(package = "sf", "shape/nc.shp")
+    nc = sf::read_sf(nc)
+
+    stars_bcsd_tr = switch_packbound(bcsd_stars)
+    sf_nc_tr = switch_packbound(nc)
+
+    testthat::expect_equal(check_packbound(stars_bcsd_tr), "terra")
+    testthat::expect_equal(check_packbound(sf_nc_tr), "terra")
+
+    stars_bcsd_trb = switch_packbound(stars_bcsd_tr)
+    sf_nc_trb = switch_packbound(sf_nc_tr)
+
+    testthat::expect_equal(check_packbound(stars_bcsd_trb), "sf")
+    testthat::expect_equal(check_packbound(sf_nc_trb), "sf")
+
+})
+
+
+
## pr, tas, 
+## Test passed
#' @title check_crs2: Coordinate system checker
 #' @description The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179.
 #' @param input Input object one of sf or terra::Spat* object
@@ -1308,44 +1341,47 @@ 

Documenting the package and building

## ℹ Updating scomps documentation
 ## ℹ Loading scomps
-
## Warning: [check_crs.R:6] @description requires a value
-
## Warning: [extract_with.R:11] @return requires a value
+
## Warning: [check.R:92] @description requires a value
+
## Warning: [processing.R:139] @return requires a value
## Writing 'NAMESPACE'
-## Writing 'aw_covariates.Rd'
-## Writing 'calculate_sedc.Rd'
+## Writing 'check_packbound.Rd'
+## Writing 'check_crs2.Rd'
 ## Writing 'check_bbox.Rd'
 ## Writing 'check_crs.Rd'
-## Writing 'check_crs2.Rd'
-## Writing 'check_packbound.Rd'
 ## Writing 'check_within_reference.Rd'
-## Writing 'clip_as_extent.Rd'
-## Writing 'clip_as_extent_ras.Rd'
-## Writing 'clip_as_extent_ras2.Rd'
-## Writing 'distribute_process.Rd'
 ## Writing 'estimate_demands.Rd'
-## Writing 'extract_with.Rd'
-## Writing 'extract_with_buffer.Rd'
-## Writing 'extract_with_buffer.flat.Rd'
-## Writing 'extract_with_buffer.kernel.Rd'
-## Writing 'extract_with_polygons.Rd'
+## Writing 'sp_indexing.Rd'
 ## Writing 'get_computational_regions.Rd'
 ## Writing 'sp_index_grid.Rd'
 ## Writing 'grid_merge.Rd'
+## Writing 'distribute_process.Rd'
 ## Writing 'initate_log.Rd'
-## Writing 'rast_short.Rd'
 ## Writing 'set_clip_extent.Rd'
-## Writing 'sp_indexing.Rd'
+## Writing 'rast_short.Rd'
+## Writing 'clip_as_extent.Rd'
+## Writing 'clip_as_extent_ras.Rd'
+## Writing 'clip_as_extent_ras2.Rd'
+## Writing 'extract_with_polygons.Rd'
+## Writing 'extract_with.Rd'
+## Writing 'calculate_sedc.Rd'
+## Writing 'aw_covariates.Rd'
+## Writing 'extract_with_buffer.flat.Rd'
+## Writing 'extract_with_buffer.kernel.Rd'
+## Writing 'extract_with_buffer.Rd'
 ## Writing 'switch_packbound.Rd'
 ## Writing 'validate_and_repair_vectors.Rd'
## ℹ Testing scomps
## ✔ | F W S  OK | Context
 ## 
 ## ⠏ |         0 | tests                                                           pr, tas, 
+## pr, tas, 
+## pr, tas, 
 ## 
-## ✔ |         4 | tests
+## ⠼ |         5 | tests                                                           
+## ✔ |         8 | tests
 ## 
 ## ══ Results ═════════════════════════════════════════════════════════════════════
-## [ FAIL 0 | WARN 0 | SKIP 0 | PASS 4 ]
+## [ FAIL 0 | WARN 0 | SKIP 0 | PASS 8 ]
## ── R CMD build ─────────────────────────────────────────────────────────────────
 ## * checking for file ‘/Users/songi2/Documents/GitHub/Scalable_GIS/scomps/DESCRIPTION’ ... OK
 ## * preparing ‘scomps’:
@@ -1361,18 +1397,12 @@ 

Documenting the package and building

## * checking for LF line-endings in source and make files and shell scripts ## * checking for empty or unneeded directories ## Removed empty directory ‘scomps/build’ -## * building ‘scomps_0.0.2.10022023.tar.gz’ +## * building ‘scomps_0.0.2.10032023.tar.gz’ ## Warning: invalid uid value replaced by that for user 'nobody' ## Warning: invalid gid value replaced by that for user 'nobody'
-
## [1] "/Users/songi2/Documents/GitHub/Scalable_GIS/scomps_0.0.2.10022023.tar.gz"
-
## curl (5.0.2 -> 5.1.0) [CRAN]
-
## Installing 1 packages: curl
-## Installing package into '/Users/songi2/Library/R/arm64/4.3/library'
-## (as 'lib' is unspecified)
-
## 
-## The downloaded binary packages are in
-##  /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpLf04ac/downloaded_packages
-## ── R CMD build ─────────────────────────────────────────────────────────────────
+
## [1] "/Users/songi2/Documents/GitHub/Scalable_GIS/scomps_0.0.2.10032023.tar.gz"
+
## Skipping 1 packages ahead of CRAN: data.table
+
## ── R CMD build ─────────────────────────────────────────────────────────────────
 ## * checking for file ‘/Users/songi2/Documents/GitHub/Scalable_GIS/scomps/DESCRIPTION’ ... OK
 ## * preparing ‘scomps’:
 ## * checking DESCRIPTION meta-information ... OK
@@ -1387,12 +1417,12 @@ 

Documenting the package and building

## * checking for LF line-endings in source and make files and shell scripts ## * checking for empty or unneeded directories ## Removed empty directory ‘scomps/build’ -## * building ‘scomps_0.0.2.10022023.tar.gz’ +## * building ‘scomps_0.0.2.10032023.tar.gz’ ## Warning: invalid uid value replaced by that for user 'nobody' ## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpLf04ac/scomps_0.0.2.10022023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//Rtmp2UqRyZ/scomps_0.0.2.10032023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index f3767faf..e67a1222 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -21,7 +21,7 @@ usethis::create_package( path = ".", fields = list( Package = params$package_name, - Version = "0.0.2.10022023", + Version = "0.0.2.10032023", Title = "Scalable R geospatial computation", Description = "A package for scalable geospatial computation for environmental health research", `Authors@R` = person( @@ -79,7 +79,7 @@ litr::add_vignettes("../vignettes-sources/01_generate_computational_grid.Rmd") # Now to the package itself ### Create functions -```{r} +```{r, send_to = "R/check.R"} #' @title Return the package the input object is based on #' @description Detect whether the input object is sf or Spat* object. #' @author Insang Song @@ -129,11 +129,13 @@ testthat::test_that("What package does the input object belong?", withr::local_package("stars") withr::local_package("terra") withr::local_options(list(sf_use_s2 = FALSE)) - data(stars_sentinel2) + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + nc = system.file(package = "sf", "shape/nc.shp") nc = sf::read_sf(nc) - datatype_stars = check_datatype(stars_sentinel2) + datatype_stars = check_datatype(bcsd_stars) datatype_sf = check_datatype(nc) testthat::expect_equal(datatype_stars, "raster") @@ -141,7 +143,7 @@ testthat::test_that("What package does the input object belong?", }) ``` -```{r} +```{r, send_to = "R/switch_format.R"} #' @title Switch spatial data class #' @description Convert stars into SpatRaster and vice versa; sf into SpatVector and vice versa. #' @author Insang Song @@ -169,6 +171,37 @@ switch_packbound <- function(input) { ```{r} + +testthat::test_that("Format is well converted", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + + # starts from sf/stars + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + nc = system.file(package = "sf", "shape/nc.shp") + nc = sf::read_sf(nc) + + stars_bcsd_tr = switch_packbound(bcsd_stars) + sf_nc_tr = switch_packbound(nc) + + testthat::expect_equal(check_packbound(stars_bcsd_tr), "terra") + testthat::expect_equal(check_packbound(sf_nc_tr), "terra") + + stars_bcsd_trb = switch_packbound(stars_bcsd_tr) + sf_nc_trb = switch_packbound(sf_nc_tr) + + testthat::expect_equal(check_packbound(stars_bcsd_trb), "sf") + testthat::expect_equal(check_packbound(sf_nc_trb), "sf") + +}) + + +``` + +```{r, send_to = "R/check.R"} #' @title check_crs2: Coordinate system checker #' @description The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179. #' @param input Input object one of sf or terra::Spat* object @@ -198,7 +231,7 @@ check_crs2 <- function(input, crs_standard = "EPSG:4326") { } ``` -```{r} +```{r, send_to = "R/validate.R"} #' Validate and repair input vector data #' @description It tries repairing input vector data. Vector validity violation usually appears in polygon data with self-crossing or hole orders. This function will pass the input_vector object to sf::st_make_valid() (if input_vector is sf) or terra::makeValid() (if input_vector is SpatVector). May take some time depending on the geometry complexity. #' @author Insang Song @@ -218,7 +251,7 @@ validate_and_repair_vectors <- function(input_vector) { ``` -```{r} +```{r, send_to = "R/logging.R"} #' Turn on logging #' @author Insang Song #' @param expr expression. Any function call to be logged. @@ -239,7 +272,7 @@ initate_log <- function(expr, dolog = FALSE, logpath) { ``` -```{r} +```{r, send_to = "R/preprocessing.R"} #' Setting the clipping extent #' @description Return clipping extent with buffer radius. It assumes the input CRS is projected and linear unit is meters. #' @author Insang Song @@ -265,7 +298,7 @@ set_clip_extent <- function(pnts, buffer_r) { ``` -```{r} +```{r, send_to = "R/processing.R"} #' Extent clipping #' @description Clip input vector by the expected maximum extent of computation. #' @author Insang Song @@ -304,7 +337,7 @@ clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input){ ``` -```{r} +```{r, send_to = "R/processing.R"} #' @title clip_as_extent_ras: Clip input raster. #' @description Clip input raster by the expected maximum extent of computation. #' @author Insang Song @@ -326,7 +359,7 @@ clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras){ ``` -```{r} +```{r, send_to = "R/processing.R"} #' @title clip_as_extent_ras2: Clip input raster (version 2). #' @description Clip input raster by the expected maximum extent of computation. #' @author Insang Song @@ -348,7 +381,7 @@ clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras){ ``` -```{r} +```{r, send_to = "R/indexing.R"} #' @title Create integer indices for grid #' @description Returns a tibble object that includes x- and y- index by using two inputs ncutsx and ncutsy, which are x- and y-directional splits, respectively. #' @author Insang Song @@ -374,7 +407,7 @@ sp_indexing <- function(points_in, ncutsx, ncutsy){ } ``` -```{r} +```{r, send_to = "R/preprocessing.R"} #' Quick call for SpatRaster with a window #' #' @param rasterpath character(1). Path to the raster file. @@ -414,7 +447,7 @@ estimate_demands <- function( ``` -```{r} +```{r, send_to = "R/interpret_computational_domain.R"} #' Get a set of computational regions #' #' @param input sf or Spat* object. @@ -585,7 +618,7 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ -```{r} +```{r, send_to = "R/check.R"} #' Check if the data extent is inside the reference bounding box #' #' @description One of the most common errors in spatial computation is rooted in the entirely or partly incomparable spatial extents of input datasets. This function returns whether your data is inside the target computational extent. It is assumed that you know and have the exact computational region. This function will return TRUE if the reference region completely contains your data's extent and FALSE otherwise. @@ -636,7 +669,7 @@ check_bbox <- function( ``` -```{r} +```{r, send_to = "R/processing.R"} #' @title Extract summarized values from raster with generic polygons #' #' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. @@ -692,7 +725,7 @@ extract_with_polygons <- function( ``` -```{r} +```{r, send_to = "R/processing.R"} #' Extract raster values with point buffers or polygons #' #' @param raster SpatRaster object. @@ -726,7 +759,7 @@ extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) ``` -```{r} +```{r, send_to = "R/check.R"} #' Check Coordinate Reference System #' @param x sf/stars/SpatVector/SpatRaster object. #' @return A st_crs or crs object. @@ -755,7 +788,7 @@ check_crs <- function(x) { ``` -```{r} +```{r, send_to = "R/check.R"} #' Check if the boundary of the vector/raster object is inside the reference #' @param input_object sf/stars/SpatVector/SpatRaster object. #' @param reference sf/stars/SpatVector/SpatRaster object. @@ -784,7 +817,7 @@ check_within_reference <- function(input_object, reference) { ``` -```{r} +```{r, send_to = "R/processing.R"} #' Calculate SEDC covariates #' @param point_from SpatVector object. Locations where the sum of SEDCs are calculated. #' @param point_to SpatVector object. Locations where each SEDC is calculated. @@ -833,7 +866,7 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, ``` -```{r} +```{r, send_to = "R/processing.R"} #' Computing area weighted covariates using two polygon sf or SpatVector objects #' @param poly_in A sf/SpatVector object at weighted means will be calculated. #' @param poly_weight A sf/SpatVector object from which weighted means will be calculated. @@ -902,7 +935,7 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { ``` -```{r} +```{r, send_to = "R/processing.R"} #' Subfunction: extract with buffers (flat weight; simple mean) #' #' @export @@ -926,7 +959,7 @@ extract_with_buffer.flat <- function( } ``` -```{r} +```{r, send_to = "R/processing.R"} #' Subfunction: extract with buffers (kernel weight; weighted mean) #' #' @export @@ -955,7 +988,7 @@ extract_with_buffer.kernel <- function( ``` -```{r} +```{r, send_to = "R/processing.R"} #' @title Extract summarized values from raster with points and a buffer radius (to be written) #' #' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. @@ -1007,7 +1040,7 @@ extract_with_buffer <- function( ``` -```{r} +```{r, send_to = "R/interpret_computational_domain.R"} #' @title Process a given function in the entire or partial computational grids (under construction) #' #' @description Should diff --git a/tarballs/scomps_0.0.2.10032023.tar.gz b/tarballs/scomps_0.0.2.10032023.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..9f194ddcd35c000903b9fc653b4d0ac6bdfe2624 GIT binary patch literal 21871 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 Yw*IU?>(BbL{$!v3A9$XTg8=3M0Md*I&j0`b literal 0 HcmV?d00001 From 9ca2eae5c6374ff5266257aa249b38bab88be780 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 12:05:22 -0400 Subject: [PATCH 04/21] Directory restructuring - While keeping litr Rmd, others were adjusted - codecov edit to find if it works --- .github/workflows/codecov.yaml | 2 +- {containers => tools/containers}/apptainer_rocker | 0 .../slurm_test}/merra1h_aero_extract.r | 0 .../slurm_test}/merra1h_aero_extract_local.r | 0 .../slurm_test}/merra1h_aero_extract_local_stars.r | 0 .../slurm_test}/terra_runs_Rcode_file copy.sh | 0 .../slurm_test}/terra_runs_Rcode_file.sh | 0 .../tarballs}/scomps_0.0.1.09032023.tar.gz | Bin .../tarballs}/scomps_0.0.2.09152023.tar.gz | Bin .../tarballs}/scomps_0.0.2.09192023.tar.gz | Bin .../tarballs}/scomps_0.0.2.10022023.tar.gz | Bin .../tarballs}/scomps_0.0.2.10032023.tar.gz | Bin .../00_good_practice_parallelization.Rmd | 0 .../01_generate_computational_grid.Rmd | 0 14 files changed, 1 insertion(+), 1 deletion(-) rename {containers => tools/containers}/apptainer_rocker (100%) rename {slurm_test => tools/slurm_test}/merra1h_aero_extract.r (100%) rename {slurm_test => tools/slurm_test}/merra1h_aero_extract_local.r (100%) rename {slurm_test => tools/slurm_test}/merra1h_aero_extract_local_stars.r (100%) rename {slurm_test => tools/slurm_test}/terra_runs_Rcode_file copy.sh (100%) rename {slurm_test => tools/slurm_test}/terra_runs_Rcode_file.sh (100%) rename {tarballs => tools/tarballs}/scomps_0.0.1.09032023.tar.gz (100%) rename {tarballs => tools/tarballs}/scomps_0.0.2.09152023.tar.gz (100%) rename {tarballs => tools/tarballs}/scomps_0.0.2.09192023.tar.gz (100%) rename {tarballs => tools/tarballs}/scomps_0.0.2.10022023.tar.gz (100%) rename {tarballs => tools/tarballs}/scomps_0.0.2.10032023.tar.gz (100%) rename {vignettes-sources => tools/vignettes-sources}/00_good_practice_parallelization.Rmd (100%) rename {vignettes-sources => tools/vignettes-sources}/01_generate_computational_grid.Rmd (100%) diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 30ba6e81..779871b8 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -27,7 +27,7 @@ jobs: path: | ~/.cache/R ~/.local/share/R - key: dependencies-${{ runner.os }}-${{ hashFiles('**/scomps/DESCRIPTION') }} + key: dependencies-${{ runner.os }}-${{ hashFiles('**/**/DESCRIPTION') }} restore-keys: | dependencies-${{ runner.os }}- diff --git a/containers/apptainer_rocker b/tools/containers/apptainer_rocker similarity index 100% rename from containers/apptainer_rocker rename to tools/containers/apptainer_rocker diff --git a/slurm_test/merra1h_aero_extract.r b/tools/slurm_test/merra1h_aero_extract.r similarity index 100% rename from slurm_test/merra1h_aero_extract.r rename to tools/slurm_test/merra1h_aero_extract.r diff --git a/slurm_test/merra1h_aero_extract_local.r b/tools/slurm_test/merra1h_aero_extract_local.r similarity index 100% rename from slurm_test/merra1h_aero_extract_local.r rename to tools/slurm_test/merra1h_aero_extract_local.r diff --git a/slurm_test/merra1h_aero_extract_local_stars.r b/tools/slurm_test/merra1h_aero_extract_local_stars.r similarity index 100% rename from slurm_test/merra1h_aero_extract_local_stars.r rename to tools/slurm_test/merra1h_aero_extract_local_stars.r diff --git a/slurm_test/terra_runs_Rcode_file copy.sh b/tools/slurm_test/terra_runs_Rcode_file copy.sh similarity index 100% rename from slurm_test/terra_runs_Rcode_file copy.sh rename to tools/slurm_test/terra_runs_Rcode_file copy.sh diff --git a/slurm_test/terra_runs_Rcode_file.sh b/tools/slurm_test/terra_runs_Rcode_file.sh similarity index 100% rename from slurm_test/terra_runs_Rcode_file.sh rename to tools/slurm_test/terra_runs_Rcode_file.sh diff --git a/tarballs/scomps_0.0.1.09032023.tar.gz b/tools/tarballs/scomps_0.0.1.09032023.tar.gz similarity index 100% rename from tarballs/scomps_0.0.1.09032023.tar.gz rename to tools/tarballs/scomps_0.0.1.09032023.tar.gz diff --git a/tarballs/scomps_0.0.2.09152023.tar.gz b/tools/tarballs/scomps_0.0.2.09152023.tar.gz similarity index 100% rename from tarballs/scomps_0.0.2.09152023.tar.gz rename to tools/tarballs/scomps_0.0.2.09152023.tar.gz diff --git a/tarballs/scomps_0.0.2.09192023.tar.gz b/tools/tarballs/scomps_0.0.2.09192023.tar.gz similarity index 100% rename from tarballs/scomps_0.0.2.09192023.tar.gz rename to tools/tarballs/scomps_0.0.2.09192023.tar.gz diff --git a/tarballs/scomps_0.0.2.10022023.tar.gz b/tools/tarballs/scomps_0.0.2.10022023.tar.gz similarity index 100% rename from tarballs/scomps_0.0.2.10022023.tar.gz rename to tools/tarballs/scomps_0.0.2.10022023.tar.gz diff --git a/tarballs/scomps_0.0.2.10032023.tar.gz b/tools/tarballs/scomps_0.0.2.10032023.tar.gz similarity index 100% rename from tarballs/scomps_0.0.2.10032023.tar.gz rename to tools/tarballs/scomps_0.0.2.10032023.tar.gz diff --git a/vignettes-sources/00_good_practice_parallelization.Rmd b/tools/vignettes-sources/00_good_practice_parallelization.Rmd similarity index 100% rename from vignettes-sources/00_good_practice_parallelization.Rmd rename to tools/vignettes-sources/00_good_practice_parallelization.Rmd diff --git a/vignettes-sources/01_generate_computational_grid.Rmd b/tools/vignettes-sources/01_generate_computational_grid.Rmd similarity index 100% rename from vignettes-sources/01_generate_computational_grid.Rmd rename to tools/vignettes-sources/01_generate_computational_grid.Rmd From 661866aa9f8699e10dd795bcff35421ec0537e16 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 12:53:49 -0400 Subject: [PATCH 05/21] YAML working directory edit --- .github/workflows/check-standard.yaml | 1 + .github/workflows/codecov.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-standard.yaml b/.github/workflows/check-standard.yaml index a71ab36e..0e914c84 100644 --- a/.github/workflows/check-standard.yaml +++ b/.github/workflows/check-standard.yaml @@ -38,6 +38,7 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: + working-directory: "./scomps" extra-packages: any::rcmdcheck needs: check diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 779871b8..bff599f3 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -27,7 +27,7 @@ jobs: path: | ~/.cache/R ~/.local/share/R - key: dependencies-${{ runner.os }}-${{ hashFiles('**/**/DESCRIPTION') }} + key: dependencies-${{ runner.os }}-${{ hashFiles('**/DESCRIPTION') }} restore-keys: | dependencies-${{ runner.os }}- From 01d2064aec02d251ce18ecea9da4423ed5ad34da Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 13:10:23 -0400 Subject: [PATCH 06/21] Added working-directory in relevant entries --- .github/workflows/check-standard.yaml | 1 + .github/workflows/codecov.yaml | 1 + .github/workflows/test-coverage.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/workflows/check-standard.yaml b/.github/workflows/check-standard.yaml index 0e914c84..70f743d2 100644 --- a/.github/workflows/check-standard.yaml +++ b/.github/workflows/check-standard.yaml @@ -44,4 +44,5 @@ jobs: - uses: r-lib/actions/check-r-package@v2 with: + working-directory: "./scomps" upload-snapshots: true diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index bff599f3..34b8f901 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -56,6 +56,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} coverage_reports: ${{ github.workspace }}/coverage.xml + working-directory: "./scomps" - name: Cleanup run: | diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index ad146389..c34f5922 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -26,6 +26,7 @@ jobs: with: extra-packages: any::covr needs: coverage + working-directory: "./scomps" - name: Test coverage run: | From c6946d3977a9cc9212cab701b2dd4802bf2502cd Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 13:18:15 -0400 Subject: [PATCH 07/21] package path fix (2) --- .github/workflows/codecov.yaml | 4 ++-- .github/workflows/test-coverage.yaml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 34b8f901..cb8a71b8 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -40,7 +40,7 @@ jobs: - name: Install dependencies run: | R -e 'install.packages("remotes")' - R -e 'remotes::install_deps()' + R -e 'remotes::install_deps(pkgdir = "./scomps")' - name: Install dependencies for covr and testthat run: R -e 'install.packages(c("covr", "testthat"), dependencies = TRUE)' @@ -48,7 +48,7 @@ jobs: - name: Run tests and calculate coverage run: | echo "Current working directory: $(pwd)" - R -e 'library(covr); covr::package_coverage(coverage_file = "coverage.xml")' + R -e 'library(covr); covr::package_coverage(path = "./scomps", coverage_file = "coverage.xml")' - name: Upload coverage to Codecov diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index c34f5922..545aea4a 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -31,6 +31,7 @@ jobs: - name: Test coverage run: | covr::codecov( + path = "./scomps", quiet = FALSE, clean = FALSE, install_path = file.path(Sys.getenv("RUNNER_TEMP"), "package") From 8f1433058d1c09cc53e8d77b7b3c8bc798cd3764 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 13:27:21 -0400 Subject: [PATCH 08/21] Edited DESCRIPTION - added stars in "Imports" --- scomps/DESCRIPTION | 3 ++- scomps_rmarkdown_litr.html | 7 ++++--- scomps_rmarkdown_litr.rmd | 5 +++-- tools/tarballs/scomps_0.0.2.10032023.tar.gz | Bin 21871 -> 21884 bytes 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index 2f72afbd..90815873 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -18,6 +18,7 @@ Imports: future.apply, rlang, sf, + stars, terra, testthat Suggests: @@ -30,4 +31,4 @@ Suggests: VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: 7c9484dd9127c939a90d433ec83cd305 +LitrId: f6481d6de18f4e515f064d81bc8ae4ed diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index 240b4444..35f9efea 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -385,6 +385,7 @@

Package setup

usethis::use_package("sf") # Default is "Imports" # usethis::use_package("stars") # Default is "Imports" usethis::use_package("terra") # Default is "Imports" +usethis::use_package("stars") usethis::use_package("rlang") # Default is "Imports" usethis::use_package("testthat") usethis::use_package("logr", "Suggests") # Default is "Imports" @@ -406,11 +407,11 @@

Package setup

Vignettes 1

-
litr::add_vignettes("../vignettes-sources/00_good_practice_parallelization.Rmd")
+
litr::add_vignettes("../tools/vignettes-sources/00_good_practice_parallelization.Rmd")

Vignettes 2

-
litr::add_vignettes("../vignettes-sources/01_generate_computational_grid.Rmd")
+
litr::add_vignettes("../tools/vignettes-sources/01_generate_computational_grid.Rmd")
@@ -1422,7 +1423,7 @@

Documenting the package and building

## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//Rtmp2UqRyZ/scomps_0.0.2.10032023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpfPUv07/scomps_0.0.2.10032023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index e67a1222..d0608b0c 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -38,6 +38,7 @@ usethis::use_package("dplyr") # Default is "Imports" usethis::use_package("sf") # Default is "Imports" # usethis::use_package("stars") # Default is "Imports" usethis::use_package("terra") # Default is "Imports" +usethis::use_package("stars") usethis::use_package("rlang") # Default is "Imports" usethis::use_package("testthat") usethis::use_package("logr", "Suggests") # Default is "Imports" @@ -66,13 +67,13 @@ usethis::use_package("future.batchtools", "Suggests") # Default is "Imports" ### Vignettes 1 ```{r} -litr::add_vignettes("../vignettes-sources/00_good_practice_parallelization.Rmd") +litr::add_vignettes("../tools/vignettes-sources/00_good_practice_parallelization.Rmd") ``` ### Vignettes 2 ```{r} -litr::add_vignettes("../vignettes-sources/01_generate_computational_grid.Rmd") +litr::add_vignettes("../tools/vignettes-sources/01_generate_computational_grid.Rmd") ``` diff --git a/tools/tarballs/scomps_0.0.2.10032023.tar.gz b/tools/tarballs/scomps_0.0.2.10032023.tar.gz index 9f194ddcd35c000903b9fc653b4d0ac6bdfe2624..6ac28a5d720b22e5a7de6fa4cfc69d66c1ae344e 100644 GIT binary patch delta 20607 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

j7BK7 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 delta 20605 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 From dd2151930afaf63bf58c6da4a3dc686706e5c717 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 15:33:01 -0400 Subject: [PATCH 09/21] YAML fix - removed codecov.yaml - dependencies fix - codecov path fix --- .github/workflows/check-standard.yaml | 5 ++- .github/workflows/codecov.yaml | 63 --------------------------- .github/workflows/test-coverage.yaml | 8 +++- 3 files changed, 10 insertions(+), 66 deletions(-) delete mode 100644 .github/workflows/codecov.yaml diff --git a/.github/workflows/check-standard.yaml b/.github/workflows/check-standard.yaml index 70f743d2..8592acbe 100644 --- a/.github/workflows/check-standard.yaml +++ b/.github/workflows/check-standard.yaml @@ -39,7 +39,10 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: working-directory: "./scomps" - extra-packages: any::rcmdcheck + packages: | + any::tictoc + any::units + any::rcmdcheck needs: check - uses: r-lib/actions/check-r-package@v2 diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml deleted file mode 100644 index cb8a71b8..00000000 --- a/.github/workflows/codecov.yaml +++ /dev/null @@ -1,63 +0,0 @@ -on: - push: - branches: - - main - pull_request: - branches: - - main - -name: R Package CI - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Set up R - uses: r-lib/actions/setup-r@v2 - with: - r-version: 4.1 # You can change this to the R version you need - - - name: Cache C++ and R dependencies - uses: actions/cache@v2 - with: - path: | - ~/.cache/R - ~/.local/share/R - key: dependencies-${{ runner.os }}-${{ hashFiles('**/DESCRIPTION') }} - restore-keys: | - dependencies-${{ runner.os }}- - - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y libudunits2-dev libgdal-dev - - - - name: Install dependencies - run: | - R -e 'install.packages("remotes")' - R -e 'remotes::install_deps(pkgdir = "./scomps")' - - - name: Install dependencies for covr and testthat - run: R -e 'install.packages(c("covr", "testthat"), dependencies = TRUE)' - - - name: Run tests and calculate coverage - run: | - echo "Current working directory: $(pwd)" - R -e 'library(covr); covr::package_coverage(path = "./scomps", coverage_file = "coverage.xml")' - - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.CODECOV_TOKEN }} - coverage_reports: ${{ github.workspace }}/coverage.xml - working-directory: "./scomps" - - - name: Cleanup - run: | - R -e 'remove.packages("remotes")' diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 545aea4a..f99a35d4 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -24,7 +24,11 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::covr + packages: | + any::covr + any::tictoc + any::units + any::spData needs: coverage working-directory: "./scomps" @@ -54,4 +58,4 @@ jobs: - name: Upload coverage to Codecov # Add this step run: | - Rscript -e "covr::codecov(token = Sys.getenv('CODECOV_TOKEN'))" + Rscript -e "covr::codecov(path = "./scomps", token = Sys.getenv('CODECOV_TOKEN'))" From 6189b52efbe88f95d6f204f0ebe02cb8980bb4b3 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 15:36:16 -0400 Subject: [PATCH 10/21] knitr error fix --- .github/workflows/check-standard.yaml | 3 +++ .github/workflows/test-coverage.yaml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/.github/workflows/check-standard.yaml b/.github/workflows/check-standard.yaml index 8592acbe..f2288234 100644 --- a/.github/workflows/check-standard.yaml +++ b/.github/workflows/check-standard.yaml @@ -43,6 +43,9 @@ jobs: any::tictoc any::units any::rcmdcheck + any::spData + any::knitr + any::rmarkdown needs: check - uses: r-lib/actions/check-r-package@v2 diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index f99a35d4..c2f6f29d 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -29,6 +29,8 @@ jobs: any::tictoc any::units any::spData + any::knitr + any::rmarkdown needs: coverage working-directory: "./scomps" From b3e30077a585215b9cecc432299ec81ea43aa524 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 15:49:00 -0400 Subject: [PATCH 11/21] DESCRIPTION patch - linebreak to whitespace --- .github/workflows/test-coverage.yaml | 2 +- scomps/DESCRIPTION | 19 ++----------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index c2f6f29d..6583f134 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -24,6 +24,7 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: + working-directory: "./scomps" packages: | any::covr any::tictoc @@ -32,7 +33,6 @@ jobs: any::knitr any::rmarkdown needs: coverage - working-directory: "./scomps" - name: Test coverage run: | diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index 90815873..dfc8ad0e 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -11,23 +11,8 @@ License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 -Imports: - covr, - dplyr, - future, - future.apply, - rlang, - sf, - stars, - terra, - testthat -Suggests: - future.batchtools, - igraph, - knitr, - logr, - rmarkdown, - withr +Imports: covr, dplyr, future, future.apply, rlang, sf, stars, terra, testthat +Suggests: future.batchtools, igraph, knitr, logr, rmarkdown, withr VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 From 98b2c8de07a2997c7d5453e7406d338c2745935c Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 15:57:34 -0400 Subject: [PATCH 12/21] DESCRIPTION patch (2) --- .github/workflows/check-standard.yaml | 2 +- .github/workflows/test-coverage.yaml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-standard.yaml b/.github/workflows/check-standard.yaml index f2288234..076fc94e 100644 --- a/.github/workflows/check-standard.yaml +++ b/.github/workflows/check-standard.yaml @@ -39,7 +39,7 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: working-directory: "./scomps" - packages: | + extra-packages: | any::tictoc any::units any::rcmdcheck diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 6583f134..d74b4f4d 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -25,8 +25,7 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: working-directory: "./scomps" - packages: | - any::covr + extra-packages: | any::tictoc any::units any::spData From ff1956af4f01b7e3ddad188991fe338f2d30f943 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 16:09:04 -0400 Subject: [PATCH 13/21] Redundant dependency fix - tictoc in one of examples was removed; system.time() is in place --- scomps/DESCRIPTION | 21 +++++++++++++++++--- scomps/R/processing.R | 5 +---- scomps/man/aw_covariates.Rd | 5 +---- scomps_rmarkdown_litr.html | 7 ++----- scomps_rmarkdown_litr.rmd | 5 +---- tools/tarballs/scomps_0.0.2.10032023.tar.gz | Bin 21884 -> 21874 bytes 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index dfc8ad0e..f27c2850 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -11,9 +11,24 @@ License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 -Imports: covr, dplyr, future, future.apply, rlang, sf, stars, terra, testthat -Suggests: future.batchtools, igraph, knitr, logr, rmarkdown, withr +Imports: + covr, + dplyr, + future, + future.apply, + rlang, + sf, + stars, + terra, + testthat +Suggests: + future.batchtools, + igraph, + knitr, + logr, + rmarkdown, + withr VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: f6481d6de18f4e515f064d81bc8ae4ed +LitrId: 2567a6b91b5b130f91bd90d6aa1ca518 diff --git a/scomps/R/processing.R b/scomps/R/processing.R index c1c84a03..b27f3301 100644 --- a/scomps/R/processing.R +++ b/scomps/R/processing.R @@ -217,7 +217,6 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' @examples #' # package #' library(sf) -#' library(tictoc) #' #' # run #' nc = st_read(system.file("shape/nc.shp", package="sf")) @@ -227,9 +226,7 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' st_crs(pp) = "EPSG:5070" #' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' -#' tic() -#' ppb_nc_aw = aw_covariates(ppb, nc, 'id') -#' toc() +#' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) #' summary(ppb_nc_aw) #' #### Example of aw_covariates ends #### #' @export diff --git a/scomps/man/aw_covariates.Rd b/scomps/man/aw_covariates.Rd index fdb5d71e..2cefe0bf 100644 --- a/scomps/man/aw_covariates.Rd +++ b/scomps/man/aw_covariates.Rd @@ -22,7 +22,6 @@ When poly_in and poly_weight are different classes, poly_weight will be converte \examples{ # package library(sf) -library(tictoc) # run nc = st_read(system.file("shape/nc.shp", package="sf")) @@ -32,9 +31,7 @@ pp[["id"]] = seq(1,nrow(pp)) st_crs(pp) = "EPSG:5070" ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) -tic() -ppb_nc_aw = aw_covariates(ppb, nc, 'id') -toc() +system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) summary(ppb_nc_aw) #### Example of aw_covariates ends #### } diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index 35f9efea..3e2875de 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -1141,7 +1141,6 @@

Create functions

#' @examples #' # package #' library(sf) -#' library(tictoc) #' #' # run #' nc = st_read(system.file("shape/nc.shp", package="sf")) @@ -1151,9 +1150,7 @@

Create functions

#' st_crs(pp) = "EPSG:5070" #' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' -#' tic() -#' ppb_nc_aw =
aw_covariates(ppb, nc, 'id') -#' toc() +#' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) #' summary(ppb_nc_aw) #' #### Example of aw_covariates ends #### #' @export @@ -1423,7 +1420,7 @@

Documenting the package and building

## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpfPUv07/scomps_0.0.2.10032023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpcN1CIt/scomps_0.0.2.10032023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index d0608b0c..353996ee 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -878,7 +878,6 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' @examples #' # package #' library(sf) -#' library(tictoc) #' #' # run #' nc = st_read(system.file("shape/nc.shp", package="sf")) @@ -888,9 +887,7 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' st_crs(pp) = "EPSG:5070" #' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' -#' tic() -#' ppb_nc_aw = aw_covariates(ppb, nc, 'id') -#' toc() +#' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) #' summary(ppb_nc_aw) #' #### Example of aw_covariates ends #### #' @export diff --git a/tools/tarballs/scomps_0.0.2.10032023.tar.gz b/tools/tarballs/scomps_0.0.2.10032023.tar.gz index 6ac28a5d720b22e5a7de6fa4cfc69d66c1ae344e..fd510b70b1b6c3fd01218b7ffb14a1054999830c 100644 GIT binary patch delta 21217 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 QPxkr$0ebBtO#tQr0Oo?Yr~m)} delta 21171 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 W>(BbL{;WUQ=l=(g@bEbR<^cdX<;d3n From f2e6c736416c84372b38c8a4a22c0a3e3a4f7c63 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 16:41:38 -0400 Subject: [PATCH 14/21] aw_covariates fix - poly_weight will contain numeric/integer fields only --- scomps/DESCRIPTION | 2 +- scomps/R/processing.R | 13 +++++++++---- scomps/man/aw_covariates.Rd | 3 ++- scomps_rmarkdown_litr.html | 15 ++++++++++----- scomps_rmarkdown_litr.rmd | 13 +++++++++---- tools/tarballs/scomps_0.0.2.10032023.tar.gz | Bin 21874 -> 21939 bytes 6 files changed, 31 insertions(+), 15 deletions(-) diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index f27c2850..b09f16a8 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -31,4 +31,4 @@ Suggests: VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: 2567a6b91b5b130f91bd90d6aa1ca518 +LitrId: e2d777683c377ffccba3c8047709cee6 diff --git a/scomps/R/processing.R b/scomps/R/processing.R index b27f3301..c02d1ce1 100644 --- a/scomps/R/processing.R +++ b/scomps/R/processing.R @@ -222,7 +222,8 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' nc = st_read(system.file("shape/nc.shp", package="sf")) #' nc = st_transform(nc, 5070) #' pp = st_sample(nc, size = 300) -#' pp[["id"]] = seq(1,nrow(pp)) +#' pp = st_as_sf(pp) +#' pp[["id"]] = seq(1, nrow(pp)) #' st_crs(pp) = "EPSG:5070" #' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' @@ -234,6 +235,10 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { stopifnot("Inputs have invalid classes.\n" = is(poly_in, "sf") || is(poly_weight, "sf") || is(poly_in, "SpatVector") || is(poly_weight, "SpatVector")) #check_crs() + + ## distinguish numeric and nonnumeric columns + index_numeric = grep("(integer|numeric)", unlist(sapply(poly_weight, class))) + aw_covariates.terra = function(poly_in, poly_weight, id_poly_in = id_poly_in) { poly_intersected = terra::intersect(poly_in, poly_weight) @@ -250,12 +255,12 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { class_poly_weight = check_packbound(poly_weight) if (class_poly_in != class_poly_weight) { - class_poly_weight = as(class_poly_weight, class(class_poly_in)[1]) + class_poly_weight = switch_packbound(class_poly_weight) } switch(class_poly_in, - sf = sf::st_interpolate_aw(poly_weight, poly_in, extensive = FALSE), - terra = aw_covariates.terra(poly_in, poly_weight, id_poly_in = id_poly_in)) + sf = sf::st_interpolate_aw(poly_weight[,index_numeric], poly_in, extensive = FALSE), + terra = aw_covariates.terra(poly_in, poly_weight[,index_numeric], id_poly_in = id_poly_in)) } diff --git a/scomps/man/aw_covariates.Rd b/scomps/man/aw_covariates.Rd index 2cefe0bf..4604c030 100644 --- a/scomps/man/aw_covariates.Rd +++ b/scomps/man/aw_covariates.Rd @@ -27,7 +27,8 @@ library(sf) nc = st_read(system.file("shape/nc.shp", package="sf")) nc = st_transform(nc, 5070) pp = st_sample(nc, size = 300) -pp[["id"]] = seq(1,nrow(pp)) +pp = st_as_sf(pp) +pp[["id"]] = seq(1, nrow(pp)) st_crs(pp) = "EPSG:5070" ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index 3e2875de..a6de8d23 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -1146,7 +1146,8 @@

    Create functions

    #' nc = st_read(system.file("shape/nc.shp", package="sf")) #' nc = st_transform(nc, 5070) #' pp = st_sample(nc, size = 300) -#' pp[["id"]] = seq(1,nrow(pp)) +#' pp = st_as_sf(pp) +#' pp[["id"]] = seq(1, nrow(pp)) #' st_crs(pp) = "EPSG:5070" #' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' @@ -1158,6 +1159,10 @@

    Create functions

    stopifnot("Inputs have invalid classes.\n" = is(poly_in, "sf") || is(poly_weight, "sf") || is(poly_in, "SpatVector") || is(poly_weight, "SpatVector")) #
    check_crs() + + ## distinguish numeric and nonnumeric columns + index_numeric = grep("(integer|numeric)", unlist(sapply(poly_weight, class))) + aw_covariates.terra = function(poly_in, poly_weight, id_poly_in = id_poly_in) { poly_intersected = terra::intersect(poly_in, poly_weight) @@ -1174,12 +1179,12 @@

    Create functions

    class_poly_weight = check_packbound(poly_weight) if (class_poly_in != class_poly_weight) { - class_poly_weight = as(class_poly_weight, class(class_poly_in)[1]) + class_poly_weight = switch_packbound(class_poly_weight) } switch(class_poly_in, - sf = sf::st_interpolate_aw(poly_weight, poly_in, extensive = FALSE), - terra = aw_covariates.terra(poly_in, poly_weight, id_poly_in = id_poly_in)) + sf = sf::st_interpolate_aw(poly_weight[,index_numeric], poly_in, extensive = FALSE), + terra = aw_covariates.terra(poly_in, poly_weight[,index_numeric], id_poly_in = id_poly_in)) } @@ -1420,7 +1425,7 @@

    Documenting the package and building

    ## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpcN1CIt/scomps_0.0.2.10032023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpDc71Ig/scomps_0.0.2.10032023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index 353996ee..4b4f8ccb 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -883,7 +883,8 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' nc = st_read(system.file("shape/nc.shp", package="sf")) #' nc = st_transform(nc, 5070) #' pp = st_sample(nc, size = 300) -#' pp[["id"]] = seq(1,nrow(pp)) +#' pp = st_as_sf(pp) +#' pp[["id"]] = seq(1, nrow(pp)) #' st_crs(pp) = "EPSG:5070" #' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' @@ -895,6 +896,10 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { stopifnot("Inputs have invalid classes.\n" = is(poly_in, "sf") || is(poly_weight, "sf") || is(poly_in, "SpatVector") || is(poly_weight, "SpatVector")) #check_crs() + + ## distinguish numeric and nonnumeric columns + index_numeric = grep("(integer|numeric)", unlist(sapply(poly_weight, class))) + aw_covariates.terra = function(poly_in, poly_weight, id_poly_in = id_poly_in) { poly_intersected = terra::intersect(poly_in, poly_weight) @@ -911,12 +916,12 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { class_poly_weight = check_packbound(poly_weight) if (class_poly_in != class_poly_weight) { - class_poly_weight = as(class_poly_weight, class(class_poly_in)[1]) + class_poly_weight = switch_packbound(class_poly_weight) } switch(class_poly_in, - sf = sf::st_interpolate_aw(poly_weight, poly_in, extensive = FALSE), - terra = aw_covariates.terra(poly_in, poly_weight, id_poly_in = id_poly_in)) + sf = sf::st_interpolate_aw(poly_weight[,index_numeric], poly_in, extensive = FALSE), + terra = aw_covariates.terra(poly_in, poly_weight[,index_numeric], id_poly_in = id_poly_in)) } diff --git a/tools/tarballs/scomps_0.0.2.10032023.tar.gz b/tools/tarballs/scomps_0.0.2.10032023.tar.gz index fd510b70b1b6c3fd01218b7ffb14a1054999830c..b5395dbcec656415b26985e20b3767f6074b9ad0 100644 GIT binary patch delta 20437 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 From 78fe49ff17685332ab15d65d2007710a23c0f2c9 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 16:49:41 -0400 Subject: [PATCH 15/21] spData dependency removal --- .github/workflows/check-standard.yaml | 1 - .github/workflows/test-coverage.yaml | 1 - scomps/DESCRIPTION | 2 +- scomps/R/check.R | 8 ++++---- scomps/man/check_crs.Rd | 8 ++++---- scomps_0.0.2.10032023.tar.gz | Bin 0 -> 21937 bytes scomps_rmarkdown_litr.html | 10 +++++----- scomps_rmarkdown_litr.rmd | 8 ++++---- 8 files changed, 18 insertions(+), 20 deletions(-) create mode 100644 scomps_0.0.2.10032023.tar.gz diff --git a/.github/workflows/check-standard.yaml b/.github/workflows/check-standard.yaml index 076fc94e..cb373c74 100644 --- a/.github/workflows/check-standard.yaml +++ b/.github/workflows/check-standard.yaml @@ -43,7 +43,6 @@ jobs: any::tictoc any::units any::rcmdcheck - any::spData any::knitr any::rmarkdown needs: check diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index d74b4f4d..9a7705b7 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -28,7 +28,6 @@ jobs: extra-packages: | any::tictoc any::units - any::spData any::knitr any::rmarkdown needs: coverage diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index b09f16a8..a94cfeef 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -31,4 +31,4 @@ Suggests: VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: e2d777683c377ffccba3c8047709cee6 +LitrId: ea0225b0ebfbc140538ec9cfa4fa0628 diff --git a/scomps/R/check.R b/scomps/R/check.R index 3fed02f7..3e8e20c6 100644 --- a/scomps/R/check.R +++ b/scomps/R/check.R @@ -93,10 +93,10 @@ check_bbox <- function( #' @author Insang Song \email{geoissong@@gmail.com} #' @examples #' # data -#' install.packages('spData') -#' library(spData) -#' data(us_states) -#' check_crs(us_states) +#' library(sf) +#' ncpath = system.file("shape/nc.shp", package = "sf") +#' nc = read_sf(ncpath) +#' check_crs(nc) #' #' @export check_crs <- function(x) { diff --git a/scomps/man/check_crs.Rd b/scomps/man/check_crs.Rd index 2cc3c9d1..ad8edfa3 100644 --- a/scomps/man/check_crs.Rd +++ b/scomps/man/check_crs.Rd @@ -17,10 +17,10 @@ Check Coordinate Reference System } \examples{ # data -install.packages('spData') -library(spData) -data(us_states) -check_crs(us_states) +library(sf) +ncpath = system.file("shape/nc.shp", package = "sf") +nc = read_sf(ncpath) +check_crs(nc) } \author{ diff --git a/scomps_0.0.2.10032023.tar.gz b/scomps_0.0.2.10032023.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..530b8ef1ddf0563efc05c67baa4dba7bea77b239 GIT binary patch literal 21937 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 literal 0 HcmV?d00001 diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index a6de8d23..5a3b4994 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -1042,10 +1042,10 @@

    Create functions

    #' @author Insang Song \email{geoissong@@gmail.com} #' @examples #' # data -#' install.packages('spData') -#' library(spData) -#' data(us_states) -#' check_crs(us_states) +#' library(sf) +#' ncpath = system.file("shape/nc.shp", package = "sf") +#' nc = read_sf(ncpath) +#' check_crs(nc) #' #' @export check_crs <- function(x) { @@ -1425,7 +1425,7 @@

    Documenting the package and building

    ## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpDc71Ig/scomps_0.0.2.10032023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpYa4GNv/scomps_0.0.2.10032023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index 4b4f8ccb..f9a54253 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -768,10 +768,10 @@ extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) #' @author Insang Song \email{geoissong@@gmail.com} #' @examples #' # data -#' install.packages('spData') -#' library(spData) -#' data(us_states) -#' check_crs(us_states) +#' library(sf) +#' ncpath = system.file("shape/nc.shp", package = "sf") +#' nc = read_sf(ncpath) +#' check_crs(nc) #' #' @export check_crs <- function(x) { From 805f41341de908066bd3e98782fedcb66249c125 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 16:55:47 -0400 Subject: [PATCH 16/21] codecov path format fix - path argument in codecov does not accept dot as the current directory --- .github/workflows/test-coverage.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 9a7705b7..ff55df7e 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -58,4 +58,4 @@ jobs: - name: Upload coverage to Codecov # Add this step run: | - Rscript -e "covr::codecov(path = "./scomps", token = Sys.getenv('CODECOV_TOKEN'))" + Rscript -e "covr::codecov(path = "scomps", token = Sys.getenv('CODECOV_TOKEN'))" From bf571061b3276c143b4a330f6a6a6ac42c91261c Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 17:30:24 -0400 Subject: [PATCH 17/21] Changed function examples - Deprecated functions were removed - Example with implicit dependency is removed - covr.io upload part was commented out from YAML --- .github/workflows/test-coverage.yaml | 6 +- scomps/DESCRIPTION | 2 +- scomps/R/interpret_computational_domain.R | 23 +- scomps/R/processing.R | 8 +- scomps/man/extract_with.Rd | 7 - scomps/man/grid_merge.Rd | 23 +- scomps_0.0.2.10032023.tar.gz | Bin 21937 -> 0 bytes scomps_coverage_report.html | 6066 +++++++++++++++++++ scomps_rmarkdown_litr.html | 33 +- scomps_rmarkdown_litr.rmd | 31 +- tools/tarballs/scomps_0.0.2.10032023.tar.gz | Bin 21939 -> 21945 bytes 11 files changed, 6122 insertions(+), 77 deletions(-) delete mode 100644 scomps_0.0.2.10032023.tar.gz create mode 100644 scomps_coverage_report.html diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index ff55df7e..533abab8 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -56,6 +56,6 @@ jobs: name: coverage-test-failures path: ${{ runner.temp }}/package - - name: Upload coverage to Codecov # Add this step - run: | - Rscript -e "covr::codecov(path = "scomps", token = Sys.getenv('CODECOV_TOKEN'))" + # - name: Upload coverage to Codecov # Add this step + # run: | + # Rscript -e "covr::codecov(path = "scomps", token = Sys.getenv('CODECOV_TOKEN'))" diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index a94cfeef..cbdada5f 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -31,4 +31,4 @@ Suggests: VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: ea0225b0ebfbc140538ec9cfa4fa0628 +LitrId: c9221a987065acea06c724ff541a9119 diff --git a/scomps/R/interpret_computational_domain.R b/scomps/R/interpret_computational_domain.R index 757acf37..a57ddc33 100644 --- a/scomps/R/interpret_computational_domain.R +++ b/scomps/R/interpret_computational_domain.R @@ -76,17 +76,18 @@ sp_index_grid <- function(points_in, ncutsx, ncutsy){ #' @param grid_min_features integer(1). Threshold to merge adjacent grids. #' @return A sf or SpatVector object of computation grids. #' @examples -#' library(sf) -#' library(igraph) -#' ligrary(dplyr) -#' dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -#' st_crs(dg) = 5070 -#' dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) -#' dgs$CGRIDID = seq(1, nrow(dgs)) -#' dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -#' st_crs(dg_sample) = st_crs(dg) -#' dg_merged = grid_merge(st_as_sf(sss), dgs, 100) -#' #### Example End #### +#' # library(sf) +#' # library(igraph) +#' # ligrary(dplyr) +#' # dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +#' # st_crs(dg) = 5070 +#' # dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) +#' # dgs$CGRIDID = seq(1, nrow(dgs)) +#' # +#' # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") +#' # st_crs(dg_sample) = st_crs(dg) +#' # dg_merged = grid_merge(st_as_sf(sss), dgs, 100) +#' #### NOT RUN #### #' @export grid_merge <- function(points_in, grid_in, grid_min_features){ package_detected = check_packbound(points_in) diff --git a/scomps/R/processing.R b/scomps/R/processing.R index c02d1ce1..3b08a05c 100644 --- a/scomps/R/processing.R +++ b/scomps/R/processing.R @@ -138,13 +138,7 @@ extract_with_polygons <- function( #' @param ... various. Passed to extract_with_buffer. See \code{?extract_with_buffer} for details. #' @return #' @author Insang Song \email{geoissong@@gmail.com} -#' @examples -#' # data -#' -#' # run -#' clip_with() -#' -#' @export +#' @export extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) { if (!mode %in% c("polygon", "buffer")) { stop("Argument 'mode' should be one of 'polygon' or 'buffer'.\n") diff --git a/scomps/man/extract_with.Rd b/scomps/man/extract_with.Rd index eac08536..d95b9bbb 100644 --- a/scomps/man/extract_with.Rd +++ b/scomps/man/extract_with.Rd @@ -21,13 +21,6 @@ extract_with(raster, vector, id, func = mean, mode = "polygon", ...) } \description{ Extract raster values with point buffers or polygons -} -\examples{ -# data - -# run -clip_with() - } \author{ Insang Song \email{geoissong@gmail.com} diff --git a/scomps/man/grid_merge.Rd b/scomps/man/grid_merge.Rd index f3b5ac47..614e7ba9 100644 --- a/scomps/man/grid_merge.Rd +++ b/scomps/man/grid_merge.Rd @@ -20,17 +20,18 @@ A sf or SpatVector object of computation grids. Merge boundary-sharing (in "Rook" contiguity) grids with fewer target features than the threshold. This function strongly assumes that the input is returned from the sp_index_grid, which has 'CGRIDID' as the unique id field. } \examples{ -library(sf) -library(igraph) -ligrary(dplyr) -dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -st_crs(dg) = 5070 -dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) -dgs$CGRIDID = seq(1, nrow(dgs)) -dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -st_crs(dg_sample) = st_crs(dg) -dg_merged = grid_merge(st_as_sf(sss), dgs, 100) -#### Example End #### +# library(sf) +# library(igraph) +# ligrary(dplyr) +# dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +# st_crs(dg) = 5070 +# dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) +# dgs$CGRIDID = seq(1, nrow(dgs)) +# +# dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") +# st_crs(dg_sample) = st_crs(dg) +# dg_merged = grid_merge(st_as_sf(sss), dgs, 100) +#### NOT RUN #### } \author{ Insang Song diff --git a/scomps_0.0.2.10032023.tar.gz b/scomps_0.0.2.10032023.tar.gz deleted file mode 100644 index 530b8ef1ddf0563efc05c67baa4dba7bea77b239..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21937 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 diff --git a/scomps_coverage_report.html b/scomps_coverage_report.html new file mode 100644 index 00000000..60117c09 --- /dev/null +++ b/scomps_coverage_report.html @@ -0,0 +1,6066 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +

    scomps coverage - 6.75%

    +
    + +
    +
    +
    + +
    +
    +
    + + + + + + + + + +
    +
    +
    +
    +
    +
    + + diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index 5a3b4994..bce70b2f 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -817,17 +817,18 @@

    Create functions

    #' @param grid_min_features integer(1). Threshold to merge adjacent grids. #' @return A sf or SpatVector object of computation grids. #' @examples -#' library(sf) -#' library(igraph) -#' ligrary(dplyr) -#' dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -#' st_crs(dg) = 5070 -#' dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) -#' dgs$CGRIDID = seq(1, nrow(dgs)) -#' dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -#' st_crs(dg_sample) = st_crs(dg) -#' dg_merged = grid_merge(st_as_sf(sss), dgs, 100) -#' #### Example End #### +#' # library(sf) +#' # library(igraph) +#' # ligrary(dplyr) +#' # dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +#' # st_crs(dg) = 5070 +#' # dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) +#' # dgs$CGRIDID = seq(1, nrow(dgs)) +#' # +#' # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") +#' # st_crs(dg_sample) = st_crs(dg) +#' # dg_merged = grid_merge(st_as_sf(sss), dgs, 100) +#' #### NOT RUN #### #' @export grid_merge <- function(points_in, grid_in, grid_min_features){ package_detected = check_packbound(points_in) @@ -1014,13 +1015,7 @@

    Create functions

    #' @param ... various. Passed to extract_with_buffer. See \code{?extract_with_buffer} for details. #' @return #' @author Insang Song \email{geoissong@@gmail.com} -#' @examples -#' # data -#' -#' # run -#' clip_with() -#' -#' @export +#' @export extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) { if (!mode %in% c("polygon", "buffer")) { stop("Argument 'mode' should be one of 'polygon' or 'buffer'.\n") @@ -1425,7 +1420,7 @@

    Documenting the package and building

    ## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpYa4GNv/scomps_0.0.2.10032023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpA41AYL/scomps_0.0.2.10032023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index f9a54253..aff7cdd7 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -525,17 +525,18 @@ sp_index_grid <- function(points_in, ncutsx, ncutsy){ #' @param grid_min_features integer(1). Threshold to merge adjacent grids. #' @return A sf or SpatVector object of computation grids. #' @examples -#' library(sf) -#' library(igraph) -#' ligrary(dplyr) -#' dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -#' st_crs(dg) = 5070 -#' dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) -#' dgs$CGRIDID = seq(1, nrow(dgs)) -#' dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -#' st_crs(dg_sample) = st_crs(dg) -#' dg_merged = grid_merge(st_as_sf(sss), dgs, 100) -#' #### Example End #### +#' # library(sf) +#' # library(igraph) +#' # ligrary(dplyr) +#' # dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +#' # st_crs(dg) = 5070 +#' # dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) +#' # dgs$CGRIDID = seq(1, nrow(dgs)) +#' # +#' # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") +#' # st_crs(dg_sample) = st_crs(dg) +#' # dg_merged = grid_merge(st_as_sf(sss), dgs, 100) +#' #### NOT RUN #### #' @export grid_merge <- function(points_in, grid_in, grid_min_features){ package_detected = check_packbound(points_in) @@ -737,13 +738,7 @@ extract_with_polygons <- function( #' @param ... various. Passed to extract_with_buffer. See \code{?extract_with_buffer} for details. #' @return #' @author Insang Song \email{geoissong@@gmail.com} -#' @examples -#' # data -#' -#' # run -#' clip_with() -#' -#' @export +#' @export extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) { if (!mode %in% c("polygon", "buffer")) { stop("Argument 'mode' should be one of 'polygon' or 'buffer'.\n") diff --git a/tools/tarballs/scomps_0.0.2.10032023.tar.gz b/tools/tarballs/scomps_0.0.2.10032023.tar.gz index b5395dbcec656415b26985e20b3767f6074b9ad0..419b78c67d6e1accb195f1f1f4e738da6ac2389b 100644 GIT binary patch literal 21945 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 |1tSDb$2{O@~3`+s+Dzq^V5`}F94zQQu{ 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 From 8111edb930bad44ed5609f97a732cc1569972ae8 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Tue, 3 Oct 2023 17:38:53 -0400 Subject: [PATCH 18/21] Fixed invalid examples --- scomps/DESCRIPTION | 2 +- scomps/R/interpret_computational_domain.R | 7 +++++-- scomps/man/get_computational_regions.Rd | 7 +++++-- scomps_rmarkdown_litr.html | 9 ++++++--- scomps_rmarkdown_litr.rmd | 7 +++++-- tools/tarballs/scomps_0.0.2.10032023.tar.gz | Bin 21945 -> 21974 bytes 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index cbdada5f..7bef829f 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -31,4 +31,4 @@ Suggests: VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: c9221a987065acea06c724ff541a9119 +LitrId: 61344b231498c72af24f2ecd7d672874 diff --git a/scomps/R/interpret_computational_domain.R b/scomps/R/interpret_computational_domain.R index a57ddc33..ebd48b57 100644 --- a/scomps/R/interpret_computational_domain.R +++ b/scomps/R/interpret_computational_domain.R @@ -14,9 +14,12 @@ #' @author Insang Song #' @examples #' # data -#' +#' library(sf) +#' ncpath = system.file("shape/nc.shp", package = "sf") +#' nc = read_sf(ncpath) +#' nc = st_transform(nc, "EPSG:5070") #' # run -#' get_computational_regions() +#' # nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) #' #' @export get_computational_regions <- function(input, mode = "grid", nx = 10, ny = 10, grid_min_features = 30, padding = NULL, unit = NULL, ...) { diff --git a/scomps/man/get_computational_regions.Rd b/scomps/man/get_computational_regions.Rd index 9433fa9c..91f578d9 100644 --- a/scomps/man/get_computational_regions.Rd +++ b/scomps/man/get_computational_regions.Rd @@ -38,9 +38,12 @@ TODO. Using input points, the bounding box is split to the predefined numbers of } \examples{ # data - +library(sf) +ncpath = system.file("shape/nc.shp", package = "sf") +nc = read_sf(ncpath) +nc = st_transform(nc, "EPSG:5070") # run -get_computational_regions() +# nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) } \author{ diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index bce70b2f..d5be20c6 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -755,9 +755,12 @@

    Create functions

    #' @author Insang Song #' @examples #' # data -#' +#' library(sf) +#' ncpath = system.file("shape/nc.shp", package = "sf") +#' nc = read_sf(ncpath) +#' nc = st_transform(nc, "EPSG:5070") #' # run -#' get_computational_regions() +#' # nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) #' #' @export get_computational_regions <- function(input, mode = "grid", nx = 10, ny = 10, grid_min_features = 30, padding = NULL, unit = NULL, ...) { @@ -1420,7 +1423,7 @@

    Documenting the package and building

    ## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpA41AYL/scomps_0.0.2.10032023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpqAS5kJ/scomps_0.0.2.10032023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index aff7cdd7..db0eaf46 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -463,9 +463,12 @@ estimate_demands <- function( #' @author Insang Song #' @examples #' # data -#' +#' library(sf) +#' ncpath = system.file("shape/nc.shp", package = "sf") +#' nc = read_sf(ncpath) +#' nc = st_transform(nc, "EPSG:5070") #' # run -#' get_computational_regions() +#' # nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) #' #' @export get_computational_regions <- function(input, mode = "grid", nx = 10, ny = 10, grid_min_features = 30, padding = NULL, unit = NULL, ...) { diff --git a/tools/tarballs/scomps_0.0.2.10032023.tar.gz b/tools/tarballs/scomps_0.0.2.10032023.tar.gz index 419b78c67d6e1accb195f1f1f4e738da6ac2389b..82b32a66814abc1b216043d07e23ea637bf34573 100644 GIT binary patch literal 21974 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 literal 21945 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 |1tSDb$2{O@~3`+s+Dzq^V5`}F94zQQu{ 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 Date: Tue, 3 Oct 2023 17:46:42 -0400 Subject: [PATCH 19/21] LICENSE info added - Provisional. Subject to change. - Last test-coverage passed, R CMD check failed --- scomps/.Rbuildignore | 1 + scomps/DESCRIPTION | 5 ++--- scomps/LICENSE | 2 ++ scomps/LICENSE.md | 21 ++++++++++++++++++++ scomps_rmarkdown_litr.html | 8 ++++---- scomps_rmarkdown_litr.rmd | 2 +- tools/tarballs/scomps_0.0.2.10032023.tar.gz | Bin 21974 -> 22021 bytes 7 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 scomps/LICENSE create mode 100644 scomps/LICENSE.md diff --git a/scomps/.Rbuildignore b/scomps/.Rbuildignore index eb97a3c9..597996f8 100644 --- a/scomps/.Rbuildignore +++ b/scomps/.Rbuildignore @@ -1 +1,2 @@ rds$ +^LICENSE\.md$ diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index 7bef829f..cc8b8d68 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -6,8 +6,7 @@ Authors@R: comment = c(ORCID = "0000-0001-8732-3256")) Description: A package for scalable geospatial computation for environmental health research -License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a - license +License: MIT + file LICENSE Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 @@ -31,4 +30,4 @@ Suggests: VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: 61344b231498c72af24f2ecd7d672874 +LitrId: 1af1eaeb8441cd422e37a21fe2e2deb1 diff --git a/scomps/LICENSE b/scomps/LICENSE new file mode 100644 index 00000000..74e6421f --- /dev/null +++ b/scomps/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2023 +COPYRIGHT HOLDER: I. Song diff --git a/scomps/LICENSE.md b/scomps/LICENSE.md new file mode 100644 index 00000000..1a857826 --- /dev/null +++ b/scomps/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2023 I. Song + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index d5be20c6..55aba55e 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -396,11 +396,11 @@

    Package setup

    usethis::use_package("covr") usethis::use_package("future.batchtools", "Suggests") # Default is "Imports" # usethis::use_gpl3_license() +usethis::use_mit_license(copyright_holder = "I. Song") # usethis::use_vignette("scomps_1_setting_distribution.rmd")

# parallelly::availableCores()
 # plan(future.batchtools::batchtools_slurm)
@@ -1376,9 +1376,9 @@ 

Documenting the package and building

## ## ⠏ | 0 | tests pr, tas, ## pr, tas, -## pr, tas, ## -## ⠼ | 5 | tests +## ⠹ | 3 | tests pr, tas, +## ## ✔ | 8 | tests ## ## ══ Results ═════════════════════════════════════════════════════════════════════ @@ -1423,7 +1423,7 @@

Documenting the package and building

## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpqAS5kJ/scomps_0.0.2.10032023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmptULHMx/scomps_0.0.2.10032023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index db0eaf46..f0f3b5ed 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -49,12 +49,12 @@ usethis::use_package("withr", "Suggests") usethis::use_package("covr") usethis::use_package("future.batchtools", "Suggests") # Default is "Imports" # usethis::use_gpl3_license() +usethis::use_mit_license(copyright_holder = "I. Song") # usethis::use_vignette("scomps_1_setting_distribution.rmd") ``` ```{r} diff --git a/tools/tarballs/scomps_0.0.2.10032023.tar.gz b/tools/tarballs/scomps_0.0.2.10032023.tar.gz index 82b32a66814abc1b216043d07e23ea637bf34573..e41126c870e883ed72b7038b921e8cf3a5662f3a 100644 GIT binary patch delta 21347 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 delta 21453 zcmV)4K+3;`tO3@m0gxFSQY*=l{FN$o_D&tQJMWt&87FOLKdDEdNl0Q$ku@rRM$=ic z_2}ru;ql|=FCRa9`q`a-y71ZC*@3_N_%Z&{r?omC~VXphlvx8>n%}#5z$}x2B7@}5&!owAU5a#e0UK@(C&e78+B)%Vg)yr z^=6BpsSgyK$}pu;&yEitKZ0*{TuW_SPwjjA+x_--e|N9mY}Ovh#Et!bSxTLKC}uoh zF^Xasvl?af7_khsD#LR>jzVk_N=&2^q!SU#L^`oMsXg&s876?V*YiXUr+zvN_(`Mr zy2TI2vtZkJDxmFA?90$gL>h^i@16-K8=opyI||*%^TY8#{Pgns_PyG1bh#Ky7)0PF zX=CcdXI^v>!pL79|8&%U)UTgLDRgBYrewSJcsh&XG#S94&f}KwX2AmfjOOV)milkU znZaYgdH~bY63GbugB_8yL@MLh$WNE_*od$)Z+C90+(L92h+bT`n|#S{$OVxuy%M~@U~W~av*pW3S5HX6)dlo zfW>tp8sARRbe0UZwxZbey-pO5wBAq7 zUOazzc=RFKxQYIM_xJk-{qF+(-`U&muIc~B_-u$DBrIkpm7X|V0PQ6r(jN#ff*qC$ z+=BRG;)GtUCNGhoG@OeeP!uQjp<2?^Pl1@abJ(47m`KmfA5WxvHatCzE(?#`I4M8r z7ak$GK8@y~S9p$e#1DtD9LZRQuFPKt{%q(ZLwT73xnA;rco;j$idT6jJRr5Pe>#Uj z&Em+FNnQTFa2Q)l;2FOW=36Rpfa|yym6c#X^%!YpG z$;%;vEzesXliC-@`5dexb)R$B&2S(oG{=IiIaRcSrw^w?1GSNaXi- zcbCzB{N(h12cGw~_jdO_6T55r|MBLZ$ZF^KQn8cdh?@bpAhzqp8vZ zhndI@YD*e-;;FYpB-q##e@{_q6vq;@fl#CqnJHO+_}veI?TF~~4G?bOC*srr@j!qE zi8Z}kITMd$ibXCa5~{_Ob(0aQPA@=J`$|3S5EzHVds85%$1^8(rV0pGg4rXr2EiaO z14hiZyIaehWdX~V`ZC3TX1Tt2I3FNi8 zS#yDVAP%D__WTfNfJhclVaji1T-u^9vpor$kqdd*hV@f;RssbDXJ{%3(~fvNLIMIk zr}`k!#Su;qz(^x;^!&vSgWcZ#H=WYneQc5eYnEw64F=|9+nc#zw9+(|22YDc0IZ#V zjF>4eK{OX6L%??EIkAUEC+hXic7LzVxX)^Lpsn%}=IPh`+6xn{prb*=5^M3G8zo5w!e_GWGoI2 z>;dZal&vT(OwX>_zDG}npnQbMD2k_ll1QHdpFP#sGnzHqX*O%cHcW`Td@bZM5nnz?Ye4y8%T57sMqYH06TrA-cN2CS{{Kf1Qt4|GG z*ff+fnhuJHQ?<>Kuv!nS#jDpO;~w_MAuUJ1EUrkT(t;H}+{%8K_#U(SOd}V6)KSp$ z;L9ZfC{dGVypyrkG)hvk>cV5_At-prs;g|WNI0Shk>azg0bTH887y#50MSU{n;&8g zARuVl)j+tn3AV_a1jhi%YtjL-22k}%QuC5zbdB~E4cHzj&|J`~g{4=kR)EwIUVy*P zae<&U6XA%nFuEZ5Vd9)K6nP1MvPJ<2E9b?2UHCzuI!EhQ&qa=Lu1CNESPg&)HzI3g zk`H1t(esAg`2OLO7e^w(abEa|G)XTO9{x6$@d6gdS6jqlwsO+Bl`|uYigM+=Pq(X! zljn%gL1cx1vee0j9; zuCxkRKM=@wYD`l#*JBKSHFDFP__u!(^dblvR{cz#L7}fvKRkY6NPB=BnW5iCNRB#3 zO$17SreL+SAD^%8NZ!VQW@Zi$_K~YODx%5&Ndg0uwV|nw5cU+FGSb_~5!)moc~mN4 z7(Go{A_J#Havn$i)JEn@Ma6*v5@phBZ{j2%qzS-vM<_vL>YTxU+MmZVry^JjOR{tl z$GC;DN`_|Abvm6+&bC1aoCj$x_nS{i{x`UcA(0+u7=J;#&)DIYFa@`!OPNH-@&|4c z`ePI^dDFXY9@sbz?$(4LY!I^WTi~C@PP~9+(!`&k3%#7+B4Uy<@&gH)(8QU^thbkfjIUcKs_oD_;Q^6v+tM=!&3Kk-2$$X+qm zS)c!q{l9ped51>^^FWcQ2M z2i+^oB^851q0o*VPHg1cGEI9VwV|jaQ1D5Nn&BmXR8Hks#*JRHW5Ns<%ihc!kF+MO z2;l3Z%QT)RU+Qrhp+j2kq~KXF75B~2sfw%4bD>!b=mF_|I#m(| zOXLZE(#G}i_+N+qYp;wCa0Gk<{qJ|T_lxJhd%d;)*PreD_Ym~bRBCDqe?8v?Js2Hr z(FLfaVjn9zt0PkX6fLz%H6dfEAG*ODN{h=joA*$Fg%yeo1AzvzonAzmVT3OHdr9T! z>!KwtCcZlnPAqc(o{we<=1s{AhLxa#kj(IZ;kgVJw>V0kMKHQ#h^Fc6@YrHD+!2%E zpq&Lc%qeO{Bh{{O0@Qmh+d%7+PO<*tw)GcAePypR+^a0+ly$tN`l$XcntUofONp5w zd+DTTHgC+JJc`Zvkl}s)Ly7oPWcRWW#X}!YDH8cxqt^n4G|gMYqwS_rBx1m+99{~4 zghk);VqcJQ9{5uj-;k`04OJTIi?0cESNFatzRF+sPefbfWt(D4m&#gPRJOPGg&Jno#L#8kYZ=}y@%@1iPSVkH4o@1F`78y_sSJ`FwQ6Kd+aG?x za0*}+t!z6~f>|`1*~G9F!s`4h=AWM;|8FQPil5M&hFto&*mp@5EjplSErkbA~zsnPm=A02+Ly10n-?E4M`5 zlVReg3jhUz2wK&ErMB63?Hn{EWUyE?!LsB$?Re)-=t^uH{iv~kTgypU4-8u;Pa71z~A zJ?AQaFiJEoKww(>8b_#`N>rK%-c1Z7LtPPV4f!2>&tSmWLyPe1NV z(rIu_9V9#{vw-8eaz;{LHsWbgJT>Fpts@Jp^AUDrEIW%md-SXW#1iqqVp_wq6w3hU_M2K0mS)#IJ$tTKhisvog+^5V&PyGItXz*e-0(Z z(i6Sk@zjoXvHK-)6Nx!kepNeX^bFM?zG}1yT)hXl`9s)C za>iCYhC-)J2@clYZ*w)L@c+i)566!mJ$}@zG{n$Kcned^Ey!MOS;6&hHPj(D&RaC4 zRyr+b!(kWYEdpd!r7-&f06gRs$^_vg9Woq^U`k}ee4|f)8%?`8`tr(XSwMWwR0n3|MdGytCEaCt4bjbw>H=7H2p& zxC+RsI%%e#M;z#^r zQ$XHFV<0#o$TlE$l}I92(vB}}5V2yCzk%q~kE7_UPM)p)cn;jMX>QJck-R`%f$5K} zS&`4KR#b}4wV+7?i3k?TWjA30oSN|tJZP;a<0}i@n%tsW+@?b0rcgd|ie>-~M!tmB zKPr`_*;ol^q9$l;#)4a;yR|a-vZxBmf+F}H^tWTl>MRl$MD+XtXQId+j_Dz#z);V; zF-zatfm6A!xa43Aue$7iWX#{t(HLcDx!WRFWB9%&cTq4RSjrpC8#mzvitf6J#Au^o zQCM%RNoybA_i|WJX~{-}H>!{>IZOx_+z5Xsz-P{Eh6G_(w!Z<%eU1`3^c)kOVBtO* z-dZehgZT4u5>1_?UL1=8*ktHxd|Ashx1J^q^sAANG(p1%^cO~d*6ng7_=u;^UW((N zp3)DKUFI;B@k+IbE3}Mv;G67uSgunN1@m2K`}^9!M7G5WrPSlhB{m%97IxZj+LtNO z{=;O3P0-h&k&QTStEq`~B7;%hSS&H^Lc>N8)kGKf7`s*Pf2BV43`h)w^zDFr5A}Ox zAh^hHOUW*RTV#2<4=siyv{g#e{*l={#_@67J9?iG~*nw3|jk|*o{O*{sJQiK=D zgsi6*QGAA60Tw(nI8XQHa4x z4c3Wuq*wt7%___Q6(!~8p!DVoev?f68CE1}JM_Iv`{0m*Y#K|T(yHK!Su>n&XbzTCVv}}TG}WVZEA~{P?D^grix*` zIy*V3%2N##v(rU;7R_cz%Yj&O5;ruzvaQHXLzyJH zm$ra{h+(3aX**f_KxLY(6T9BfiKW9^LmR3zYljy`z8o*-%Bm)G&!5Vac1O9oa$eT% z&!~1aSQg01`d3Gaz}h6W@>O~G^+dapFk3M!7DiD zPB155bP|yO6|cIj-pPH@?Q9!|I`AInBIGkP(u?5HG(zJjiYE#BRWH~EPe(R>ngvpj zsS2o0M+sdZJ2y()p+IC{LPkLp#f@&K2LrU3ExNq3Ik$wBZ?WH5%*cfkhoCfas8dXT zbA8AUJTS-6b!oq$3U^im59v6#lFiuSKXuaBzid2x*vj1Cb0%B$jQ6hRJL5(L#HJyF zn%p|4R=%cIP^?h_KBrYw{EaH!@GCoilb04%1AGOw-kcaN{#qP1fV_I;pPZO%=GCh= zCnsv0%iz9&3MV#GwA)m*uQN)wv0@4?t5Mmms$g<(w3H#QtE#PH;0!CubIv#>9AzrW zj1^YovyOW%1WN05C>pr2W9ziMSs9M4KFomw!cJ-&mdc1FN=y zkMps$%H7TEC1~X42SwXMKC7xbiOkp0iq3mc$Hk*mr9f5`vJL_&-~YkFDl-4SAR3Q9 zjQju1@n5?o|Nous{@VWr@6Y1@_Y#vX7$5<9lTR2Ye*`QHYw$ZXiCC=tX@udUW6JVE zN{{lVaq>D!M8ku1ws=tkPNMr^9TppzRxRd@C~B!8Ytp3w8JSlppV$3)~d{wcG6#=>Oi{ z-kSdZYH8^I3z??c2tt9X_=9usEb($X zfD_J7>JFciUl}=n_foJ^#p|zMi)e;x4*MU4*0AR(LUCLdnopC=Rhi1;QCPysBRi#L z^Y34aMvv@<*~EM;w!3EbCu<~zn_vzDW45sU|9W7jwzzpPs;C|b#UU(&<9Ue@d2nA` zpj(8O<);!832I2W6V|BIu-rzw*An<2{=aDqw3&^x0LIRL#F4!!WMVa*vsdH4&+%pw zlE+5MNkb)hq5bN>pAcw7A-aR}(o_gr&+(D+@K(udP*yVc5&#rW9o{1xMyl}B*l8O1 zK5=n1wf<$+U+&+{4$pc1dTUqYUB(+qLS7H1!&spJthWo5KjhQl{~w0=-^l;BcXqdT ziu@lWfHnVr|I_6EU^b(9dWq*BV%QGTBDI@UaEA7Q$dXeXc}fdMU@k1`4otbKMQ<5-0F4uyQW9-Z;2e+9&vWSnGz@P2-6Y2&7By@ zpzFtOAn%J8&w$szd?vm-5|56aA0Hh)e0lW9fUXaJYYXvnw&xtH&MIR_A+@2)N-dqduvy4iNTOOSrco^O^qWp*i^qck zK1eV#D4VGt3!eW=#ht8NW-2X~v^rcX$Q2C!^MfLs(#hmwmGA~SjysDi26$Y+5~%99 zu&4chpqTJiTV!oNV#U31!`Yp!@ESH<)~vD`Z#7%iDhQZGp%PO*I%%U$`@ZOko7q?x zn0l_o*p43bjUgSbBQ2>d-ZG|4P3c-4X~a6XF?0#KYpn5>NJ0l4gEm3Q*=)YuO7B-J zbaA@%X~(js{xrBdoqtlBF`slCy@n_RcE;!i3=DLw(exv z>h#{qZXPtlR0_@~9r2Tn!BM_91e9`rJ`gH8wnK;u?PTLloiolaAhUJYp&3xIC@m|i zGCFur4j%{fCVi}oWQDw0F%r1+*4+K{+&tlW`cN+woSkUuQ{H+`Eub)gS>iJ!+|CUp z8{D0_qEy~NSj>?qc!jiR;?awXaYx>*PH3Zrisw0Kn;zNov;1+srtBVBi0v z+RyL*(GSeTy5-cpOWRQ5n$-pm&bm=ZJzAL`*z%4+7Z7%(aD!yX`>HCc1)evvVziyg zrSP!=hU7U1`1wIrE%&z2Z51zOG#gV%v@7Sl6oy(c;ihkg0-{`f0A(b>tEVKqb6p1s zx`OuoPft}FxjV>)1u6fY=?2<=QCfK@fBt#0m=d0gMRF%)2grVsG}>9&miTXKwNxi_ zSk9j2c2(}kEihLR;QAKG%NZD9jw>0HRxDqMq8kzP_UL(6Y^?C2gQHTUI{Dqhy4L`d?O)S4`O3gJ;rKt3m|9Zt93yEjK7Ws2Bl%QE(z|N{S(0 zCv%iI#1&>gYVDu!CPF(u=##avJ->qcD-vMw4$ISFN3xfET*f$NMd zsLaSKpF1`SuAX?!afCAc^UTw;>N;M|=!192T>Y)$Jty7qWD2~~j(~m7r1%!otvJ(Y zDZEy2TAj~DBh+%aBgYazD``nyOe4|oP*gIzPMETZH8(3#rYInrlp}?~Z02^Z>l@i& z;l0PbMJO$O`!uMd=nws<@AFoMs zB{F*ssHbky#Tw|uj)CNHeifJs>!4jZYqYnUpnJ|{adb)9w1IVevn#%A3X{_1aV=)M zD9snHfASiQK(~^iyWosf=wpCUCQ5N44=)W#Ya)pZ$Rts=*;CwqV$e^OMGl+BSL${v zfSMIa%C?ZF&t4u4kkw`CSB46e1Wnye<(vbtpp;%CeQdhYAwnAgtUKJx`ai9$R<;~? zJ7Cd#Hd{GbTK3>|><5PisX0Y%3F;)R7wiPae?9t?rQCHEoMaW9)1(Ru=EZ%G1*A}H zQ2vHCQC=99MP<=6Vlt6e{DOivbwsw&7KaDYvaVW~uuhC(U!+lSd}+jS ze?H_rV_WFGY#Sj8@2FhVPPMQM#D2t#< z_os^D;S78oQfp>IxF^Eot6}8wF*nvN z3gWh^C|2mNF0nxdOu9P>34*Ufn{>{@DeNuu&7Vy=K!Z9!>9@Z7@d$|85K|u_!AR#Y zc|a^Uc|Bz}tZ6-vnE{%_PBBKc+v)C_nU^n^z|rJ2ps4tY@QSgMHaW{jv_dN?f9XR` z5DcU2Finxa7KQXTRKx#`*#}fNz7m~+LCA<)&s8Vu78`S3DT}j~6Nrh?*1-tY3+az1 zDMdbNfx*Zfrlp@HX78k6*h35X!%E{Gv1{EF%9lxnb*@tc$2FFLBs$76z*~X#S%n&! zyfn)VHeaE#FfO2)s%{^i8+J5ye}95LXyrw5cTA=UNN?NSEwk}o&~~T$h!$8A8z_Z& zKBch?l`|r8NwY{ce$KSV0uZ}jD)W>A-np}j>{POpimaGcj!K=<60==4ZjmPQfbYUy zo(&U|>Co%h%*t|u@9-iN$}wq|P#Icg>fx(bb>FL>oD{NmzL`RQc|DIv*~6t!;!*9>I1#J0?5PA9Xc1thc1Ts=7cs* zF+&&B_Px#KHTRK;dn2orXVf|3X`-cP!Vwbhcq!)Dv5VN^9W5AZowdxZ1ju>(sJ`qX zH5Egxt~ArDRvAT=rld@*f7FV3&6(9==>?Upxbw`eW!Y|-3FLPoDwS|!gJuh8-`r0! zt%EZrMxp+xvdpTho-zNGeuDvX64cy=k_!Gyy}(4GDv51-ZjTR8&zw+wn1HU#^W3_@Bfg6bbvS@W=A$Le{`)jTjRD0xM{Me`(l2o ziRK`){2C_RL^MW0CYatA>QVp%Th4`DW!0tHr31`7F`Pb^Vbd{NL&zhdU}`<%b95bj zpIg4v1=;pFr_REtM^RHo#-!SGkf2LC1JnI5Yz5RE9k+lk49XIj0o4wkR^$f0P}Wu$ z;1KK0Og2Kke-J!&0|wVXLl&LQ3_%vaxg+Z=pFmotbheQ`Z_OcjE2%!u(tY8Eo26Pq zeI$O6vqKANo}IRE*u|-e?3c?FJ8O)1=4BjSAG~aq0onXO@q(&;YqybGtZlWb^y;>h z4qV?iE^h_k&K9__vaKb(Vp-qO(ym_Kw_M`yw#;u@f9giR@Fs+TCIYtQwpJ^jURUgk zci$Vg*&jFVksJ5Po$i&D=f$h`%-g$K8BS1+eGa(vs?tA)6BdE3OxvToqK|7dIng$S zEC+DWN$YOivlNzB#7t7}FiwupN&bxhCC(4L!(eeohtp+;%cq&MB^p@hB10!Nye(1P zRxX!Te9b|Rz(BX120))RhXyQ)#q($b!9Jqj~qr7 zys64xNLALzdu#{ud?ZIO1+Po z|D(6p?U(X@?Dp32zkjm(pI^`l5((bfq%P=Nax>hax*&>teL3l=AzY#`d=3&9N?wU` zF`v9$LfiGoE^>=ZAIx9*u1Q~IoZuWAmYbszdmd5Oi)U+5iaF%<^={0*8$MK#{ou^ZDi)+3>uWS;4$0jXKq65)-hB z<8`JZGhYoB|9M5}oDSnP$Ib!`1?V6NS~t222(Ng>EvVI)L298BmIG>T%LR3_?~#A^ zDsze9sau{oxmg<(<%kXb7um$PK7s6}OVAH#g?7vI-+D)~$HudHqFF(EpvC{{ClTcTN94 z>im0=yYw1lIoeo5%G!6zBi!nU+$DvG9S<_zz0-Ytl{Pkz``!PD&9fhFC zTmgJBwmQHH9ChK^s&xc270N3`X|hI(h1>`gkE@?ve&4=#UBiLaYOi0vzKXBkok&4_ zP)qZVo5|A9vd&Bc}y2SLRqpc;sJjGS^?(*HZPf= z;z+Tw^3;?tP2L~wjLXFHJR#(6gOtp514xqZs184JPTkE6eG7g*tK>ZO_>(|!h#yCD08)?0chu5GPS8FO9 zvBA0`Ohp;6Uz^E;Uh{u_bSW)@kn-8uC;kc@MhcmMc+EEtAE7oQb zhJIjYa7z`Q1+v~)L?C#Pt>YNMas)JM;bH_@q1YYd2? z+*%n}yDo+{z_R#j@_!`kcgp|!JH7s1LH^&_+3BwN|Ht@z`}w11hcEy6{7B%$KB(2c z&HhTq!@pCBhhcvcyum6xsL#_;`(9maJy0)jTOZVw&sY@K@z@M^>p>l3Vk6fmigBH7 zOy_ofQ2&qiPY>IN8I3fmJw7@(di28))w9|-_vHl|2#vCI27lm5JPK^9;ByKjb%His zb$-xeI2IrjVhkXCP&eDXZo9j!+9Yx4!A-)@w_98eDlmWPda$)6p3|5`zw-@ee0NgC z*wI@}oJLR;(W(wPJ^#ETe!*0>)99Q@6&}B1KEyPt0k~6X@{x>To=Olk{D_>;REyt2 zoA;WX8hmF*GHCwj9KJjOqKT8!*nITt$3q_TlL)$?-0jsxGi*RTcVaO~=%OnH=C`?w z7cVIKJ&J!H20^2aomOd8Uy(8QtAkBq-J2)kffx`&XuA_X@aoO`3Z~x@Ff$JRR98wK zi0*yiL$@bMhp&2spI?8iy^zq!Vv@Y_PwwXqOI!ardDUz0oqVz7cks5)#-x)vV|0jX zHfc8fa4zo)0eJJxb5lp7e9~)A_Bj3u!FTe>;Z}bxCMbI~9MvHhO}7cfcy=D@!VTwD z_oRa>iH3JwyN18tZmBhZt07$g7(7WlsHecXw%jDCKd4b^7-%Au?PTV-!0%@_rFLWLnPu38Fa}4upgQzTVqteSZPH&Er zQa#lHs9v>rxaIZ^Hm$+a-NT%N!)W5B2H=lllHSXPd4qMfh7uA1ssMfxar)PfJPNTUyX=94q2<-`6N58~tq}!Z{ zMZK!E&rn*acq7`==wFpJrb$)tijrzAzycOKv&)Pu;>^_4*4c3AbH8ed=nbIO(l#QF zaiJ;a>=LFEgQYc?!t$e5i(3z7ue_U9F7zeKKyQF*=0VGz785ZXPa`uFx_p@cuJSROZZ#lNcs zes=K=OD~$4t<$GiBCP;xm6(|@PThT{G>eIQ(*jQt6UOP@-o1Op66sAa&K;vf@0;HK zei23I$xSdWocEdyLsC?tJSY-mn-VM+ih|6d1jU2H}c*gXIg)X0mG2GBKEOXEx$e+e|9K<2S-Z3UcCJ0lcVABPfw08VF*1+ zlp^~QubLy2*ih?c6wI5izrLTRo3${OU*1iVN((`?N7*hbZmXoaG6{nT;KFvcybboV+pdED~o@qK3$MWR4ze(zF0g! zZz^%UG~P7tmtMoh04b4PZ`$ClHpSNpjbDq+>&=$X^{~|i67BZ8T@bmd6iHh!L)|NT6ffpGT12@_12 z`VSeLOB9jCQ#pT^@FaWC5)UzlSxY2P6lBoYA1O$f-Uzyia$v2XGj8vq(7EyQ*&z(p z4Wttf$h?$~unYg|!FcE&Lz*RMT9)MjYZ2X$NDt|wU$r?R2s9!pUV+;^{GZ+J?W%5P zz3!xu%V7gowK9>m08yisFilSspm~4-uq`-uOEr{9LO*{@qnU!D9susrXj+0yz->S@ z(W*q?!)tqpdki3@)SFio>rG))%|I{5e}>FQ^vND8Rs{+XPzSSc;LH+oVKhKslD!dANlf?G^xy zOI(JU7z&#pGJPZ<0}Q-jtM*CrrZuESWYK&)OOFD)BId^^blj*VHV=WzVeI)+d9jH( zx5J1=V3D|cyI=CEWF;Q+M5?bjZKFLbR9}%pkNokR#%-EoFgvo0v4}q%SC8O(`rNnR zR`P#<0v)pOx`Jio3`p(!Nw2)FjKOd3mKep38s?;*Ppe*1J9&$GE;RM$-DJ*gR*S}H zF;zzSWV_r#|5h!S!1`SVwo?YyD+9B3=Di}UuIkusOHB4w!gF1>vZ{k3L8kR>Z+o!2 zOQs%8L!H3{(LS--_$@1*wtK%LGhWLfPCDz zqK4_#9}EV7DR}lE_kAms`9c-3UW|X{^#>sBsaFl_os-rdWX^M{gs@7uVf_L5(5bgA zQ38-T+uaI4Q}=NTu?Bwtt?(~k{{hbdBFo9W^y=9F`RrQInRUO8v)X@PxbwkG_Tk|? zfPVu2!L42UzTJY-ROP)r{AyJmehU5;b*wPXQ}p|5YrntML$!Sb)o3*!y#;^TqbP3Y z&Vp@r7OV!mO@Ox_tadbnhPDl~7Mu=g=|3RPLp7mjA<3R9Cq(^V=!%$k;`Yvn z2J-WH{@?%kf5}1dfB)zIx!FVUfB)zIvwRd+O((|_x7pLKtvnZ3Bfrwwv4C^(8)Tdo zydO1Um-|5GqrQbJq?$LwA5wocP`k-1GV8157|HN%;T@R~gNoT&;x(B!d6VB{4(h#K zCu_Frqy>3}_hjX`v^ymu$@HnzvwEXvWz9fK4*2~XENkpwnS*<0Kg+6}!hew6e%@}g zqBH_Q0*BXbKhV#;1)xn`xEe$b-V>Wn-Z+;;q4ZMp0}LxRf`vgkaX^2z^axUR7$8I= zPqn3ut7QFU>>4J0HEG=SP@IYYWq=CF$0W@aq4-t2fEtU;v;R9=w$Q(SG>ji}sH{J{kVw<&RII7``d^ zSyy4Vt9~ZmEnc!WRil57!c)D8ZcZ3m9eRg&ZrtEbvC~u09{cSU3tB*N$a`=dSM#U! z|LqNR0>GiQ8;MoCTXKk-@;`KU`gZ(he|vj(o&Vvl7XNqWUCHjLpf%pCnfF%c?uF8eSI>%mQ(8D%LF)6strzBjTCeW9~UG;8ay z%r*VD=>OYCf8I?0w|936@t@oK-F5uu$B+Ni3A$}D949{cps}B;8vbL2e%2_WQqE8( z<7`Eg+epE_JBFjhSt>nz3KluME~6!|F^xfU6B7NBydgt*YSV9WBlI=p0tynIXsiC zITw@LIT15$^3ZCdMPzkMT-l?`h>Ke~sr@^c)P8YN`_+?LniA!vrKd%CoT;BRyNQ0W ziT*n^F|b>mXqzJsN@U0kZ$w^*ufRDWgZkvc7Z2|w8NpKp2pV;ArL?DzZY z`yW5@{5uyzHzLnN*u|Y=?@s4`)%|bV-QB|c?{BZ~fB86{FOB=ZPZuJNE*E1N_Ny=Z z{!%;-q?1T~stGq=#|?N{dUbfG_A5HgURf*by7nu`U`|qcN-FvlGk;{Fz^EO;HUsEn zUR31{NiU**?Beew*H9zWIVzb~HLI}()&nuLMF57}Mhirip?ZM~@A0ELUeo+5hypa+ z~;coj?B{QT-Qu!Tz)A;x}g1H;)AI2 z7LfDdTwkFdzvH6YU$2SxpGz?h{om%G`l2hOKk^MeX-FegU967v5fA51Fb70Fy@*a?)CeBQ5g>EOA%<3%-10>r~z1hs_r7?^Zo%$Q0+Y&(Dy3N{b#_tm9 z0lh#2EcX65=OFs{cO5-zas$qFjq{cftQN+A&O|=iYyz0B}?M@9xfi zk^k@PZm;?OC&&No6_yDArN>GF(2vE7qeq9rk`WX)w`(>)8=OUcm=2Lqwz6Mogx`G+ z|HX2{Qy2_~i@}q063b))3OoHEg@4HGtG0~q>n5(RN<6wFo5Kp$UI4eo_f78`kxeV#>twzgO0V+^!-=Bj5F9=q_5+*HA(Sfi+Nf z629nDfy($SJJU%oZ_UJ;DQ3W&EkH`cmhl~h;1STQNRszC@uV?1cE=w9yK+KTl2}C| z5Fu8FK7@Gs9jm37h*)}am&E{iIcv1Ho1)>&X0W^|YgMoi-|T;iU%zZ#mqd}L&t4u4 zP>}SIQyJ?!5omsZv2?_<5EFEr0|O$*6SUxv`MR@&d;Nhqlu7^5O>ua78eQI{@^=gU zufJc^|MvE}>-gVKkp5>YET{eEBSrTO4`9wWr}F3dNI1~zh~7}DJc$(H6c2_`6=W!y zH)N0-2xLg%tgU~%n(-BdXb@_j{`BNYHObEbTwf)lueRtY$xzVf>#?#DGsVt`TGq;K ztD*|)ROUxyJ!^z1N12XNN<>bG$mtMUq&;Ci#AZbgaGcjyzsMkHpM@|%ZE~+b6~#$$ z0YD3=L$D278Pv1No4{wHC|YafahrXLp=`WdT?o$3Xp#M;n2}>iN-$*v*Ar6V08d?3QL$XmC{N^ zYrLJ(khn?|@dfP0Q3G@Z+L<|Vs--;|EdNI)WV3&MVsih(oYNdC*pxnE~`O4v;?@nB=d%hLh$^JRRYv) zXkcC@{rhQ!!bMsXrW_$re}q%i!jwm3^2)k^8WtZ0_4dE%tfcLw{g3>H)Tp~70ypjd zz5VT?{eQ2&&j0+W?*D9s6^MZOoGHOE>zse6Yicnl&9;o%sIc-e;fx16wn!5)fJ_)x zZhqd|sM+IQ$Nh`DxJo+A4A<)QeN8Jisp=-Fx0}gmv$WkGfoklg*#@r~N=`byGO5Og zvniMMKigG?xq;^W$-qteU$5V{_kX|F+gtDdPj&wnS6G1zRJ^XR3)8*^MM~T8*vNml z6W2W~)2EyzxcMy*=f_8f4__WVDmrK=X?Mw3QEx;qO2jxicUWRCKfJwidx$|aEZ?dVKo~F|Jk3~3 zojR9){&YUo$3ph~Uw=YhicgCE4?#k>BOY+0{J&o~|LJ$PclX!y{}ZSGxWbn30QE}Q z152+4!XPdz$##~p2Q0swMUW>nl=yTRL#}E7O0UY!CS{VpjEXCjVNJ#VGW7qB4uWo! z|NGlT`oFWirvHBh`rlu{0QxI9K)-?oh{id8%nSCV-(1NK`VFR+6#4b`OhMOObA~l% z_>|~>eo6gMU2px7etw=notf#3+Ec_O`zsKXPCR2snFG^z{s z^(NQ021oujRITQ(fghe-sq)t?vFvpkT{p9n@j=(I)>=U+SI%triFuLvv z^ujIeMMWP?Gp)FBjR zcj3z~L83!}0`qcv{p)yYf&5LE$Xxd^Q zM(#&w?0B9@edZjgEF~TBLQ3%~-In>ciuczPY3<1rgtw$qK?>ht(frj##wGM$&&bDr zu>bbAd!_Tg-JLc4|Fr49-qTfVAb)3b15PXC{|ox6HaCekYQN_jJs}@l$0kWD1jKUF zSt^l)l7`IV5&mUBc`^}gF#e{Czf7hAKhIhZ0+L5V=rkaj zqG`*qzPmlo%z=HcVp!s##v8DMi;0te;%qw##fyrBVuraGv0%%o-`O^8>f41>VaQ}} z1|V@xfWu&M7woXY{QWdDee=Df5^v%*Y~PrAN*TZ{d&)Q6BA0bUkve9xONhoG3XH+8W5NG8{C@;n|GkBPo8y0q_MhHvcg_F* z68xW5*eW4F7hp-?#r#xLk3puT80rUbc`UEeW8PxawU{0*eH^ z+umO}jt{#3wSD9+EC4szfA@Rk_`luWdjEgg``<9zR&0Ia?OWRbiWbc!8(zPrEZ|9t zcX`=796B%r_=TCTmL~#Vdg%XLZ=`}op2zy#m0tedX63TNi`L>y$EDnVp(>$GD=XT# zY!adxmjzUzmGxJ88+o$yHa`x-r`K01mXWpPhk9yJeT=3)C8wj@avBZAq^Gw~ezUQy z72s<6kMTj)A>xqJy1h3KxPks}Z*Q0A|Nib;{`>Uk|I!tf@qkq&m=F9Qi5$wJKWUb| z&>;6qp`m!k$ztG(KL101Pp3LQ2rtnIm~6V?BKt~?P*Xn~j-->$W0_FWe#$bJQekVF9G26H58bh$3&+)&w_*_RE=5|SK$?;JBVW8+ha_uY<# zJhDupkEF^@Eh6@c3}iS4 zB-2V%bA5RHB1=Mlnhy(0R9y^W0vM5VC9m>EG~>+#<%*X_AVWjPL#qNa?vasefPE9` zu$R0Fxvoy}a_)~q2`pbUF63$R`byt8=EhFgiQ6j6Q74MWTToz2RZF%A%9gGTJPk+{ zOcU-m?%fdP?zn@Og7HZ*p-DOQIIb&ae2=^y@iZys1!SUslO2>R|5NsXr<+E~8J?a! zdIoYBT~x#6lvbJNW>D#BDfaPO?Ai0h6r6E(TXxdwdF(`VK8m(x0o{DTbk@}eIW4m z@*mMRAY1Z(BjKv;pLA8;z#_$)GZ^stm9KCKs*o3 z>p=3FW`q}euXliP6c0+Q1}Y5)NP))Q_X+tWFt!!2R(YB*&&H^^N2O$}x;TTi~PI z=6V#xB;+9A!VblIH%KK}F+Jfcppm)c8V; zxp0vfyulJwM%_zh-BE_{&YaoI!RBTAo0gc)kq1Lp6W5`_eI(-`(x`i6UrvBdCUvXx z3R;svs{wJFv{o^|#@N33&=S-uppP&VydjN$t`U3s?4>yV>FKHq!`A%&t@*zXaxc2c z2hsR$1%Mm#zwZ|Bf8FnP*Y|&Ydi>v5VVMA6KVu2tC1(A^8^WXU*vkB56mH1NSqzjR zg6}{(=st-S)?f{!im_vjYx-9v37JYBf)u@7u2|Txd6^cqVjHP{L1l|>5CLF+ zsDD<~Q{5@5*H56!S;PplMT9h(1IR$XLyTE0`)Pz}3deNC2dR26k|;)NSXM`Aq{&RW zXz%y90bp^eBNZu#ZB(zR>0g)r z{{KGr-7}`fBc-7n8>hPt{0RYk&J}Wh7%JEYNnHzzt%~BQBFxW`Tq^sUI>1A^niKR3 z)aIVj^;Syv(yqXbou-j0US6h+CMYDyJV*@_GLu$JHJ_2zau~}k$A338+1USR#ie8^ zcbx$A=KRm4_`m(`+W+Iz+y8|XmJxySbLHtJQ@R13Z}R3epdu@yc7LIAA=le~s>E*3 z%sU=%8?zDrw$`2M>^_A^2>UuVK+;sEXu7dXF*(uT#Pja(`Lieg{NdSC!zRPd2f1BF zZPF6;P&xAp=&A_OqrTR))uwBLF<$a-m?1sGhwEN)u=LwBAgm+J50 zLtFg0wN)MlbjG{XIe|KP>*|?@!n@k_nJp;WH(?h3-%xhq<}&7jshINfe6qv)p&QJh zD2#}2plu794qQ5OI{i*BBAthVkwoQqz}hm8&T<(5&yS_6JbQT5cohQ}nl@7ZTn39Z z`}sihA8kw@)&AS-mF>U1lNe4e5!63L-=sCoU4K3p{Rd&doqUs5P9Fh>lXp%de>8lw zBefXdeY$%KzqJJViPXUgjNV~`AEUnZ)B z-09pvOGl`-2rGWN07?=CJcsjSP8sK&*-SEN(v}vcyd1V6gHhX!ql83E05pkEFpWJl z2^XC9$V~w={pJQ{)p;Yyd@>pgvxpOT#}U9FJv$w)q83TmU*n`d1Kl75z_Tk|tXps11_wc6XP`fAGoa{|-C{j?mlx zOzf`d|Hqww{1;Wrt>1C}+5ck)Yjf<~TP$%25garihlBa{@7tvhHj?>8VM+@O&aj5VM zWd%$qQ@<{TA%e=@gs@TB8u{aSO!COzpwbf%L_&ZBH62jz*yBG2iG#!;l~T|CC_i zB@-@G*djMeC*bM?vzEov>3YpP!j5)YvsS}bL%MmoQRj#CX6=tf|LNzQQGuJ{|M&NH z3j2S59smE)_J6MbQP|86r!dV&0s(a8^1Q{zaS~lCK4~QJWQ12e=5=T{kM9n zc2yJbLFFPI41&mYe}bW^3L6A%B(Oi0mmqzhsszU=Ck+hoZ6u@NJdwksuYJXvT;tSD zykSMys~P4>U1*7V=x$N*=rkGjzWL^xPUzMRC~VF-V6)C(z%jA-y^%EnyB~{ZwyLZS zUqqkVuyTOhKr$mIM|=#Wl?sH9OxQMPwr!O`8=zEo@)_i-f4heAH_!tcgj-v=j2ZlxX zu7m{@W1gPC{}_G+tZ*d@;5!?!N+pyeKDz7Rpx7o7 zi;E~egR*p{j7~QRNH!c2kY7IOu^~oh7HsGP86O4{&mvaS=rkCGWQ5K|k*q_nzH<`a zrG`d9bb*gH#B+^KwBJnq(4YGMqPT!Kj$-WmA&kMtt1;PU=rv3ROe%k#wBXl62bdZD zM$He}MNgz~!L|8#XW|4YT|bFk!nSGR&{X3<#iu&Ke{Dv7y{1DXpqHmAkk>2R z9HG!*WYipp*PI*TKxKwFP%xo zRSZz6ZaT$0ZuWp^YLwp>-PJ_Zi$E!4*^i+g*qI#cNXE`7o+5u@G&8*6G@gtF=>9LU zk0-a{^=OW{KRV8A7A#&1KE}kPP$7r>#L;{_Q5Q;6%f^ra%<()#H)PBqC!8q=JY=_| zV@m9?z7>zwM3j~;h2{J40M3i~>D0#{>NnA;4zL5n(1qCm1G=%Sstg$b&qeQc&p(FUG5l|0emE|3~w{;R^c{y=lzxn41TxW&r2`0Kvl(J^%m! From 66d4adcaae89113fc8de61d080699a7839209904 Mon Sep 17 00:00:00 2001 From: Insang Song Date: Wed, 4 Oct 2023 11:44:16 -0400 Subject: [PATCH 20/21] Local R CMD check cleared (0.0.3) - Added functions - Fixed missing argument entries in Roxygen documentation - Roxygen syntax error fixed - Vignette naming convention - Local R CMD check passed with three NOTEs, no WARNINGs/ERRORs --- scomps.Rcheck/00_pkg_src/scomps/DESCRIPTION | 21 + scomps.Rcheck/00_pkg_src/scomps/LICENSE | 2 + scomps.Rcheck/00_pkg_src/scomps/NAMESPACE | 27 + scomps.Rcheck/00_pkg_src/scomps/R/check.R | 180 ++++++ .../00_pkg_src/scomps/R/estimate_demands.R | 24 + scomps.Rcheck/00_pkg_src/scomps/R/indexing.R | 25 + .../scomps/R/interpret_computational_domain.R | 210 +++++++ scomps.Rcheck/00_pkg_src/scomps/R/logging.R | 20 + .../00_pkg_src/scomps/R/preprocessing.R | 36 ++ .../00_pkg_src/scomps/R/processing.R | 364 +++++++++++ .../00_pkg_src/scomps/R/switch_format.R | 25 + scomps.Rcheck/00_pkg_src/scomps/R/validate.R | 18 + .../doc/v00_good_practice_parallelization.R | 4 + .../doc/v00_good_practice_parallelization.Rmd | 2 +- .../v00_good_practice_parallelization.html | 408 +++++++++++++ .../doc/v01_generate_computational_grid.R | 22 + .../doc/v01_generate_computational_grid.Rmd | 2 +- .../doc/v01_generate_computational_grid.html | 388 ++++++++++++ .../00_pkg_src/scomps/man/aw_covariates.Rd | 41 ++ .../00_pkg_src/scomps/man/calculate_sedc.Rd | 34 ++ .../00_pkg_src/scomps/man/check_bbox.Rd | 24 + .../00_pkg_src/scomps/man/check_crs.Rd | 28 + .../00_pkg_src/scomps/man/check_crs2.Rd | 19 + .../00_pkg_src/scomps/man/check_packbound.Rd | 20 + .../scomps/man/check_within_reference.Rd | 22 + .../00_pkg_src/scomps/man/clip_as_extent.Rd | 26 + .../scomps/man/clip_as_extent_ras.Rd | 23 + .../scomps/man/clip_as_extent_ras2.Rd | 23 + .../scomps/man/distribute_process.Rd | 26 + .../00_pkg_src/scomps/man/estimate_demands.Rd | 23 + .../scomps/man/extent_to_polygon.Rd | 21 + .../00_pkg_src/scomps/man/extract_with.Rd | 27 + .../scomps/man/extract_with_buffer.Rd | 43 ++ .../scomps/man/extract_with_polygons.Rd | 28 + .../scomps/man/get_computational_regions.Rd | 53 ++ .../00_pkg_src/scomps/man/grid_merge.Rd | 38 ++ .../00_pkg_src/scomps/man/initate_log.Rd | 24 + .../00_pkg_src/scomps/man/rast_short.Rd | 22 + .../00_pkg_src/scomps/man/set_clip_extent.Rd | 22 + .../00_pkg_src/scomps/man/sp_index_grid.Rd | 24 + .../00_pkg_src/scomps/man/sp_indexing.Rd | 21 + .../00_pkg_src/scomps/man/switch_packbound.Rd | 20 + .../scomps/man/validate_and_repair_vectors.Rd | 20 + .../00_pkg_src/scomps/tests/testthat.R | 12 + .../00_pkg_src/scomps/tests/testthat/tests.R | 65 ++ .../v00_good_practice_parallelization.Rmd | 2 +- .../v01_generate_computational_grid.Rmd | 2 +- scomps.Rcheck/00check.log | 79 +++ scomps.Rcheck/00install.out | 13 + scomps.Rcheck/Rdlatex.log | 564 +++++++++++++++++ scomps.Rcheck/scomps-Ex.R | 121 ++++ scomps.Rcheck/scomps-Ex.Rout | 212 +++++++ scomps.Rcheck/scomps-Ex.pdf | Bin 0 -> 3611 bytes scomps.Rcheck/scomps-manual.log | 570 ++++++++++++++++++ scomps.Rcheck/scomps-manual.pdf | Bin 0 -> 116155 bytes scomps.Rcheck/scomps/DESCRIPTION | 22 + scomps.Rcheck/scomps/INDEX | 39 ++ scomps.Rcheck/scomps/LICENSE | 2 + scomps.Rcheck/scomps/Meta/Rd.rds | Bin 0 -> 1232 bytes scomps.Rcheck/scomps/Meta/features.rds | Bin 0 -> 123 bytes scomps.Rcheck/scomps/Meta/hsearch.rds | Bin 0 -> 1124 bytes scomps.Rcheck/scomps/Meta/links.rds | Bin 0 -> 517 bytes scomps.Rcheck/scomps/Meta/nsInfo.rds | Bin 0 -> 453 bytes scomps.Rcheck/scomps/Meta/package.rds | Bin 0 -> 994 bytes scomps.Rcheck/scomps/Meta/vignette.rds | Bin 0 -> 277 bytes scomps.Rcheck/scomps/NAMESPACE | 27 + scomps.Rcheck/scomps/R/scomps | 27 + scomps.Rcheck/scomps/R/scomps.rdb | Bin 0 -> 35289 bytes scomps.Rcheck/scomps/R/scomps.rdx | Bin 0 -> 729 bytes scomps.Rcheck/scomps/doc/index.html | 34 ++ .../doc/v00_good_practice_parallelization.R | 4 + .../doc/v00_good_practice_parallelization.Rmd | 39 ++ .../v00_good_practice_parallelization.html | 408 +++++++++++++ .../doc/v01_generate_computational_grid.R | 22 + .../doc/v01_generate_computational_grid.Rmd | 46 ++ .../doc/v01_generate_computational_grid.html | 388 ++++++++++++ scomps.Rcheck/scomps/help/AnIndex | 25 + scomps.Rcheck/scomps/help/aliases.rds | Bin 0 -> 350 bytes scomps.Rcheck/scomps/help/paths.rds | Bin 0 -> 442 bytes scomps.Rcheck/scomps/help/scomps.rdb | Bin 0 -> 35998 bytes scomps.Rcheck/scomps/help/scomps.rdx | Bin 0 -> 769 bytes scomps.Rcheck/scomps/html/00Index.html | 76 +++ scomps.Rcheck/scomps/html/R.css | 130 ++++ scomps.Rcheck/tests/startup.Rs | 4 + scomps.Rcheck/tests/testthat.R | 12 + scomps.Rcheck/tests/testthat.Rout | 37 ++ scomps.Rcheck/tests/testthat/tests.R | 65 ++ scomps/DESCRIPTION | 8 +- scomps/NAMESPACE | 3 +- scomps/R/check.R | 65 +- scomps/R/estimate_demands.R | 1 + scomps/R/indexing.R | 4 +- scomps/R/interpret_computational_domain.R | 28 +- scomps/R/preprocessing.R | 3 +- scomps/R/processing.R | 140 +++-- scomps/R/switch_format.R | 2 +- scomps/man/aw_covariates.Rd | 16 +- scomps/man/calculate_sedc.Rd | 10 +- scomps/man/check_bbox.Rd | 4 +- scomps/man/check_crs.Rd | 4 +- scomps/man/check_crs2.Rd | 6 +- scomps/man/check_packbound.Rd | 4 +- scomps/man/check_within_reference.Rd | 4 +- scomps/man/clip_as_extent.Rd | 4 +- scomps/man/clip_as_extent_ras.Rd | 4 +- scomps/man/clip_as_extent_ras2.Rd | 4 +- scomps/man/distribute_process.Rd | 6 +- scomps/man/estimate_demands.Rd | 7 +- scomps/man/extent_to_polygon.Rd | 21 + scomps/man/extract_with.Rd | 4 +- scomps/man/extract_with_buffer.Rd | 4 +- scomps/man/extract_with_buffer.flat.Rd | 20 - scomps/man/extract_with_buffer.kernel.Rd | 20 - scomps/man/extract_with_polygons.Rd | 4 +- scomps/man/get_computational_regions.Rd | 8 +- scomps/man/grid_merge.Rd | 14 +- scomps/man/initate_log.Rd | 4 +- scomps/man/rast_short.Rd | 12 +- scomps/man/set_clip_extent.Rd | 4 +- scomps/man/sp_index_grid.Rd | 4 +- scomps/man/sp_indexing.Rd | 4 +- scomps/man/switch_packbound.Rd | 4 +- scomps/man/validate_and_repair_vectors.Rd | 4 +- .../v00_good_practice_parallelization.Rmd | 39 ++ .../v01_generate_computational_grid.Rmd | 46 ++ scomps_rmarkdown_litr.html | 298 ++++----- scomps_rmarkdown_litr.rmd | 266 ++++---- tools/tarballs/scomps_0.0.3.10042023.tar.gz | Bin 0 -> 22596 bytes .../v00_good_practice_parallelization.Rmd | 39 ++ .../v01_generate_computational_grid.Rmd | 46 ++ 130 files changed, 6220 insertions(+), 469 deletions(-) create mode 100644 scomps.Rcheck/00_pkg_src/scomps/DESCRIPTION create mode 100644 scomps.Rcheck/00_pkg_src/scomps/LICENSE create mode 100644 scomps.Rcheck/00_pkg_src/scomps/NAMESPACE create mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/check.R create mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/estimate_demands.R create mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/indexing.R create mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/interpret_computational_domain.R create mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/logging.R create mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/preprocessing.R create mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/processing.R create mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/switch_format.R create mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/validate.R create mode 100644 scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.R rename tools/vignettes-sources/00_good_practice_parallelization.Rmd => scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.Rmd (95%) create mode 100644 scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.html create mode 100644 scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.R rename tools/vignettes-sources/01_generate_computational_grid.Rmd => scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.Rmd (92%) create mode 100644 scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.html create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/aw_covariates.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/calculate_sedc.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/check_bbox.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/check_crs.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/check_crs2.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/check_packbound.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/check_within_reference.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras2.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/distribute_process.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/estimate_demands.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/extent_to_polygon.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/extract_with.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/extract_with_buffer.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/extract_with_polygons.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/get_computational_regions.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/grid_merge.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/initate_log.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/rast_short.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/set_clip_extent.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/sp_index_grid.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/sp_indexing.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/switch_packbound.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/validate_and_repair_vectors.Rd create mode 100644 scomps.Rcheck/00_pkg_src/scomps/tests/testthat.R create mode 100644 scomps.Rcheck/00_pkg_src/scomps/tests/testthat/tests.R rename scomps/vignettes/00_good_practice_parallelization.Rmd => scomps.Rcheck/00_pkg_src/scomps/vignettes/v00_good_practice_parallelization.Rmd (95%) rename scomps/vignettes/01_generate_computational_grid.Rmd => scomps.Rcheck/00_pkg_src/scomps/vignettes/v01_generate_computational_grid.Rmd (92%) create mode 100644 scomps.Rcheck/00check.log create mode 100644 scomps.Rcheck/00install.out create mode 100644 scomps.Rcheck/Rdlatex.log create mode 100644 scomps.Rcheck/scomps-Ex.R create mode 100644 scomps.Rcheck/scomps-Ex.Rout create mode 100644 scomps.Rcheck/scomps-Ex.pdf create mode 100644 scomps.Rcheck/scomps-manual.log create mode 100644 scomps.Rcheck/scomps-manual.pdf create mode 100644 scomps.Rcheck/scomps/DESCRIPTION create mode 100644 scomps.Rcheck/scomps/INDEX create mode 100644 scomps.Rcheck/scomps/LICENSE create mode 100644 scomps.Rcheck/scomps/Meta/Rd.rds create mode 100644 scomps.Rcheck/scomps/Meta/features.rds create mode 100644 scomps.Rcheck/scomps/Meta/hsearch.rds create mode 100644 scomps.Rcheck/scomps/Meta/links.rds create mode 100644 scomps.Rcheck/scomps/Meta/nsInfo.rds create mode 100644 scomps.Rcheck/scomps/Meta/package.rds create mode 100644 scomps.Rcheck/scomps/Meta/vignette.rds create mode 100644 scomps.Rcheck/scomps/NAMESPACE create mode 100644 scomps.Rcheck/scomps/R/scomps create mode 100644 scomps.Rcheck/scomps/R/scomps.rdb create mode 100644 scomps.Rcheck/scomps/R/scomps.rdx create mode 100644 scomps.Rcheck/scomps/doc/index.html create mode 100644 scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.R create mode 100644 scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.Rmd create mode 100644 scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.html create mode 100644 scomps.Rcheck/scomps/doc/v01_generate_computational_grid.R create mode 100644 scomps.Rcheck/scomps/doc/v01_generate_computational_grid.Rmd create mode 100644 scomps.Rcheck/scomps/doc/v01_generate_computational_grid.html create mode 100644 scomps.Rcheck/scomps/help/AnIndex create mode 100644 scomps.Rcheck/scomps/help/aliases.rds create mode 100644 scomps.Rcheck/scomps/help/paths.rds create mode 100644 scomps.Rcheck/scomps/help/scomps.rdb create mode 100644 scomps.Rcheck/scomps/help/scomps.rdx create mode 100644 scomps.Rcheck/scomps/html/00Index.html create mode 100644 scomps.Rcheck/scomps/html/R.css create mode 100644 scomps.Rcheck/tests/startup.Rs create mode 100644 scomps.Rcheck/tests/testthat.R create mode 100644 scomps.Rcheck/tests/testthat.Rout create mode 100644 scomps.Rcheck/tests/testthat/tests.R create mode 100644 scomps/man/extent_to_polygon.Rd delete mode 100644 scomps/man/extract_with_buffer.flat.Rd delete mode 100644 scomps/man/extract_with_buffer.kernel.Rd create mode 100644 scomps/vignettes/v00_good_practice_parallelization.Rmd create mode 100644 scomps/vignettes/v01_generate_computational_grid.Rmd create mode 100644 tools/tarballs/scomps_0.0.3.10042023.tar.gz create mode 100644 tools/vignettes-sources/v00_good_practice_parallelization.Rmd create mode 100644 tools/vignettes-sources/v01_generate_computational_grid.Rmd diff --git a/scomps.Rcheck/00_pkg_src/scomps/DESCRIPTION b/scomps.Rcheck/00_pkg_src/scomps/DESCRIPTION new file mode 100644 index 00000000..eae7ecd6 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/DESCRIPTION @@ -0,0 +1,21 @@ +Package: scomps +Title: Scalable R geospatial computation +Version: 0.0.3.10042023 +Authors@R: + person("Insang", "Song", , "geoissong@gmail.com", role = c("aut", "cre"), + comment = c(ORCID = "0000-0001-8732-3256")) +Description: A package for scalable geospatial computation for + environmental health research +License: MIT + file LICENSE +Encoding: UTF-8 +Roxygen: list(markdown = TRUE) +RoxygenNote: 7.2.3 +Imports: covr, dplyr, future, future.apply, methods, rlang, sf, stars, + terra, testthat, units +Suggests: future.batchtools, igraph, knitr, logr, rmarkdown, withr +VignetteBuilder: knitr +Config/testthat/edition: 3 +NeedsCompilation: no +Packaged: 2023-10-04 15:41:03 UTC; songi2 +Author: Insang Song [aut, cre] () +Maintainer: Insang Song diff --git a/scomps.Rcheck/00_pkg_src/scomps/LICENSE b/scomps.Rcheck/00_pkg_src/scomps/LICENSE new file mode 100644 index 00000000..74e6421f --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2023 +COPYRIGHT HOLDER: I. Song diff --git a/scomps.Rcheck/00_pkg_src/scomps/NAMESPACE b/scomps.Rcheck/00_pkg_src/scomps/NAMESPACE new file mode 100644 index 00000000..b8f3fc6a --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/NAMESPACE @@ -0,0 +1,27 @@ +# Generated by roxygen2: do not edit by hand + +export(aw_covariates) +export(calculate_sedc) +export(check_bbox) +export(check_crs) +export(check_crs2) +export(check_packbound) +export(check_within_reference) +export(clip_as_extent) +export(clip_as_extent_ras) +export(clip_as_extent_ras2) +export(distribute_process) +export(estimate_demands) +export(extent_to_polygon) +export(extract_with) +export(extract_with_buffer) +export(extract_with_polygons) +export(get_computational_regions) +export(grid_merge) +export(initate_log) +export(rast_short) +export(set_clip_extent) +export(sp_index_grid) +export(sp_indexing) +export(switch_packbound) +export(validate_and_repair_vectors) diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/check.R b/scomps.Rcheck/00_pkg_src/scomps/R/check.R new file mode 100644 index 00000000..2e1bbcf2 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/R/check.R @@ -0,0 +1,180 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' @title Return the package the input object is based on +#' @description Detect whether the input object is sf or Spat* object. +#' @author Insang Song +#' @param input Spat* in terra or sf object. +#' @return A character object; one of 'terra' and 'sf' +#' @export +check_packbound <- function(input) { + # cl_inobj = class(input)[1] + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) + if (methods::is(input, "SpatVector") || methods::is(input, "SpatRaster")) { + return("terra") + } + return("sf") +} + +check_datatype <- function(input) { + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) + if (any(methods::is(input, "SpatVector"), methods::is(input, "sf"))) { + return("vector") + } + if (any(methods::is(input, "SpatRaster"), methods::is(input, "stars"))) { + return("raster") + } +} + +#' @title check_crs2: Coordinate system checker +#' @description The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179. +#' @param input Input object one of sf or terra::Spat* object +#' @param crs_standard character(1). A standard definition of coordinate reference system. Default is "EPSG:4326" Consult [epsg.io](https://epsg.io) for details of other CRS. +#' @return A (reprojected) sf or SpatVector object. +#' @export +check_crs2 <- function(input, crs_standard = "EPSG:4326") { + check_crs.sf <- function(input){ + if (is.na(sf::st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} + if (sf::st_crs(input)$epsg == crs_standard ) { + return(input) + } + input_transformed <- sf::st_transform(input, sf::st_crs(crs_standard)) + return(input_transformed) + } + + check_crs.terra <- function(input) { + if (terra::crs(input, describe = TRUE)$code == crs_standard) { + return(input) + } + input_transformed = terra::project(input, terra::crs(crs_standard)) + return(input_transformed) + } + detected = check_packbound(input) + switch(detected, + terra = check_crs.terra(input), + sf = check_crs.sf(input)) + } + +#' Generate a rectangular polygon from extent +#' +#' @param extent input extent. A numeric vector with xmin/xmax/ymin/ymax, sf::st_bbox() or terra::ext() outputs. +#' @param output_class character(1). Class of the output polygon. One of "sf" or "terra" +#' @param crs character(1). Coordinate reference system definition. +#' @author Insang Song +#' @export +extent_to_polygon <- function(extent, output_class = "terra", crs = "EPSG:4326") { + if (!output_class %in% c("sf", "terra")) { + stop("output_class should be one of 'sf' or 'terra'.\n") + } + if (methods::is(extent, "numeric")) { + if (is.null(attr(extent, "names"))) { + stop("Your extent is an unnamed numeric vector. Please define names xmin/xmax/ymin/ymax explicitly.\n") + } + extent = switch( + output_class, + sf = sf::st_bbox(extent), + terra = terra::ext(extent) + ) + } + + extent_polygon = switch( + output_class, + sf = sf::st_as_sfc(extent), + terra = terra::vect(extent) + ) + + extent_polygon = switch( + output_class, + sf = sf::st_set_crs(extent_polygon, sf::st_crs(crs)), + terra = terra::set.crs(extent_polygon, terra::crs(crs)) + ) + + return(extent_polygon) + +} + + +#' Check if the data extent is inside the reference bounding box +#' +#' @description One of the most common errors in spatial computation is rooted in the entirely or partly incomparable spatial extents of input datasets. This function returns whether your data is inside the target computational extent. It is assumed that you know and have the exact computational region. This function will return TRUE if the reference region completely contains your data's extent and FALSE otherwise. +#' @param data_query sf*/stars/SpatVector/SpatRaster object. +#' @param reference sf*/stars/SpatVector/SpatRaster object or a named numeric vector with four names (xmin, ymin, xmax, and ymax). +#' @param reference_crs Well-known-text-formatted or EPSG code of the reference's coordinate system. Only required when a named numeric vector is passed to reference. +#' @return TRUE (the queried data extent is completely within the reference bounding box) or FALSE +#' @author Insang Song \email{geoissong@@gmail.com} +#' +#' @export +check_bbox <- function( + data_query, reference, reference_crs = NULL +) { + if (is.numeric(reference) && is.null(reference_crs)) { + stop("CRS should be entered when the reference extent is a vector.\n") + } + if (is.numeric(reference) && !is.null(reference_crs)) { + reference = sf::st_as_sfc(sf::st_bbox(reference), crs = reference_crs) + } + query_crs = check_crs(data_query) + ref_crs = check_crs(reference) + if (is.na(query_crs) || is.null(query_crs)) { + stop("The dataset you queried has no CRS. Please make sure your dataset has the correct CRS.\n") + } + query_matched = sf::st_transform(data_query, sf::st_crs(ref_crs)) + + + + check_result = sf::st_within() + return(check_result) +} + + + +#' Check Coordinate Reference System +#' @param x sf/stars/SpatVector/SpatRaster object. +#' @return A st_crs or crs object. +#' @description +#' @author Insang Song \email{geoissong@@gmail.com} +#' @examples +#' # data +#' library(sf) +#' ncpath = system.file("shape/nc.shp", package = "sf") +#' nc = read_sf(ncpath) +#' check_crs(nc) +#' +#' @export +check_crs <- function(x) { + stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) + + if (methods::is(x, "sf") || methods::is(x, "stars")) { + crs_wkt = sf::st_crs(x) + } else { + crs_wkt = terra::crs(x) + } + + stopifnot("No CRS is defined in the input. Please consult the metadata or the data source.\n" = !is.na(crs_wkt) || crs_wkt != "") + return(crs_wkt) +} + +#' Check if the boundary of the vector/raster object is inside the reference +#' @param input_object sf/stars/SpatVector/SpatRaster object. +#' @param reference sf/stars/SpatVector/SpatRaster object. +#' @return logical +#' @author Insang Song \email{geoissong@@gmail.com} +#' @export +check_within_reference <- function(input_object, reference) { + stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) + stopifnot("Reference is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) + + bbox_input <- input_object + sf::st_bbox() |> + sf::st_as_sfc() + + bbox_reference = reference |> + sf::st_bbox() |> + sf::st_as_sfc() + + iswithin = sf::st_covered_by(bbox_input, bbox_reference) + iswithin = length(iswithin[[1]]) + iswithin = (iswithin == 1) + invisible(iswithin) +} + + diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/estimate_demands.R b/scomps.Rcheck/00_pkg_src/scomps/R/estimate_demands.R new file mode 100644 index 00000000..0c0bf6d7 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/R/estimate_demands.R @@ -0,0 +1,24 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' Estimate computational demands from inputs (to be written) +#' +#' @param inputs a list of sf/Spat* objects or file paths +#' @param nx integer(1). +#' @param ny integer(1). +#' @param padding numeric(1). Extrusion factor +#' @author Insang Song +#' @export +estimate_demands <- function( + inputs, + nx, ny, + padding +) { + ## cpu + ## memory + ## estimate maximum coverage + ## clipped data size + ## total distributed memory + ## return a list of total demands + ## print summary of results +} + diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/indexing.R b/scomps.Rcheck/00_pkg_src/scomps/R/indexing.R new file mode 100644 index 00000000..7555a3f9 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/R/indexing.R @@ -0,0 +1,25 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' @title Create integer indices for grid +#' @description Returns a tibble object that includes x- and y- index by using two inputs ncutsx and ncutsy, which are x- and y-directional splits, respectively. +#' @author Insang Song +#' @param points_in sf object. +#' @param ncutsx integer(1). The number of splits along x-axis. +#' @param ncutsy integer(1). The number of splits along y-axis. +#' @export +sp_indexing <- function(points_in, ncutsx, ncutsy){ + # pts <- data.table(pnts) + points_in <- points_in |> + dplyr::mutate(or_id = seq(1, dim(points_in)[1])) + + range_x <- range(points_in$x) + limits_x <- (range_x[1] + seq(0, ncutsx) * (range_x[2] - range_x[1]) / ncutsx) + range_y <- range(points_in$y) + limits_y <- (range_y[1] + seq(0, ncutsy) * (range_y[2] - range_y[1]) / ncutsy) + + points_in_cut <- points_in |> + dplyr::mutate(xcut = as.integer(cut(x, ncutsx, labels = seq(1, ncutsx))), + ycut = as.integer(cut(y, ncutsy, labels = seq(1, ncutsy)))) + + return(points_in_cut) +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/interpret_computational_domain.R b/scomps.Rcheck/00_pkg_src/scomps/R/interpret_computational_domain.R new file mode 100644 index 00000000..90132a7f --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/R/interpret_computational_domain.R @@ -0,0 +1,210 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' Get a set of computational regions +#' +#' @param input sf or Spat* object. +#' @param mode character(1). Mode of region construction. One of "grid" (simple grid regardless of the number of features in each grid), "density" (clustering-based varying grids), "grid_advanced" (merging adjacent grids with smaller number of features than grid_min_features). +#' @param nx integer(1). The number of grids along x-axis. +#' @param ny integer(1). The number of grids along y-axis. +#' @param grid_min_features integer(1). A threshold to merging adjacent grids +#' @param padding numeric(1). A extrusion factor to make buffer to clip actual datasets. Depending on the length unit of the CRS of input. +#' @param unit character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See [units package vignette (web)](https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html) for the list of acceptable unit forms. +#' @param ... arguments passed to the internal function +#' @return A set of polygons in the input class +#' @description TODO. Using input points, the bounding box is split to the predefined numbers of columns and rows. Each grid will be buffered by the radius. +#' @author Insang Song +#' @examples +#' # data +#' library(sf) +#' ncpath = system.file("shape/nc.shp", package = "sf") +#' nc = read_sf(ncpath) +#' nc = st_transform(nc, "EPSG:5070") +#' # run +#' # nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) +#' +#' @export +get_computational_regions <- function(input, mode = "grid", nx = 10, ny = 10, grid_min_features = 30, padding = NULL, unit = NULL, ...) { + # type check + package_detected = check_packbound(input) + # stopifnot("Invalid input.\n" = !any(grepl("^(sf|Spat)", class(input)))) + stopifnot("Argument mode should be one of 'grid', 'grid_advanced', or 'density'.\n" = !mode %in% c("grid", "grid_advanced", "density")) + stopifnot("Ensure that nx, ny, and grid_min_features are all integer.\n" = all(is.integer(nx), is.integer(y), is.integer(grid_min_features))) + stopifnot("padding should be numeric. We convert padding to numeric...\n" = !is.numeric(padding)) + # valid unit compatible with units::set_units? + + # if (detected_pnts == "sf") { + # } + # if (detected_pnts == "terra") { + # grid1$ID = seq(1, nrow(grid1)) + # } + } + +#' @title sp_index_grid: Generate grid polygons +#' @description Returns a sf object that includes x- and y- index by using two inputs ncutsx and ncutsy, which are x- and y-directional splits, respectively. +#' @author Insang Song +#' @param points_in sf or SpatVector object. Target points of computation. +#' @param ncutsx integer(1). The number of splits along x-axis. +#' @param ncutsy integer(1). The number of splits along y-axis. +#' @return A sf or SpatVector object of computation grids with unique grid id (CGRIDID). +#' @export +sp_index_grid <- function(points_in, ncutsx, ncutsy){ + package_detected = check_packbound(points_in) + + sp_index_grid.sf = function(points_in, ncutsx, ncutsy) { + grid1 <- sf::st_make_grid(points_in, n = c(ncutsx, ncutsy)) |> + as.data.frame() |> + sf::st_as_sf() + grid1 <- grid1[points_in, ] + return(grid1) + } + sp_index_grid.terra = function(points_in, ncutsx, ncutsy) { + grid1 <- terra::rast(points_in, nrows = ncutsy, ncols = ncutsx) + grid1 <- terra::as.polygons(grid1) + return(grid1) + } + grid_out = switch(package_detected, + sf = sp_index_grid.sf(points_in, ncutsx, ncutsy), + terra = sp_index_grid.terra(points_in, ncutsx, ncutsy)) + + grid_out$CGRIDID = seq(1, nrow(x = grid_out)) + return(grid_out) + +} + + +#' @title grid_merge: Merge grid polygons with given rules +#' @description Merge boundary-sharing (in "Rook" contiguity) grids with fewer target features than the threshold. This function strongly assumes that the input is returned from the sp_index_grid, which has 'CGRIDID' as the unique id field. +#' @author Insang Song +#' @param points_in sf or SpatVector object. Target points of computation. +#' @param grid_in sf or SpatVector object. The grid generated by sp_index_grid +#' @param grid_min_features integer(1). Threshold to merge adjacent grids. +#' @return A sf or SpatVector object of computation grids. +#' @examples +#' # library(sf) +#' # library(igraph) +#' # ligrary(dplyr) +#' # dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +#' # sf::st_crs(dg) = 5070 +#' # dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) +#' # dgs$CGRIDID = seq(1, nrow(dgs)) +#' # +#' # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") +#' # sf::st_crs(dg_sample) = sf::st_crs(dg) +#' # dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) +#' #### NOT RUN #### +#' @export +grid_merge <- function(points_in, grid_in, grid_min_features){ + package_detected = check_packbound(points_in) + if (package_detected == "terra") { + points_in = sf::st_as_sf(points_in) + grid_in = sf::st_as_sf(grid_in) + } + + n_points_in_grid = lengths(sf::st_intersects(grid_in, points_in)) + grid_self = sf::st_relate(grid_in, grid_in, pattern = "2********") + grid_rook = sf::st_relate(grid_in, grid_in, pattern = "F***1****") + grid_rooks = mapply(c, grid_self, grid_rook, SIMPLIFY = FALSE) + grid_lt_threshold = (n_points_in_grid < grid_min_features) + stopifnot("Threshold is too low. Please try higher threshold.\n" = sum(grid_lt_threshold) != 0) + grid_lt_threshold = seq(1, nrow(grid_in))[grid_lt_threshold] + + # This part does not work as expected. Should investigate edge list and actual row index of the grid object; + identified = lapply(grid_rooks, \(x) sort(x[which(x %in% grid_lt_threshold)])) + identified = identified[grid_lt_threshold] + identified = unique(identified) + identified = identified[sapply(identified, length) > 1] + + identified_graph = lapply(identified, \(x) t(utils::combn(x, 2))) |> + Reduce(f = rbind, x = _) |> + unique() |> + apply(X = _, 2, as.character) |> + igraph::graph_from_edgelist(el = _, directed = 0) |> + igraph::mst() |> + igraph::components() + # return(identified_graph) + + identified_graph_member = identified_graph$membership + + merge_idx = as.integer(names(identified_graph_member)) + merge_member = split(merge_idx, identified_graph_member) + merge_member_label = unlist(lapply(merge_member, \(x) paste(x, collapse = "_"))) + merge_member_label = merge_member_label[identified_graph_member] + + # sf object manipulation + grid_out = grid_in + grid_out[["CGRIDID"]][merge_idx] = merge_member_label + # for (k in seq_along(merge_member_label)) { + # target_idx = merge_member_label[[k]] + # grid_out[["CGRIDID"]][target_idx] = paste("M_", paste(target_idx, collapse = "_"), sep = "") + # } + grid_out = grid_out |> + dplyr::group_by(!!rlang::sym("CGRIDID")) |> + dplyr::summarize(n_merged = dplyr::n()) |> + dplyr::ungroup() + + ## polsby-popper test for shape compactness + grid_merged = grid_out[which(grid_out$n_merged > 1),] + grid_merged_area = as.numeric(sf::st_area(grid_merged)) + grid_merged_perimeter = as.numeric(sf::st_length(sf::st_cast(grid_merged, "LINESTRING"))) + grid_merged_pptest = (4 * pi * grid_merged_area) / (grid_merged_perimeter ^ 2) + + # pptest value is bounded [0,1]; 0.3 threshold is groundless at this moment, possibly will make it defined by users. + if (max(unique(identified_graph_member)) > floor(0.1 * nrow(grid_in)) || any(grid_merged_pptest < 0.3)) { + warning("The reduced computational regions have too complex shapes. Consider increasing thresholds or using the original grids.\n") + } + + return(grid_out) + + # union unique sets into one + # identified_relation = matrix(NA, length(identified), length(identified)) + # diag(identified_relation) = lengths(identified) + + # for (i in seq_len(length(identified))) { + # for (j in seq(i, length(identified))) { + # identified_relation[i, j] = length(intersect(identified[[i]], identified[[j]])) + # identified_relation[j, i] = identified_relation[i, j] + # } + # } + # # identified_relation = max(identified_relation) - identified_relation + # return(as.dist(identified_relation)) +} + + + + +#' @title Process a given function in the entire or partial computational grids (under construction) +#' +#' @description Should +#' @param grids sf/SpatVector object. Computational grids. +#' @param grid_id character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. \code{"id_from:id_to"} format or \code{c(unique(grid_id)[id_from], unique(grid_id)[id_to])} +#' @param fun function supported in scomps. +#' @param ... Arguments passed to fun. +#' @return a data.frame object with mean value +#' @author Insang Song \email{geoissong@@gmail.com} +#' +#' @export +distribute_process <- function(grids, grid_id = NULL, fun, ...) { + + # subset using grids and grid_id + if (!is.null(grid_id)) { + if (is.character(grid_id)) { + grid_id_parsed = strsplit(grid_id, ":", fixed = TRUE)[[1]] + grid_ids = c(which(unique(grids[["CGRIDID"]]) == grid_id_parsed[1]), + which(unique(grids[["CGRIDID"]]) == grid_id_parsed[2])) + } + if (is.numeric(grid_id)) { + grid_ids = unique(grids[["CGRIDID"]])[grid_id] + } + } + grids_target = grids[grid_ids,] + grids_target_list = split(grids_target, grids_target[["CGRIDID"]]) + + results_distributed = future.apply::future_lapply( + \(x, ...) { + fun(...) + }, grids_target_list, + future.seed = TRUE) + results_distributed = do.call(rbind, results_distributed) + return(results_distributed) +} + diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/logging.R b/scomps.Rcheck/00_pkg_src/scomps/R/logging.R new file mode 100644 index 00000000..87a7dab2 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/R/logging.R @@ -0,0 +1,20 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' Turn on logging +#' @author Insang Song +#' @param expr expression. Any function call to be logged. +#' @param dolog logical(1). Will the messages be logged. +#' @param logpath character(1). Log file path with the full log file name. +#' @return Nothing. It will export a log file in the specified path as logpath. +#' @export +initate_log <- function(expr, dolog = FALSE, logpath) { + if (!dolog) { + return(NULL) + } + logr::log_path(logpath) + try(expr) + logr::log_close() + return(NULL) +} + + diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/preprocessing.R b/scomps.Rcheck/00_pkg_src/scomps/R/preprocessing.R new file mode 100644 index 00000000..93b3ad93 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/R/preprocessing.R @@ -0,0 +1,36 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' Setting the clipping extent +#' @description Return clipping extent with buffer radius. It assumes the input CRS is projected and linear unit is meters. +#' @author Insang Song +#' @param pnts One of sf or vect class. Target points of computation. +#' @param buffer_r numeric(1). Buffer radius. It is assumed in metres +#' @return A terra::ext or sfc_POLYGON object of the computation extent. +#' @export +set_clip_extent <- function(pnts, buffer_r) { + detected = check_packbound(pnts) + if (detected == "terra") { + ext_input = terra::ext(pnts) + # Note that `+` operation on terra::ext output accounts for the operand as it is. + ext_input = ext_input + (1.1 * buffer_r + 30) + } + if (detected == "sf") { + ext_input <- pnts |> sf::st_bbox() + # Note that `+` operation on st_bbox output simply adds the number; we add a vector here. + ext_input <- ext_input + ((1.1 * c(-1, -1, 1, 1) * buffer_r) + 30) + ext_input <- sf::st_as_sfc(ext_input) + } + return(ext_input) +} + +#' Quick call for SpatRaster with a window +#' +#' @param rasterpath character(1). Path to the raster file. +#' @param win Named integer vector (4) or terra::ext() results. +#' @return SpatRaster object. +#' @author Insang Song +#' @export +rast_short <- function(rasterpath, win) { + terra::rast(rasterpath, win = win) +} + diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/processing.R b/scomps.Rcheck/00_pkg_src/scomps/R/processing.R new file mode 100644 index 00000000..00b3e1d3 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/R/processing.R @@ -0,0 +1,364 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' Extent clipping +#' @description Clip input vector by the expected maximum extent of computation. +#' @author Insang Song +#' @param pnts sf or SpatVector object +#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 +#' @param nqsegs integer(1). the number of points per a quarter circle; SOON TO BE DEPRECATED +#' @param target_input sf or SpatVector object to be clipped +#' @return A clipped sf or SpatVector object. +#' @export +clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input){ + if (any(sapply(list(pnts, buffer_r, target_input), is.null))) { + stop("One or more required arguments are NULL. Please check.\n") + } + detected_pnts = check_packbound(pnts) + detected_target = check_packbound(target_input) + + if (detected_pnts != detected_target) { + warning("Inputs are not the same class.\n") + target_input = switch(detected_target, + sf = terra::vect(target_input), + terra = sf::st_as_sf(target_input)) + } + + ext_input = set_clip_extent(pnts, buffer_r) + cat("Clip target features with the input feature extent...\n") + if (detected_pnts == "sf") { + cae = ext_input |> + sf::st_intersection(x = target_input) + } + if (detected_pnts == "terra") { + cae = terra::intersect(target_input, ext_input) + } + + return(cae) +} + +#' @title clip_as_extent_ras: Clip input raster. +#' @description Clip input raster by the expected maximum extent of computation. +#' @author Insang Song +#' @param pnts sf or SpatVector object +#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 +#' @param nqsegs integer(1). the number of points per a quarter circle +#' @param ras SpatRaster object to be clipped +#' @export +clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras){ + if (any(sapply(list(pnts, buffer_r, ras), is.null))) { + stop("Any of required arguments are NULL. Please check.\n") + } + ext_input = set_clip_extent(pnts, buffer_r) |> + terra::ext() + + cae <- terra::crop(ras, ext_input, snap = 'out') + return(cae) +} + +#' @title clip_as_extent_ras2: Clip input raster (version 2). +#' @description Clip input raster by the expected maximum extent of computation. +#' @author Insang Song +#' @param points_in sf or SpatVector object +#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 +#' @param nqsegs integer(1). the number of points per a quarter circle +#' @param ras SpatRaster object to be clipped +#' @export +clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras){ + if (any(sapply(list(points_in, buffer_r, ras), is.null))) { + stop("Any of required arguments are NULL. Please check.\n") + } + ext_input = set_clip_extent(points_in, buffer_r) |> + terra::ext() + + cae <- terra::crop(ras, ext_input, snap = 'out') + return(cae) +} + +#' @title Extract summarized values from raster with generic polygons +#' +#' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. +#' @param polys sf/SpatVector object. Polygons. +#' @param surf stars/SpatRaster object. A raster of whatnot a summary will be calculated +#' @param id character(1). Unique identifier of each point. +#' @param func a function taking one argument. For example, function(x) mean(x, na.rm = TRUE) or \(x) mode(x, na.rm = TRUE) +#' @param na.rm logical(1). NA values are omitted when summary is calculated. +#' @return a data.frame object with function value +#' @author Insang Song \email{geoissong@@gmail.com} +#' +#' @export +extract_with_polygons <- function( + polys, surf, id, func = mean, na.rm = TRUE + ) { + # type check + stopifnot("Check class of the input points.\n" = any(methods::is(polys, "sf"), methods::is(polys, "SpatVector"))) + stopifnot("Check class of the input raster.\n" = any(methods::is(surf, "stars"), methods::is(surf, "SpatRaster"))) + stopifnot(is.character(id)) + + cls_polys = check_packbound(polys) + cls_surf = check_packbound(surf) + + if (cls_polys != cls_surf) { + polys = switch_packbound(polys) + } + + extract_with_polygons.sf = function(polys, surf, id, func) { + extracted = stars::st_extract(x = surf, at = polys, FUN = func) + # extracted = extracted |> + # group_by(!!sym(id)) |> + # summarize(across(-!!sym(id), ~func)) |> + # ungroup() + return(extracted) + } + + extract_with_polygons.terra = function(polys, surf, id, func) { + extracted = terra::extract(surf, polys) + extracted = extracted |> + dplyr::group_by(!!rlang::sym(id)) |> + dplyr::summarize(dplyr::across(-!!rlang::sym(id), ~func)) |> + dplyr::ungroup() + return(extracted) + } + + extracted_poly = switch( + cls_surf, + sf = extract_with_polygons.sf(polys = polys, surf = surf, id = id, func = func), + terra = extract_with_polygons.terra(polys = polys, surf = surf, id = id, func = func) + ) + return(extracted_poly) +} + + +#' Extract raster values with point buffers or polygons +#' +#' @param raster SpatRaster object. +#' @param vector SpatVector object. +#' @param id character(1). Unique identifier of each point. +#' @param func function taking one numeric vector argument. +#' @param mode one of "polygon" (generic polygons to extract raster values with) or "buffer" (point with buffer radius) +#' @param ... various. Passed to extract_with_buffer. See \code{?extract_with_buffer} for details. +#' @return +#' @author Insang Song \email{geoissong@@gmail.com} +#' @export +extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) { + if (!mode %in% c("polygon", "buffer")) { + stop("Argument 'mode' should be one of 'polygon' or 'buffer'.\n") + } + stopifnot(is.character(id)) + stopifnot(id %in% names(vector)) + + extracted = + switch(mode, + polygon = extract_with_polygons(vector, raster, id, func), + buffer = extract_with_buffer(vector, raster, id = id, func = func, ...)) + return(extracted) +} + + +#' Calculate SEDC covariates +#' @param point_from SpatVector object. Locations where the sum of SEDCs are calculated. +#' @param point_to SpatVector object. Locations where each SEDC is calculated. +#' @param id character(1). Name of the unique id field in point_to. +#' @param sedc_bandwidth numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 %) +#' @param threshold numeric(1). For computational efficiency, the nearest points in threshold will be selected +#' @param target_fields character(varying). Field names in characters. +#' @description NOTE: sf implementation is pending. Only available for terra. +#' @author Insang Song +#' @export +calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, target_fields) { + # define sources, set SEDC exponential decay range + len_point_from = seq_len(nrow(point_from)) + len_point_to = seq_len(nrow(point_to)) + + point_from$from_id = len_point_from + # select egrid_v only if closer than 3e5 meters from each aqs + point_from_buf = terra::buffer(point_from_buf, threshold = threshold, quadsegs = 90) + point_to = point_to[point_from_buf,] + point_to$to_id = len_point_to + + # near features with distance argument: only returns integer indices + near_from_to = terra::nearby(point_from, point_to, distance = threshold) + # attaching actual distance + dist_near_to = terra::distance(point_from, point_to) + dist_near_to_df = as.vector(dist_near_to) + # adding integer indices + dist_near_to_tdf = expand.grid(from_id = len_point_from, to_id = len_point_to) + dist_near_to_df = cbind(dist_near_to_tdf, dist = dist_near_to_df) + + # summary + near_from_to = near_from_to |> + dplyr::as_tibble() |> + dplyr::left_join(data.frame(point_from)) |> + dplyr::left_join(data.frame(point_to)) |> + dplyr::left_join(dist_near_to_df) |> + # per the definition in https://mserre.sph.unc.edu/BMElab_web/SEDCtutorial/index.html + # exp(-3) is about 0.05 + dplyr::mutate(w_sedc = exp((-3 * dist) / sedc_bandwidth)) |> + dplyr::group_by(!!rlang::sym(id)) |> + dplyr::summarize(dplyr::across(dplyr::all_of(target_fields), list(sedc = ~sum(w_sedc * ., na.rm = TRUE)))) |> + dplyr::ungroup() + + invisible(near_from_to) + +} + + +#' Computing area weighted covariates using two polygon sf or SpatVector objects +#' @param poly_in A sf/SpatVector object at weighted means will be calculated. +#' @param poly_weight A sf/SpatVector object from which weighted means will be calculated. +#' @param id_poly_in character(1). The unique identifier of each polygon in poly_in +#' @return A data.frame with all numeric fields of area-weighted means. +#' @description When poly_in and poly_weight are different classes, poly_weight will be converted to the class of poly_in. +#' @author Insang Song \email{geoissong@@gmail.com} +#' @examples +#' # package +#' library(sf) +#' +#' # run +#' nc = sf::st_read(system.file("shape/nc.shp", package="sf")) +#' nc = sf::st_transform(nc, 5070) +#' pp = sf::st_sample(nc, size = 300) +#' pp = sf::st_as_sf(pp) +#' pp[["id"]] = seq(1, nrow(pp)) +#' sf::st_crs(pp) = "EPSG:5070" +#' ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +#' +#' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) +#' summary(ppb_nc_aw) +#' #### Example of aw_covariates ends #### +#' @export +aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { + stopifnot("Inputs have invalid classes.\n" = + methods::is(poly_in, "sf") || methods::is(poly_weight, "sf") || methods::is(poly_in, "SpatVector") || methods::is(poly_weight, "SpatVector")) + #check_crs() + + ## distinguish numeric and nonnumeric columns + index_numeric = grep("(integer|numeric)", unlist(sapply(poly_weight, class))) + + aw_covariates.terra = function(poly_in, poly_weight, id_poly_in = id_poly_in) { + + poly_intersected = terra::intersect(poly_in, poly_weight) + poly_intersected[["area_segment_"]] = terra::expanse(poly_intersected) + poly_intersected = data.frame(poly_intersected) |> + dplyr::group_by(!!rlang::sym(id_poly_in)) |> + dplyr::summarize(dplyr::across(is.numeric, + ~stats::weighted.mean(., w = area_segment_))) |> + dplyr::ungroup() + return(poly_intersected) + } + + class_poly_in = check_packbound(poly_in) + class_poly_weight = check_packbound(poly_weight) + + if (class_poly_in != class_poly_weight) { + class_poly_weight = switch_packbound(class_poly_weight) + } + + switch(class_poly_in, + sf = sf::st_interpolate_aw(poly_weight[,index_numeric], poly_in, extensive = FALSE), + terra = aw_covariates.terra(poly_in, poly_weight[,index_numeric], id_poly_in = id_poly_in)) + +} + +# ncbuf = terra::intersect(vect(ppb), vect(nc)) +# ncbuf_a = ncbuf +# ncbuf_a$segarea = expanse(ncbuf_a) +# ncbuf_k = data.frame(ncbuf_a) |> +# dplyr::group_by(id) |> +# dplyr::summarize(across(is.numeric, +# ~weighted.mean(., w = segarea))) |> +# dplyr::ungroup() + +#ncbufagg = terra::aggregate(ncbuf, by = 'id', fun = weighted.mean, w = ncbuf_a$segarea) + + +#' @title Extract summarized values from raster with points and a buffer radius (to be written) +#' +#' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. +#' @param points SpatVector object. Coordinates where buffers will be generated +#' @param surf SpatRaster object. A raster of whatnot a summary will be calculated +#' @param radius numeric(1). Buffer radius. here we assume circular buffers only +#' @param id character(1). Unique identifier of each point. +#' @param qsegs integer(1). Number of vertices at a quarter of a circle. Default is 90. +#' @param func a function taking a numeric vector argument. +#' @param kernel character(1). Name of a kernel function (yet to be implemented) +#' @param bandwidth numeric(1). Kernel bandwidth. +#' @return a data.frame object with mean value +#' @author Insang Song \email{geoissong@@gmail.com} +#' +#' @export +extract_with_buffer <- function( + points, surf, radius, id, qsegs = 90, func = mean, kernel = NULL, bandwidth = NULL + ) { + # type check + stopifnot("Check class of the input points.\n" = methods::is(points, "SpatVector")) + stopifnot("Check class of the input radius.\n" = is.numeric(radius)) + stopifnot(is.character(id)) + stopifnot(is.integer(qsegs)) + + if (!is.null(kernel)) { + extracted = extract_with_buffer.flat(points = points, + surf = surf, + radius = radius, + id = id, + func = func, + qsegs = qsegs) + return(extracted) + } + + extracted = extract_with_buffer.kernel(points = points, + surf = surf, + radius = radius, + id = id, + func = func, + qsegs = qsegs, + kernel = kernel, + bandwidth = bandwidth) + return(extracted) + +} + +# Subfunction: extract with buffers (flat weight; simple mean) +extract_with_buffer.flat <- function( + points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL + ) { + # generate buffers + bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + # crop raster + bufs_extent = terra::ext(bufs) + surf_cropped = terra::crop(surf, bufs_extent) + name_surf_val = names(surf) + # extract raster values + surf_at_bufs = terra::extract(surf_cropped, bufs) + surf_at_bufs_summary = + surf_at_bufs |> + dplyr::group_by(ID) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::ungroup() + return(surf_at_bufs_summary) +} + + +# Subfunction: extract with buffers (kernel weight; weighted mean) +extract_with_buffer.kernel <- function( + points, surf, radius, id, qsegs, func = mean, kernel, bandwidth + ) { + # generate buffers + bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + # crop raster + bufs_extent = terra::ext(bufs) + surf_cropped = terra::crop(surf, bufs_extent) + name_surf_val = names(surf) + + # TODO: kernel implementation + + + # extract raster values + surf_at_bufs = terra::extract(surf_cropped, bufs) + surf_at_bufs_summary = + surf_at_bufs |> + dplyr::group_by(ID) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::ungroup() + return(surf_at_bufs_summary) +} + diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/switch_format.R b/scomps.Rcheck/00_pkg_src/scomps/R/switch_format.R new file mode 100644 index 00000000..a0c38e8f --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/R/switch_format.R @@ -0,0 +1,25 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' @title Switch spatial data class +#' @description Convert stars into SpatRaster and vice versa; sf into SpatVector and vice versa. +#' @author Insang Song +#' @param input Spat* in terra or sf object. +#' @return Data converted to the other package class (if sf, terra; if terra, sf) +#' @export +switch_packbound <- function(input) { + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) + cls_input = check_packbound(input) + type_input = check_datatype(input) + + switched = + switch(cls_input, + sf = switch(type_input, + vector = terra::vect(input), + raster = terra::rast(input) + ), + terra = switch(type_input, + vector = sf::st_as_sf(input), + raster = stars::st_as_stars(input))) + + invisible(switched) +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/validate.R b/scomps.Rcheck/00_pkg_src/scomps/R/validate.R new file mode 100644 index 00000000..545869c2 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/R/validate.R @@ -0,0 +1,18 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand + +#' Validate and repair input vector data +#' @description It tries repairing input vector data. Vector validity violation usually appears in polygon data with self-crossing or hole orders. This function will pass the input_vector object to sf::st_make_valid() (if input_vector is sf) or terra::makeValid() (if input_vector is SpatVector). May take some time depending on the geometry complexity. +#' @author Insang Song +#' @param input_vector One of sf or vect class. Target points of computation. +#' @return A repaired sf or SpatVector object depending on the class of input_vector. +#' @export +validate_and_repair_vectors <- function(input_vector) { + detected = check_packbound(input_vector) + + validated = switch(detected, + terra = terra::makeValid(input_vector), + sf = sf::st_make_valid(input_vector)) + + return(validated) +} + diff --git a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.R b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.R new file mode 100644 index 00000000..c639e81d --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.R @@ -0,0 +1,4 @@ +## ----------------------------------------------------------------------------- +knitr::opts_chunk$set(warning = FALSE, message = FALSE) + + diff --git a/tools/vignettes-sources/00_good_practice_parallelization.Rmd b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.Rmd similarity index 95% rename from tools/vignettes-sources/00_good_practice_parallelization.Rmd rename to scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.Rmd index 6da000b1..8966a59d 100644 --- a/tools/vignettes-sources/00_good_practice_parallelization.Rmd +++ b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.Rmd @@ -3,7 +3,7 @@ title: "Good practice of scomps with HPC" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{HPC good practice with scomps} + %\VignetteIndexEntry{good_practice_hpc} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- diff --git a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.html b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.html new file mode 100644 index 00000000..da4506f4 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.html @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + +Good practice of scomps with HPC + + + + + + + + + + + + + + + + + + + + + + + + + + +

Good practice of scomps with HPC

+

2023-10-04

+ + + +
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
+
+

Assumptions

+
    +
  • Users have an accessible HPC at your work
  • +
  • Data are stored in distributed file systems (usually incorporated +into the HPC system)
  • +
+
+
+

Basic workflow

+
+

Practice for minimizing errors

+
    +
  • Consider using try() or tryCatch() not to +a tiny error will halt all the work without any results +
      +
    • Especially with the higher-level functions
    • +
  • +
  • “IPDE – Inspect, Predict, Decide, Execute” all the time
  • +
+
+
+

Raster-Vector overlay

+
    +
  • Make sp_index_grid() to get padded grid objects
  • +
  • Convert sf/SpatVector objects into terra::ext() +compatible named numeric vector +
      +
    • For example: c(xmin=0, ymin=0, xmax=10, ymax=10)
    • +
  • +
  • Make list objects with: +
      +
    • An extent vector in each element
    • +
    • Preprocessed vector objects with respect to each extent vector in +the first list
    • +
    • Preferably all lists are named
    • +
  • +
  • Write a future.apply script running through the extent +list object
  • +
  • Run a small amount of data to estimate the total computational +demand
  • +
  • Submit a job with a proper amount of computational assets
  • +
+
+
+ + + + + + + + + + + diff --git a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.R b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.R new file mode 100644 index 00000000..aa3d29fc --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.R @@ -0,0 +1,22 @@ +## ----------------------------------------------------------------------------- +knitr::opts_chunk$set(warning = FALSE, message = FALSE) + + +## ----------------------------------------------------------------------------- +library(scomps) +library(sf) +library(terra) +library(stars) +library(dplyr) + + +## ----------------------------------------------------------------------------- +# your_grid = scomps::sp_index_grid() + + +## ----------------------------------------------------------------------------- +# library(mapsf) +# mf_map(your_grid$geometry) + + + diff --git a/tools/vignettes-sources/01_generate_computational_grid.Rmd b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.Rmd similarity index 92% rename from tools/vignettes-sources/01_generate_computational_grid.Rmd rename to scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.Rmd index 4c1a4ee6..4bc1aaf2 100644 --- a/tools/vignettes-sources/01_generate_computational_grid.Rmd +++ b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.Rmd @@ -3,7 +3,7 @@ title: "Generate computational grids" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Generate computational grids} + %\VignetteIndexEntry{computational_grids} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- diff --git a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.html b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.html new file mode 100644 index 00000000..c2d963b8 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.html @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + +Generate computational grids + + + + + + + + + + + + + + + + + + + + + + + + + + +

Generate computational grids

+

2023-10-04

+ + + +
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
+
+

Prepare input data

+
library(scomps)
+library(sf)
+library(terra)
+library(stars)
+library(dplyr)
+
+
+

Computational grids

+
# your_grid = scomps::sp_index_grid()
+
+
+

Visualize computational grids

+
# library(mapsf)
+# mf_map(your_grid$geometry)
+
+
+

Notes

+
    +
  • Computational grids are the exhaustive split of the entire study +region. You should take a square buffer of each grid to clip the target +raster or vector.
  • +
+
+ + + + + + + + + + + diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/aw_covariates.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/aw_covariates.Rd new file mode 100644 index 00000000..ca836de6 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/aw_covariates.Rd @@ -0,0 +1,41 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/processing.R +\name{aw_covariates} +\alias{aw_covariates} +\title{Computing area weighted covariates using two polygon sf or SpatVector objects} +\usage{ +aw_covariates(poly_in, poly_weight, id_poly_in = "ID") +} +\arguments{ +\item{poly_in}{A sf/SpatVector object at weighted means will be calculated.} + +\item{poly_weight}{A sf/SpatVector object from which weighted means will be calculated.} + +\item{id_poly_in}{character(1). The unique identifier of each polygon in poly_in} +} +\value{ +A data.frame with all numeric fields of area-weighted means. +} +\description{ +When poly_in and poly_weight are different classes, poly_weight will be converted to the class of poly_in. +} +\examples{ +# package +library(sf) + +# run +nc = sf::st_read(system.file("shape/nc.shp", package="sf")) +nc = sf::st_transform(nc, 5070) +pp = sf::st_sample(nc, size = 300) +pp = sf::st_as_sf(pp) +pp[["id"]] = seq(1, nrow(pp)) +sf::st_crs(pp) = "EPSG:5070" +ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) + +system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) +summary(ppb_nc_aw) +#### Example of aw_covariates ends #### +} +\author{ +Insang Song \email{geoissong@gmail.com} +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/calculate_sedc.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/calculate_sedc.Rd new file mode 100644 index 00000000..21178a77 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/calculate_sedc.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/processing.R +\name{calculate_sedc} +\alias{calculate_sedc} +\title{Calculate SEDC covariates} +\usage{ +calculate_sedc( + point_from, + point_to, + id, + sedc_bandwidth, + threshold, + target_fields +) +} +\arguments{ +\item{point_from}{SpatVector object. Locations where the sum of SEDCs are calculated.} + +\item{point_to}{SpatVector object. Locations where each SEDC is calculated.} + +\item{id}{character(1). Name of the unique id field in point_to.} + +\item{sedc_bandwidth}{numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 \%)} + +\item{threshold}{numeric(1). For computational efficiency, the nearest points in threshold will be selected} + +\item{target_fields}{character(varying). Field names in characters.} +} +\description{ +NOTE: sf implementation is pending. Only available for terra. +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/check_bbox.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/check_bbox.Rd new file mode 100644 index 00000000..444c934a --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/check_bbox.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check.R +\name{check_bbox} +\alias{check_bbox} +\title{Check if the data extent is inside the reference bounding box} +\usage{ +check_bbox(data_query, reference, reference_crs = NULL) +} +\arguments{ +\item{data_query}{sf*/stars/SpatVector/SpatRaster object.} + +\item{reference}{sf*/stars/SpatVector/SpatRaster object or a named numeric vector with four names (xmin, ymin, xmax, and ymax).} + +\item{reference_crs}{Well-known-text-formatted or EPSG code of the reference's coordinate system. Only required when a named numeric vector is passed to reference.} +} +\value{ +TRUE (the queried data extent is completely within the reference bounding box) or FALSE +} +\description{ +One of the most common errors in spatial computation is rooted in the entirely or partly incomparable spatial extents of input datasets. This function returns whether your data is inside the target computational extent. It is assumed that you know and have the exact computational region. This function will return TRUE if the reference region completely contains your data's extent and FALSE otherwise. +} +\author{ +Insang Song \email{geoissong@gmail.com} +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/check_crs.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/check_crs.Rd new file mode 100644 index 00000000..6f9fa5b5 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/check_crs.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check.R +\name{check_crs} +\alias{check_crs} +\title{Check Coordinate Reference System} +\usage{ +check_crs(x) +} +\arguments{ +\item{x}{sf/stars/SpatVector/SpatRaster object.} +} +\value{ +A st_crs or crs object. +} +\description{ +Check Coordinate Reference System +} +\examples{ +# data +library(sf) +ncpath = system.file("shape/nc.shp", package = "sf") +nc = read_sf(ncpath) +check_crs(nc) + +} +\author{ +Insang Song \email{geoissong@gmail.com} +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/check_crs2.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/check_crs2.Rd new file mode 100644 index 00000000..c15652d6 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/check_crs2.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check.R +\name{check_crs2} +\alias{check_crs2} +\title{check_crs2: Coordinate system checker} +\usage{ +check_crs2(input, crs_standard = "EPSG:4326") +} +\arguments{ +\item{input}{Input object one of sf or terra::Spat* object} + +\item{crs_standard}{character(1). A standard definition of coordinate reference system. Default is "EPSG:4326" Consult \href{https://epsg.io}{epsg.io} for details of other CRS.} +} +\value{ +A (reprojected) sf or SpatVector object. +} +\description{ +The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179. +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/check_packbound.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/check_packbound.Rd new file mode 100644 index 00000000..6bda7485 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/check_packbound.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check.R +\name{check_packbound} +\alias{check_packbound} +\title{Return the package the input object is based on} +\usage{ +check_packbound(input) +} +\arguments{ +\item{input}{Spat* in terra or sf object.} +} +\value{ +A character object; one of 'terra' and 'sf' +} +\description{ +Detect whether the input object is sf or Spat* object. +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/check_within_reference.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/check_within_reference.Rd new file mode 100644 index 00000000..c193a975 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/check_within_reference.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check.R +\name{check_within_reference} +\alias{check_within_reference} +\title{Check if the boundary of the vector/raster object is inside the reference} +\usage{ +check_within_reference(input_object, reference) +} +\arguments{ +\item{input_object}{sf/stars/SpatVector/SpatRaster object.} + +\item{reference}{sf/stars/SpatVector/SpatRaster object.} +} +\value{ +logical +} +\description{ +Check if the boundary of the vector/raster object is inside the reference +} +\author{ +Insang Song \email{geoissong@gmail.com} +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent.Rd new file mode 100644 index 00000000..06ec0bbf --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/processing.R +\name{clip_as_extent} +\alias{clip_as_extent} +\title{Extent clipping} +\usage{ +clip_as_extent(pnts, buffer_r, nqsegs = NULL, target_input) +} +\arguments{ +\item{pnts}{sf or SpatVector object} + +\item{buffer_r}{numeric(1). buffer radius. this value will be automatically multiplied by 1.25} + +\item{nqsegs}{integer(1). the number of points per a quarter circle; SOON TO BE DEPRECATED} + +\item{target_input}{sf or SpatVector object to be clipped} +} +\value{ +A clipped sf or SpatVector object. +} +\description{ +Clip input vector by the expected maximum extent of computation. +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras.Rd new file mode 100644 index 00000000..e6762901 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/processing.R +\name{clip_as_extent_ras} +\alias{clip_as_extent_ras} +\title{clip_as_extent_ras: Clip input raster.} +\usage{ +clip_as_extent_ras(pnts, buffer_r, nqsegs = 180, ras) +} +\arguments{ +\item{pnts}{sf or SpatVector object} + +\item{buffer_r}{numeric(1). buffer radius. this value will be automatically multiplied by 1.25} + +\item{nqsegs}{integer(1). the number of points per a quarter circle} + +\item{ras}{SpatRaster object to be clipped} +} +\description{ +Clip input raster by the expected maximum extent of computation. +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras2.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras2.Rd new file mode 100644 index 00000000..6d8c0e00 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras2.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/processing.R +\name{clip_as_extent_ras2} +\alias{clip_as_extent_ras2} +\title{clip_as_extent_ras2: Clip input raster (version 2).} +\usage{ +clip_as_extent_ras2(points_in, buffer_r, nqsegs = 180, ras) +} +\arguments{ +\item{points_in}{sf or SpatVector object} + +\item{buffer_r}{numeric(1). buffer radius. this value will be automatically multiplied by 1.25} + +\item{nqsegs}{integer(1). the number of points per a quarter circle} + +\item{ras}{SpatRaster object to be clipped} +} +\description{ +Clip input raster by the expected maximum extent of computation. +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/distribute_process.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/distribute_process.Rd new file mode 100644 index 00000000..ebb58e82 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/distribute_process.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/interpret_computational_domain.R +\name{distribute_process} +\alias{distribute_process} +\title{Process a given function in the entire or partial computational grids (under construction)} +\usage{ +distribute_process(grids, grid_id = NULL, fun, ...) +} +\arguments{ +\item{grids}{sf/SpatVector object. Computational grids.} + +\item{grid_id}{character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. \code{"id_from:id_to"} format or \code{c(unique(grid_id)[id_from], unique(grid_id)[id_to])}} + +\item{fun}{function supported in scomps.} + +\item{...}{Arguments passed to fun.} +} +\value{ +a data.frame object with mean value +} +\description{ +Should +} +\author{ +Insang Song \email{geoissong@gmail.com} +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/estimate_demands.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/estimate_demands.Rd new file mode 100644 index 00000000..787ad77f --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/estimate_demands.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/estimate_demands.R +\name{estimate_demands} +\alias{estimate_demands} +\title{Estimate computational demands from inputs (to be written)} +\usage{ +estimate_demands(inputs, nx, ny, padding) +} +\arguments{ +\item{inputs}{a list of sf/Spat* objects or file paths} + +\item{nx}{integer(1).} + +\item{ny}{integer(1).} + +\item{padding}{numeric(1). Extrusion factor} +} +\description{ +Estimate computational demands from inputs (to be written) +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/extent_to_polygon.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/extent_to_polygon.Rd new file mode 100644 index 00000000..2874461e --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/extent_to_polygon.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check.R +\name{extent_to_polygon} +\alias{extent_to_polygon} +\title{Generate a rectangular polygon from extent} +\usage{ +extent_to_polygon(extent, output_class = "terra", crs = "EPSG:4326") +} +\arguments{ +\item{extent}{input extent. A numeric vector with xmin/xmax/ymin/ymax, sf::st_bbox() or terra::ext() outputs.} + +\item{output_class}{character(1). Class of the output polygon. One of "sf" or "terra"} + +\item{crs}{character(1). Coordinate reference system definition.} +} +\description{ +Generate a rectangular polygon from extent +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/extract_with.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/extract_with.Rd new file mode 100644 index 00000000..8794f571 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/extract_with.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/processing.R +\name{extract_with} +\alias{extract_with} +\title{Extract raster values with point buffers or polygons} +\usage{ +extract_with(raster, vector, id, func = mean, mode = "polygon", ...) +} +\arguments{ +\item{raster}{SpatRaster object.} + +\item{vector}{SpatVector object.} + +\item{id}{character(1). Unique identifier of each point.} + +\item{func}{function taking one numeric vector argument.} + +\item{mode}{one of "polygon" (generic polygons to extract raster values with) or "buffer" (point with buffer radius)} + +\item{...}{various. Passed to extract_with_buffer. See \code{?extract_with_buffer} for details.} +} +\description{ +Extract raster values with point buffers or polygons +} +\author{ +Insang Song \email{geoissong@gmail.com} +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_buffer.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_buffer.Rd new file mode 100644 index 00000000..f0c3943d --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_buffer.Rd @@ -0,0 +1,43 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/processing.R +\name{extract_with_buffer} +\alias{extract_with_buffer} +\title{Extract summarized values from raster with points and a buffer radius (to be written)} +\usage{ +extract_with_buffer( + points, + surf, + radius, + id, + qsegs = 90, + func = mean, + kernel = NULL, + bandwidth = NULL +) +} +\arguments{ +\item{points}{SpatVector object. Coordinates where buffers will be generated} + +\item{surf}{SpatRaster object. A raster of whatnot a summary will be calculated} + +\item{radius}{numeric(1). Buffer radius. here we assume circular buffers only} + +\item{id}{character(1). Unique identifier of each point.} + +\item{qsegs}{integer(1). Number of vertices at a quarter of a circle. Default is 90.} + +\item{func}{a function taking a numeric vector argument.} + +\item{kernel}{character(1). Name of a kernel function (yet to be implemented)} + +\item{bandwidth}{numeric(1). Kernel bandwidth.} +} +\value{ +a data.frame object with mean value +} +\description{ +For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. +} +\author{ +Insang Song \email{geoissong@gmail.com} +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_polygons.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_polygons.Rd new file mode 100644 index 00000000..adaa9c6a --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_polygons.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/processing.R +\name{extract_with_polygons} +\alias{extract_with_polygons} +\title{Extract summarized values from raster with generic polygons} +\usage{ +extract_with_polygons(polys, surf, id, func = mean, na.rm = TRUE) +} +\arguments{ +\item{polys}{sf/SpatVector object. Polygons.} + +\item{surf}{stars/SpatRaster object. A raster of whatnot a summary will be calculated} + +\item{id}{character(1). Unique identifier of each point.} + +\item{func}{a function taking one argument. For example, function(x) mean(x, na.rm = TRUE) or \(x) mode(x, na.rm = TRUE)} + +\item{na.rm}{logical(1). NA values are omitted when summary is calculated.} +} +\value{ +a data.frame object with function value +} +\description{ +For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. +} +\author{ +Insang Song \email{geoissong@gmail.com} +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/get_computational_regions.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/get_computational_regions.Rd new file mode 100644 index 00000000..6a864a55 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/get_computational_regions.Rd @@ -0,0 +1,53 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/interpret_computational_domain.R +\name{get_computational_regions} +\alias{get_computational_regions} +\title{Get a set of computational regions} +\usage{ +get_computational_regions( + input, + mode = "grid", + nx = 10, + ny = 10, + grid_min_features = 30, + padding = NULL, + unit = NULL, + ... +) +} +\arguments{ +\item{input}{sf or Spat* object.} + +\item{mode}{character(1). Mode of region construction. One of "grid" (simple grid regardless of the number of features in each grid), "density" (clustering-based varying grids), "grid_advanced" (merging adjacent grids with smaller number of features than grid_min_features).} + +\item{nx}{integer(1). The number of grids along x-axis.} + +\item{ny}{integer(1). The number of grids along y-axis.} + +\item{grid_min_features}{integer(1). A threshold to merging adjacent grids} + +\item{padding}{numeric(1). A extrusion factor to make buffer to clip actual datasets. Depending on the length unit of the CRS of input.} + +\item{unit}{character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See \href{https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html}{units package vignette (web)} for the list of acceptable unit forms.} + +\item{...}{arguments passed to the internal function} +} +\value{ +A set of polygons in the input class +} +\description{ +TODO. Using input points, the bounding box is split to the predefined numbers of columns and rows. Each grid will be buffered by the radius. +} +\examples{ +# data +library(sf) +ncpath = system.file("shape/nc.shp", package = "sf") +nc = read_sf(ncpath) +nc = st_transform(nc, "EPSG:5070") +# run +# nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) + +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/grid_merge.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/grid_merge.Rd new file mode 100644 index 00000000..0361cece --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/grid_merge.Rd @@ -0,0 +1,38 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/interpret_computational_domain.R +\name{grid_merge} +\alias{grid_merge} +\title{grid_merge: Merge grid polygons with given rules} +\usage{ +grid_merge(points_in, grid_in, grid_min_features) +} +\arguments{ +\item{points_in}{sf or SpatVector object. Target points of computation.} + +\item{grid_in}{sf or SpatVector object. The grid generated by sp_index_grid} + +\item{grid_min_features}{integer(1). Threshold to merge adjacent grids.} +} +\value{ +A sf or SpatVector object of computation grids. +} +\description{ +Merge boundary-sharing (in "Rook" contiguity) grids with fewer target features than the threshold. This function strongly assumes that the input is returned from the sp_index_grid, which has 'CGRIDID' as the unique id field. +} +\examples{ +# library(sf) +# library(igraph) +# ligrary(dplyr) +# dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +# sf::st_crs(dg) = 5070 +# dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) +# dgs$CGRIDID = seq(1, nrow(dgs)) +# +# dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") +# sf::st_crs(dg_sample) = sf::st_crs(dg) +# dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) +#### NOT RUN #### +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/initate_log.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/initate_log.Rd new file mode 100644 index 00000000..6e64c090 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/initate_log.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/logging.R +\name{initate_log} +\alias{initate_log} +\title{Turn on logging} +\usage{ +initate_log(expr, dolog = FALSE, logpath) +} +\arguments{ +\item{expr}{expression. Any function call to be logged.} + +\item{dolog}{logical(1). Will the messages be logged.} + +\item{logpath}{character(1). Log file path with the full log file name.} +} +\value{ +Nothing. It will export a log file in the specified path as logpath. +} +\description{ +Turn on logging +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/rast_short.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/rast_short.Rd new file mode 100644 index 00000000..de4acd9f --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/rast_short.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/preprocessing.R +\name{rast_short} +\alias{rast_short} +\title{Quick call for SpatRaster with a window} +\usage{ +rast_short(rasterpath, win) +} +\arguments{ +\item{rasterpath}{character(1). Path to the raster file.} + +\item{win}{Named integer vector (4) or terra::ext() results.} +} +\value{ +SpatRaster object. +} +\description{ +Quick call for SpatRaster with a window +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/set_clip_extent.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/set_clip_extent.Rd new file mode 100644 index 00000000..4fb91191 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/set_clip_extent.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/preprocessing.R +\name{set_clip_extent} +\alias{set_clip_extent} +\title{Setting the clipping extent} +\usage{ +set_clip_extent(pnts, buffer_r) +} +\arguments{ +\item{pnts}{One of sf or vect class. Target points of computation.} + +\item{buffer_r}{numeric(1). Buffer radius. It is assumed in metres} +} +\value{ +A terra::ext or sfc_POLYGON object of the computation extent. +} +\description{ +Return clipping extent with buffer radius. It assumes the input CRS is projected and linear unit is meters. +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/sp_index_grid.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/sp_index_grid.Rd new file mode 100644 index 00000000..bf0d4ac5 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/sp_index_grid.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/interpret_computational_domain.R +\name{sp_index_grid} +\alias{sp_index_grid} +\title{sp_index_grid: Generate grid polygons} +\usage{ +sp_index_grid(points_in, ncutsx, ncutsy) +} +\arguments{ +\item{points_in}{sf or SpatVector object. Target points of computation.} + +\item{ncutsx}{integer(1). The number of splits along x-axis.} + +\item{ncutsy}{integer(1). The number of splits along y-axis.} +} +\value{ +A sf or SpatVector object of computation grids with unique grid id (CGRIDID). +} +\description{ +Returns a sf object that includes x- and y- index by using two inputs ncutsx and ncutsy, which are x- and y-directional splits, respectively. +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/sp_indexing.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/sp_indexing.Rd new file mode 100644 index 00000000..f4da1434 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/sp_indexing.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/indexing.R +\name{sp_indexing} +\alias{sp_indexing} +\title{Create integer indices for grid} +\usage{ +sp_indexing(points_in, ncutsx, ncutsy) +} +\arguments{ +\item{points_in}{sf object.} + +\item{ncutsx}{integer(1). The number of splits along x-axis.} + +\item{ncutsy}{integer(1). The number of splits along y-axis.} +} +\description{ +Returns a tibble object that includes x- and y- index by using two inputs ncutsx and ncutsy, which are x- and y-directional splits, respectively. +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/switch_packbound.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/switch_packbound.Rd new file mode 100644 index 00000000..18eafb22 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/switch_packbound.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/switch_format.R +\name{switch_packbound} +\alias{switch_packbound} +\title{Switch spatial data class} +\usage{ +switch_packbound(input) +} +\arguments{ +\item{input}{Spat* in terra or sf object.} +} +\value{ +Data converted to the other package class (if sf, terra; if terra, sf) +} +\description{ +Convert stars into SpatRaster and vice versa; sf into SpatVector and vice versa. +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/validate_and_repair_vectors.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/validate_and_repair_vectors.Rd new file mode 100644 index 00000000..e8447ca9 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/man/validate_and_repair_vectors.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/validate.R +\name{validate_and_repair_vectors} +\alias{validate_and_repair_vectors} +\title{Validate and repair input vector data} +\usage{ +validate_and_repair_vectors(input_vector) +} +\arguments{ +\item{input_vector}{One of sf or vect class. Target points of computation.} +} +\value{ +A repaired sf or SpatVector object depending on the class of input_vector. +} +\description{ +It tries repairing input vector data. Vector validity violation usually appears in polygon data with self-crossing or hole orders. This function will pass the input_vector object to sf::st_make_valid() (if input_vector is sf) or terra::makeValid() (if input_vector is SpatVector). May take some time depending on the geometry complexity. +} +\author{ +Insang Song +} diff --git a/scomps.Rcheck/00_pkg_src/scomps/tests/testthat.R b/scomps.Rcheck/00_pkg_src/scomps/tests/testthat.R new file mode 100644 index 00000000..b465b524 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/tests/testthat.R @@ -0,0 +1,12 @@ +# This file is part of the standard setup for testthat. +# It is recommended that you do not modify it. +# +# Where should you do additional test configuration? +# Learn more about the roles of various files in: +# * https://r-pkgs.org/testing-design.html#sec-tests-files-overview +# * https://testthat.r-lib.org/articles/special-files.html + +library(testthat) +library(scomps) + +test_check("scomps") diff --git a/scomps.Rcheck/00_pkg_src/scomps/tests/testthat/tests.R b/scomps.Rcheck/00_pkg_src/scomps/tests/testthat/tests.R new file mode 100644 index 00000000..6efa4142 --- /dev/null +++ b/scomps.Rcheck/00_pkg_src/scomps/tests/testthat/tests.R @@ -0,0 +1,65 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand +testthat::test_that("What package does the input object belong?", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + + packbound_stars = check_packbound(bcsd_stars) + sprast_bcsd = terra::rast(bcsd_path) + packbound_terra = check_packbound(sprast_bcsd) + + testthat::expect_equal(packbound_stars, "sf") + testthat::expect_equal(packbound_terra, "terra") +}) + + +testthat::test_that("What package does the input object belong?", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + + nc = system.file(package = "sf", "shape/nc.shp") + nc = sf::read_sf(nc) + + datatype_stars = check_datatype(bcsd_stars) + datatype_sf = check_datatype(nc) + + testthat::expect_equal(datatype_stars, "raster") + testthat::expect_equal(datatype_sf, "vector") +}) + + +testthat::test_that("Format is well converted", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + + # starts from sf/stars + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + nc = system.file(package = "sf", "shape/nc.shp") + nc = sf::read_sf(nc) + + stars_bcsd_tr = switch_packbound(bcsd_stars) + sf_nc_tr = switch_packbound(nc) + + testthat::expect_equal(check_packbound(stars_bcsd_tr), "terra") + testthat::expect_equal(check_packbound(sf_nc_tr), "terra") + + stars_bcsd_trb = switch_packbound(stars_bcsd_tr) + sf_nc_trb = switch_packbound(sf_nc_tr) + + testthat::expect_equal(check_packbound(stars_bcsd_trb), "sf") + testthat::expect_equal(check_packbound(sf_nc_trb), "sf") + +}) + + + diff --git a/scomps/vignettes/00_good_practice_parallelization.Rmd b/scomps.Rcheck/00_pkg_src/scomps/vignettes/v00_good_practice_parallelization.Rmd similarity index 95% rename from scomps/vignettes/00_good_practice_parallelization.Rmd rename to scomps.Rcheck/00_pkg_src/scomps/vignettes/v00_good_practice_parallelization.Rmd index 6da000b1..8966a59d 100644 --- a/scomps/vignettes/00_good_practice_parallelization.Rmd +++ b/scomps.Rcheck/00_pkg_src/scomps/vignettes/v00_good_practice_parallelization.Rmd @@ -3,7 +3,7 @@ title: "Good practice of scomps with HPC" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{HPC good practice with scomps} + %\VignetteIndexEntry{good_practice_hpc} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- diff --git a/scomps/vignettes/01_generate_computational_grid.Rmd b/scomps.Rcheck/00_pkg_src/scomps/vignettes/v01_generate_computational_grid.Rmd similarity index 92% rename from scomps/vignettes/01_generate_computational_grid.Rmd rename to scomps.Rcheck/00_pkg_src/scomps/vignettes/v01_generate_computational_grid.Rmd index 4c1a4ee6..4bc1aaf2 100644 --- a/scomps/vignettes/01_generate_computational_grid.Rmd +++ b/scomps.Rcheck/00_pkg_src/scomps/vignettes/v01_generate_computational_grid.Rmd @@ -3,7 +3,7 @@ title: "Generate computational grids" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Generate computational grids} + %\VignetteIndexEntry{computational_grids} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- diff --git a/scomps.Rcheck/00check.log b/scomps.Rcheck/00check.log new file mode 100644 index 00000000..2fc32c95 --- /dev/null +++ b/scomps.Rcheck/00check.log @@ -0,0 +1,79 @@ +* using log directory ‘/Users/songi2/Documents/GitHub/Scalable_GIS/scomps.Rcheck’ +* using R version 4.3.1 (2023-06-16) +* using platform: aarch64-apple-darwin20 (64-bit) +* R was compiled by + Apple clang version 14.0.0 (clang-1400.0.29.202) + GNU Fortran (GCC) 12.2.0 +* running under: macOS Ventura 13.6 +* using session charset: UTF-8 +* checking for file ‘scomps/DESCRIPTION’ ... OK +* this is package ‘scomps’ version ‘0.0.3.10042023’ +* package encoding: UTF-8 +* checking package namespace information ... OK +* checking package dependencies ... OK +* checking if this is a source package ... OK +* checking if there is a namespace ... OK +* checking for executable files ... OK +* checking for hidden files and directories ... OK +* checking for portable file names ... OK +* checking for sufficient/correct file permissions ... OK +* checking whether package ‘scomps’ can be installed ... OK +* checking installed package size ... OK +* checking package directory ... OK +* checking DESCRIPTION meta-information ... NOTE +Malformed Description field: should contain one or more complete sentences. +* checking top-level files ... OK +* checking for left-over files ... OK +* checking index information ... OK +* checking package subdirectories ... OK +* checking R files for non-ASCII characters ... OK +* checking R files for syntax errors ... OK +* checking whether the package can be loaded ... OK +* checking whether the package can be loaded with stated dependencies ... OK +* checking whether the package can be unloaded cleanly ... OK +* checking whether the namespace can be loaded with stated dependencies ... OK +* checking whether the namespace can be unloaded cleanly ... OK +* checking loading without being on the library search path ... OK +* checking dependencies in R code ... NOTE +Namespaces in Imports field not imported from: + ‘covr’ ‘future’ ‘testthat’ ‘units’ + All declared Imports should be used. +* checking S3 generic/method consistency ... OK +* checking replacement functions ... OK +* checking foreign function calls ... OK +* checking R code for possible problems ... NOTE +calculate_sedc: no visible binding for global variable ‘dist’ +check_within_reference: no visible binding for global variable ‘x’ +extract_with_buffer.flat: no visible binding for global variable ‘ID’ +extract_with_buffer.kernel: no visible binding for global variable ‘ID’ +get_computational_regions: no visible binding for global variable ‘y’ +sp_indexing: no visible binding for global variable ‘x’ +sp_indexing: no visible binding for global variable ‘y’ +Undefined global functions or variables: + ID dist x y +Consider adding + importFrom("stats", "dist") +to your NAMESPACE file. +* checking Rd files ... OK +* checking Rd metadata ... OK +* checking Rd cross-references ... OK +* checking for missing documentation entries ... OK +* checking for code/documentation mismatches ... OK +* checking Rd \usage sections ... OK +* checking Rd contents ... OK +* checking for unstated dependencies in examples ... OK +* checking installed files from ‘inst/doc’ ... OK +* checking files in ‘vignettes’ ... OK +* checking examples ... OK +* checking for unstated dependencies in ‘tests’ ... OK +* checking tests ... OK + Running ‘testthat.R’ +* checking for unstated dependencies in vignettes ... OK +* checking package vignettes in ‘inst/doc’ ... OK +* checking running R code from vignettes ... NONE + ‘v00_good_practice_parallelization.Rmd’ using ‘UTF-8’... OK + ‘v01_generate_computational_grid.Rmd’ using ‘UTF-8’... OK +* checking re-building of vignette outputs ... OK +* checking PDF version of manual ... OK +* DONE +Status: 3 NOTEs diff --git a/scomps.Rcheck/00install.out b/scomps.Rcheck/00install.out new file mode 100644 index 00000000..1c871a2e --- /dev/null +++ b/scomps.Rcheck/00install.out @@ -0,0 +1,13 @@ +* installing *source* package ‘scomps’ ... +** using staged installation +** R +** inst +** byte-compile and prepare package for lazy loading +** help +*** installing help indices +** building package indices +** installing vignettes +** testing if installed package can be loaded from temporary location +** testing if installed package can be loaded from final location +** testing if installed package keeps a record of temporary installation path +* DONE (scomps) diff --git a/scomps.Rcheck/Rdlatex.log b/scomps.Rcheck/Rdlatex.log new file mode 100644 index 00000000..bb0bdaa0 --- /dev/null +++ b/scomps.Rcheck/Rdlatex.log @@ -0,0 +1,564 @@ +Hmm ... looks like a package +Converting parsed Rd's to LaTeX .. +Creating pdf output from LaTeX ... + +This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Homebrew) (preloaded format=pdflatex) + restricted \write18 enabled. +entering extended mode +LaTeX2e <2022-11-01> patch level 1 +L3 programming layer <2023-02-22> (./Rd2.tex + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/book.c +ls +Document Class: book 2022/07/02 v1.4n Standard LaTeX document class + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/bk10.c +lo)) (/Library/Frameworks/R.framework/Resources/share/texmf/tex/latex/Rd.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/ifthen +.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/longt +able.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/bm.st +y) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/alltt. +sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/verba +tim.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/url/url.sty +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/textco +mp.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +math.sty +For additional information on amsmath, use the `?' option. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +text.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +gen.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +bsy.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +opn.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am +sfonts.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am +ssymb.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ma +thrsfs.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/iftex/ift +ex.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/fonten +c.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/time +s.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/zi4.sty +`inconsolata-zi4' v1.12, 2019/05/17 Text macros for Inconsolata (msharpe) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/xkeyval/xke +yval.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x +keyval.tex +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x +kvutils.tex +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/k +eyval.tex))))) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/co +lor.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-cf +g/color.cfg) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-de +f/pdftex.def) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/ma +thcolor.ltx)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hy +perref.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/ltxcmds/l +txcmds.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdftexcmd +s/pdftexcmds.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/infwarerr +/infwarerr.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvsetkeys/k +vsetkeys.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/kvdefinek +eys/kvdefinekeys.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdfescape +/pdfescape.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hycolor/hyc +olor.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/letltxmacro +/letltxmacro.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/auxhook/aux +hook.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/na +meref.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/refcount/re +fcount.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/gettitles +tring/gettitlestring.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvoptions/k +voptions.sty))) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pd +1enc.def) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/intcalc/i +ntcalc.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/etexcmds/ +etexcmds.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pu +enc.def) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bitset/bi +tset.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bigintcal +c/bigintcalc.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atbegs +hi-ltx.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hp +dftex.def +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atvery +end-ltx.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/rerunfilech +eck/rerunfilecheck.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/uniquecou +nter/uniquecounter.sty)))) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/makeid +x.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/inpute +nc.sty) +Writing index file Rd2.idx + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1pt +m.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/l3backend/l +3backend-pdftex.def) +No file Rd2.aux. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/context/base/mkii +/supp-pdf.mkii +[Loading MPS to PDF converter (version 2006.09.02).] +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/t1zi4.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um +sa.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um +sb.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ur +sfs.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1ph +v.fd) +No file Rd2.toc. +[1{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/map/pdftex/up +dmap/pdftex.map}{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts +/enc/dvips/base/8r.enc}{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dis +t/fonts/enc/dvips/inconsolata/i4-t1-0.enc}] +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/ts1zi4.fd) [2{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/e +nc/dvips/inconsolata/i4-ts1.enc}] +Overfull \hbox (6.7171pt too wide) in paragraph at lines 143--144 +[]\T1/ptm/m/n/10 sf*/stars/SpatVector/SpatRaster ob-ject or a named nu-meric ve +c-tor with four names +[3] [4] [5] [6] +Overfull \hbox (50.24054pt too wide) in paragraph at lines 376--377 +[]\T1/zi4/m/n/10 "id_from:id_to" []\T1/ptm/m/n/10 for-mat or []\T1/zi4/m/n/10 c +(unique(grid_id)[id_from], unique(grid_id)[id_to]) +[7] [8] [9] [10] [11] [12] [13] [14] [15] +No file Rd2.ind. +[16] +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.aux) + +Package rerunfilecheck Warning: File `Rd2.out' has changed. +(rerunfilecheck) Rerun to get outlines right +(rerunfilecheck) or use package `bookmark'. + + ) +(see the transcript file for additional information) +Output written on Rd2.pdf (16 pages, 110666 bytes). +Transcript written on Rd2.log. +This is makeindex, version 2.17 [TeX Live 2023] (kpathsea + Thai support). +Scanning input file Rd2.idx....done (25 entries accepted, 0 rejected). +Sorting entries....done (101 comparisons). +Generating output file Rd2.ind....done (53 lines written, 0 warnings). +Output written in Rd2.ind. +Transcript written in Rd2.ilg. +This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Homebrew) (preloaded format=pdflatex) + restricted \write18 enabled. +entering extended mode +LaTeX2e <2022-11-01> patch level 1 +L3 programming layer <2023-02-22> (./Rd2.tex + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/book.c +ls +Document Class: book 2022/07/02 v1.4n Standard LaTeX document class + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/bk10.c +lo)) (/Library/Frameworks/R.framework/Resources/share/texmf/tex/latex/Rd.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/ifthen +.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/longt +able.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/bm.st +y) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/alltt. +sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/verba +tim.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/url/url.sty +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/textco +mp.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +math.sty +For additional information on amsmath, use the `?' option. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +text.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +gen.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +bsy.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +opn.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am +sfonts.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am +ssymb.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ma +thrsfs.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/iftex/ift +ex.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/fonten +c.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/time +s.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/zi4.sty +`inconsolata-zi4' v1.12, 2019/05/17 Text macros for Inconsolata (msharpe) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/xkeyval/xke +yval.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x +keyval.tex +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x +kvutils.tex +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/k +eyval.tex))))) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/co +lor.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-cf +g/color.cfg) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-de +f/pdftex.def) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/ma +thcolor.ltx)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hy +perref.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/ltxcmds/l +txcmds.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdftexcmd +s/pdftexcmds.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/infwarerr +/infwarerr.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvsetkeys/k +vsetkeys.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/kvdefinek +eys/kvdefinekeys.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdfescape +/pdfescape.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hycolor/hyc +olor.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/letltxmacro +/letltxmacro.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/auxhook/aux +hook.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/na +meref.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/refcount/re +fcount.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/gettitles +tring/gettitlestring.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvoptions/k +voptions.sty))) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pd +1enc.def) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/intcalc/i +ntcalc.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/etexcmds/ +etexcmds.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pu +enc.def) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bitset/bi +tset.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bigintcal +c/bigintcalc.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atbegs +hi-ltx.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hp +dftex.def +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atvery +end-ltx.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/rerunfilech +eck/rerunfilecheck.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/uniquecou +nter/uniquecounter.sty)))) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/makeid +x.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/inpute +nc.sty) +Writing index file Rd2.idx + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1pt +m.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/l3backend/l +3backend-pdftex.def) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.aux) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/context/base/mkii +/supp-pdf.mkii +[Loading MPS to PDF converter (version 2006.09.02).] +) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.out) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.out) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/t1zi4.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um +sa.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um +sb.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ur +sfs.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1ph +v.fd) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.toc [1{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fo +nts/map/pdftex/updmap/pdftex.map}{/opt/homebrew/Cellar/texlive/20230313_2/share +/texmf-dist/fonts/enc/dvips/base/8r.enc}{/opt/homebrew/Cellar/texlive/20230313_ +2/share/texmf-dist/fonts/enc/dvips/inconsolata/i4-t1-0.enc}]) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/ts1zi4.fd) [2{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/e +nc/dvips/inconsolata/i4-ts1.enc}] +Overfull \hbox (6.7171pt too wide) in paragraph at lines 143--144 +[]\T1/ptm/m/n/10 sf*/stars/SpatVector/SpatRaster ob-ject or a named nu-meric ve +c-tor with four names +[3] [4] [5] [6] [7] +Overfull \hbox (50.24054pt too wide) in paragraph at lines 376--377 +[]\T1/zi4/m/n/10 "id_from:id_to" []\T1/ptm/m/n/10 for-mat or []\T1/zi4/m/n/10 c +(unique(grid_id)[id_from], unique(grid_id)[id_to]) +[8] [9] [10] [11] [12] [13] [14] [15] +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.ind [16] [17]) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.aux) + +Package rerunfilecheck Warning: File `Rd2.out' has changed. +(rerunfilecheck) Rerun to get outlines right +(rerunfilecheck) or use package `bookmark'. + + ) +(see the transcript file for additional information) +Output written on Rd2.pdf (17 pages, 115771 bytes). +Transcript written on Rd2.log. +This is makeindex, version 2.17 [TeX Live 2023] (kpathsea + Thai support). +Scanning input file Rd2.idx....done (25 entries accepted, 0 rejected). +Sorting entries....done (101 comparisons). +Generating output file Rd2.ind....done (53 lines written, 0 warnings). +Output written in Rd2.ind. +Transcript written in Rd2.ilg. +This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Homebrew) (preloaded format=pdflatex) + restricted \write18 enabled. +entering extended mode +LaTeX2e <2022-11-01> patch level 1 +L3 programming layer <2023-02-22> (./Rd2.tex + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/book.c +ls +Document Class: book 2022/07/02 v1.4n Standard LaTeX document class + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/bk10.c +lo)) (/Library/Frameworks/R.framework/Resources/share/texmf/tex/latex/Rd.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/ifthen +.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/longt +able.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/bm.st +y) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/alltt. +sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/verba +tim.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/url/url.sty +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/textco +mp.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +math.sty +For additional information on amsmath, use the `?' option. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +text.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +gen.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +bsy.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +opn.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am +sfonts.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am +ssymb.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ma +thrsfs.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/iftex/ift +ex.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/fonten +c.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/time +s.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/zi4.sty +`inconsolata-zi4' v1.12, 2019/05/17 Text macros for Inconsolata (msharpe) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/xkeyval/xke +yval.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x +keyval.tex +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x +kvutils.tex +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/k +eyval.tex))))) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/co +lor.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-cf +g/color.cfg) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-de +f/pdftex.def) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/ma +thcolor.ltx)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hy +perref.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/ltxcmds/l +txcmds.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdftexcmd +s/pdftexcmds.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/infwarerr +/infwarerr.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvsetkeys/k +vsetkeys.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/kvdefinek +eys/kvdefinekeys.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdfescape +/pdfescape.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hycolor/hyc +olor.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/letltxmacro +/letltxmacro.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/auxhook/aux +hook.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/na +meref.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/refcount/re +fcount.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/gettitles +tring/gettitlestring.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvoptions/k +voptions.sty))) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pd +1enc.def) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/intcalc/i +ntcalc.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/etexcmds/ +etexcmds.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pu +enc.def) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bitset/bi +tset.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bigintcal +c/bigintcalc.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atbegs +hi-ltx.sty)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hp +dftex.def +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atvery +end-ltx.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/rerunfilech +eck/rerunfilecheck.sty +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/uniquecou +nter/uniquecounter.sty)))) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/makeid +x.sty) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/inpute +nc.sty) +Writing index file Rd2.idx + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1pt +m.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/l3backend/l +3backend-pdftex.def) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.aux) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/context/base/mkii +/supp-pdf.mkii +[Loading MPS to PDF converter (version 2006.09.02).] +) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.out) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.out) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/t1zi4.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um +sa.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um +sb.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ur +sfs.fd) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1ph +v.fd) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.toc [1{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fo +nts/map/pdftex/updmap/pdftex.map}{/opt/homebrew/Cellar/texlive/20230313_2/share +/texmf-dist/fonts/enc/dvips/base/8r.enc}{/opt/homebrew/Cellar/texlive/20230313_ +2/share/texmf-dist/fonts/enc/dvips/inconsolata/i4-t1-0.enc}]) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/ts1zi4.fd) [2{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/e +nc/dvips/inconsolata/i4-ts1.enc}] [3] +Overfull \hbox (6.7171pt too wide) in paragraph at lines 143--144 +[]\T1/ptm/m/n/10 sf*/stars/SpatVector/SpatRaster ob-ject or a named nu-meric ve +c-tor with four names +[4] [5] [6] [7] +Overfull \hbox (50.24054pt too wide) in paragraph at lines 376--377 +[]\T1/zi4/m/n/10 "id_from:id_to" []\T1/ptm/m/n/10 for-mat or []\T1/zi4/m/n/10 c +(unique(grid_id)[id_from], unique(grid_id)[id_to]) +[8] [9] [10] [11] [12] [13] [14] [15] +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.ind [16] [17]) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.aux) ) +(see the transcript file for additional information) +Output written on Rd2.pdf (17 pages, 116155 bytes). +Transcript written on Rd2.log. +Saving output to ‘scomps-manual.pdf’ ... +Done +You may want to clean up by 'rm -Rf /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpOaxUwq/Rd2pdff3c856e679a5' diff --git a/scomps.Rcheck/scomps-Ex.R b/scomps.Rcheck/scomps-Ex.R new file mode 100644 index 00000000..4c502e90 --- /dev/null +++ b/scomps.Rcheck/scomps-Ex.R @@ -0,0 +1,121 @@ +pkgname <- "scomps" +source(file.path(R.home("share"), "R", "examples-header.R")) +options(warn = 1) +library('scomps') + +base::assign(".oldSearch", base::search(), pos = 'CheckExEnv') +base::assign(".old_wd", base::getwd(), pos = 'CheckExEnv') +cleanEx() +nameEx("aw_covariates") +### * aw_covariates + +flush(stderr()); flush(stdout()) + +### Name: aw_covariates +### Title: Computing area weighted covariates using two polygon sf or +### SpatVector objects +### Aliases: aw_covariates + +### ** Examples + +# package +library(sf) + +# run +nc = sf::st_read(system.file("shape/nc.shp", package="sf")) +nc = sf::st_transform(nc, 5070) +pp = sf::st_sample(nc, size = 300) +pp = sf::st_as_sf(pp) +pp[["id"]] = seq(1, nrow(pp)) +sf::st_crs(pp) = "EPSG:5070" +ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) + +system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) +summary(ppb_nc_aw) +#### Example of aw_covariates ends #### + + + +cleanEx() +nameEx("check_crs") +### * check_crs + +flush(stderr()); flush(stdout()) + +### Name: check_crs +### Title: Check Coordinate Reference System +### Aliases: check_crs + +### ** Examples + +# data +library(sf) +ncpath = system.file("shape/nc.shp", package = "sf") +nc = read_sf(ncpath) +check_crs(nc) + + + + +cleanEx() +nameEx("get_computational_regions") +### * get_computational_regions + +flush(stderr()); flush(stdout()) + +### Name: get_computational_regions +### Title: Get a set of computational regions +### Aliases: get_computational_regions + +### ** Examples + +# data +library(sf) +ncpath = system.file("shape/nc.shp", package = "sf") +nc = read_sf(ncpath) +nc = st_transform(nc, "EPSG:5070") +# run +# nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) + + + + +cleanEx() +nameEx("grid_merge") +### * grid_merge + +flush(stderr()); flush(stdout()) + +### Name: grid_merge +### Title: grid_merge: Merge grid polygons with given rules +### Aliases: grid_merge + +### ** Examples + +# library(sf) +# library(igraph) +# ligrary(dplyr) +# dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +# sf::st_crs(dg) = 5070 +# dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) +# dgs$CGRIDID = seq(1, nrow(dgs)) +# +# dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") +# sf::st_crs(dg_sample) = sf::st_crs(dg) +# dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) +#### NOT RUN #### + + + +### *
+### +cleanEx() +options(digits = 7L) +base::cat("Time elapsed: ", proc.time() - base::get("ptime", pos = 'CheckExEnv'),"\n") +grDevices::dev.off() +### +### Local variables: *** +### mode: outline-minor *** +### outline-regexp: "\\(> \\)?### [*]+" *** +### End: *** +quit('no') diff --git a/scomps.Rcheck/scomps-Ex.Rout b/scomps.Rcheck/scomps-Ex.Rout new file mode 100644 index 00000000..68d31f33 --- /dev/null +++ b/scomps.Rcheck/scomps-Ex.Rout @@ -0,0 +1,212 @@ + +R version 4.3.1 (2023-06-16) -- "Beagle Scouts" +Copyright (C) 2023 The R Foundation for Statistical Computing +Platform: aarch64-apple-darwin20 (64-bit) + +R is free software and comes with ABSOLUTELY NO WARRANTY. +You are welcome to redistribute it under certain conditions. +Type 'license()' or 'licence()' for distribution details. + + Natural language support but running in an English locale + +R is a collaborative project with many contributors. +Type 'contributors()' for more information and +'citation()' on how to cite R or R packages in publications. + +Type 'demo()' for some demos, 'help()' for on-line help, or +'help.start()' for an HTML browser interface to help. +Type 'q()' to quit R. + +> pkgname <- "scomps" +> source(file.path(R.home("share"), "R", "examples-header.R")) +> options(warn = 1) +> library('scomps') +> +> base::assign(".oldSearch", base::search(), pos = 'CheckExEnv') +> base::assign(".old_wd", base::getwd(), pos = 'CheckExEnv') +> cleanEx() +> nameEx("aw_covariates") +> ### * aw_covariates +> +> flush(stderr()); flush(stdout()) +> +> ### Name: aw_covariates +> ### Title: Computing area weighted covariates using two polygon sf or +> ### SpatVector objects +> ### Aliases: aw_covariates +> +> ### ** Examples +> +> # package +> library(sf) +Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE +> +> # run +> nc = sf::st_read(system.file("shape/nc.shp", package="sf")) +Reading layer `nc' from data source + `/Users/songi2/Library/R/arm64/4.3/library/sf/shape/nc.shp' + using driver `ESRI Shapefile' +Simple feature collection with 100 features and 14 fields +Geometry type: MULTIPOLYGON +Dimension: XY +Bounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965 +Geodetic CRS: NAD27 +> nc = sf::st_transform(nc, 5070) +> pp = sf::st_sample(nc, size = 300) +> pp = sf::st_as_sf(pp) +> pp[["id"]] = seq(1, nrow(pp)) +> sf::st_crs(pp) = "EPSG:5070" +> ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +> +> system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) +Warning in st_interpolate_aw.sf(poly_weight[, index_numeric], poly_in, extensive = FALSE) : + st_interpolate_aw assumes attributes are constant or uniform over areas of x + user system elapsed + 0.180 0.003 0.183 +> summary(ppb_nc_aw) + AREA PERIMETER CNTY_ CNTY_ID + Min. :0.06133 Min. :1.114 Min. :1825 Min. :1825 + 1st Qu.:0.12008 1st Qu.:1.549 1st Qu.:1917 1st Qu.:1917 + Median :0.13834 Median :1.685 Median :2000 Median :2000 + Mean :0.14702 Mean :1.777 Mean :2004 Mean :2004 + 3rd Qu.:0.17292 3rd Qu.:1.978 3rd Qu.:2078 3rd Qu.:2078 + Max. :0.24000 Max. :3.588 Max. :2241 Max. :2241 + FIPSNO CRESS_ID BIR74 SID74 + Min. :37009 Min. : 5.042 Min. : 315.1 Min. : 0.000 + 1st Qu.:37075 1st Qu.:38.024 1st Qu.: 1955.4 1st Qu.: 4.015 + Median :37104 Median :52.610 Median : 3124.2 Median : 6.867 + Mean :37103 Mean :51.798 Mean : 3977.7 Mean : 8.529 + 3rd Qu.:37131 3rd Qu.:65.974 3rd Qu.: 4639.0 3rd Qu.:10.591 + Max. :37191 Max. :95.910 Max. :18561.5 Max. :36.075 + NWBIR74 BIR79 SID79 NWBIR79 + Min. : 6.222 Min. : 403.3 Min. : 0.000 Min. : 4.222 + 1st Qu.: 458.022 1st Qu.: 2393.5 1st Qu.: 4.990 1st Qu.: 589.223 + Median : 955.882 Median : 3903.2 Median : 8.036 Median :1189.908 + Mean :1285.378 Mean : 5092.6 Mean :10.052 Mean :1655.747 + 3rd Qu.:1669.800 3rd Qu.: 5904.1 3rd Qu.:13.890 3rd Qu.:2127.972 + Max. :6467.572 Max. :26115.7 Max. :34.448 Max. :9367.957 + geometry + POLYGON :300 + epsg:5070 : 0 + +proj=aea ...: 0 + + + +> #### Example of aw_covariates ends #### +> +> +> +> cleanEx() + +detaching ‘package:sf’ + +> nameEx("check_crs") +> ### * check_crs +> +> flush(stderr()); flush(stdout()) +> +> ### Name: check_crs +> ### Title: Check Coordinate Reference System +> ### Aliases: check_crs +> +> ### ** Examples +> +> # data +> library(sf) +Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE +> ncpath = system.file("shape/nc.shp", package = "sf") +> nc = read_sf(ncpath) +> check_crs(nc) +Coordinate Reference System: + User input: NAD27 + wkt: +GEOGCRS["NAD27", + DATUM["North American Datum 1927", + ELLIPSOID["Clarke 1866",6378206.4,294.978698213898, + LENGTHUNIT["metre",1]]], + PRIMEM["Greenwich",0, + ANGLEUNIT["degree",0.0174532925199433]], + CS[ellipsoidal,2], + AXIS["latitude",north, + ORDER[1], + ANGLEUNIT["degree",0.0174532925199433]], + AXIS["longitude",east, + ORDER[2], + ANGLEUNIT["degree",0.0174532925199433]], + ID["EPSG",4267]] +> +> +> +> +> cleanEx() + +detaching ‘package:sf’ + +> nameEx("get_computational_regions") +> ### * get_computational_regions +> +> flush(stderr()); flush(stdout()) +> +> ### Name: get_computational_regions +> ### Title: Get a set of computational regions +> ### Aliases: get_computational_regions +> +> ### ** Examples +> +> # data +> library(sf) +Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE +> ncpath = system.file("shape/nc.shp", package = "sf") +> nc = read_sf(ncpath) +> nc = st_transform(nc, "EPSG:5070") +> # run +> # nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) +> +> +> +> +> cleanEx() + +detaching ‘package:sf’ + +> nameEx("grid_merge") +> ### * grid_merge +> +> flush(stderr()); flush(stdout()) +> +> ### Name: grid_merge +> ### Title: grid_merge: Merge grid polygons with given rules +> ### Aliases: grid_merge +> +> ### ** Examples +> +> # library(sf) +> # library(igraph) +> # ligrary(dplyr) +> # dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +> # sf::st_crs(dg) = 5070 +> # dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) +> # dgs$CGRIDID = seq(1, nrow(dgs)) +> # +> # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") +> # sf::st_crs(dg_sample) = sf::st_crs(dg) +> # dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) +> #### NOT RUN #### +> +> +> +> ### *
+> ### +> cleanEx() +> options(digits = 7L) +> base::cat("Time elapsed: ", proc.time() - base::get("ptime", pos = 'CheckExEnv'),"\n") +Time elapsed: 0.684 0.035 0.72 0 0 +> grDevices::dev.off() +null device + 1 +> ### +> ### Local variables: *** +> ### mode: outline-minor *** +> ### outline-regexp: "\\(> \\)?### [*]+" *** +> ### End: *** +> quit('no') diff --git a/scomps.Rcheck/scomps-Ex.pdf b/scomps.Rcheck/scomps-Ex.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ec1c6fe30269924782ad2fae006daca8aea4de34 GIT binary patch literal 3611 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 Ykwh3Ufe!yTo3^&D4nkSk+};B5Ul$NA%K!iX literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps-manual.log b/scomps.Rcheck/scomps-manual.log new file mode 100644 index 00000000..a85a6b5f --- /dev/null +++ b/scomps.Rcheck/scomps-manual.log @@ -0,0 +1,570 @@ +This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Homebrew) (preloaded format=pdflatex 2023.6.22) 4 OCT 2023 11:41 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**\input ./Rd2.tex \input ./Rd2.tex \input ./Rd2.tex + (./Rd2.tex + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/book.c +ls +Document Class: book 2022/07/02 v1.4n Standard LaTeX document class + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/bk10.c +lo +File: bk10.clo 2022/07/02 v1.4n Standard LaTeX file (size option) +) +\c@part=\count185 +\c@chapter=\count186 +\c@section=\count187 +\c@subsection=\count188 +\c@subsubsection=\count189 +\c@paragraph=\count190 +\c@subparagraph=\count191 +\c@figure=\count192 +\c@table=\count193 +\abovecaptionskip=\skip48 +\belowcaptionskip=\skip49 +\bibindent=\dimen140 +) (/Library/Frameworks/R.framework/Resources/share/texmf/tex/latex/Rd.sty +Package: Rd + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/ifthen +.sty +Package: ifthen 2022/04/13 v1.1d Standard LaTeX ifthen package (DPC) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/longt +able.sty +Package: longtable 2021-09-01 v4.17 Multi-page Table package (DPC) +\LTleft=\skip50 +\LTright=\skip51 +\LTpre=\skip52 +\LTpost=\skip53 +\LTchunksize=\count194 +\LTcapwidth=\dimen141 +\LT@head=\box51 +\LT@firsthead=\box52 +\LT@foot=\box53 +\LT@lastfoot=\box54 +\LT@gbox=\box55 +\LT@cols=\count195 +\LT@rows=\count196 +\c@LT@tables=\count197 +\c@LT@chunks=\count198 +\LT@p@ftn=\toks16 +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/bm.st +y +Package: bm 2022/01/05 v1.2f Bold Symbol Support (DPC/FMi) +\symboldoperators=\mathgroup4 +\symboldletters=\mathgroup5 +\symboldsymbols=\mathgroup6 +Package bm Info: No bold for \OMX/cmex/m/n, using \pmb. +LaTeX Font Info: Redeclaring math alphabet \mathbf on input line 149. +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/alltt. +sty +Package: alltt 2021/01/29 v2.0g defines alltt environment +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/verba +tim.sty +Package: verbatim 2022-07-02 v1.5u LaTeX2e package for verbatim enhancements +\every@verbatim=\toks17 +\verbatim@line=\toks18 +\verbatim@in@stream=\read2 +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip16 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/textco +mp.sty +Package: textcomp 2020/02/02 v2.0n Standard LaTeX package +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +math.sty +Package: amsmath 2022/04/08 v2.17n AMS math features +\@mathmargin=\skip54 + +For additional information on amsmath, use the `?' option. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +text.sty +Package: amstext 2021/08/26 v2.01 AMS text + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +gen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks19 +\ex@=\dimen142 +)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +bsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +LaTeX Info: Redefining \boldsymbol on input line 28. +\pmbraise@=\dimen143 +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams +opn.sty +Package: amsopn 2022/04/08 v2.04 operator names +) +\inf@bad=\count199 +LaTeX Info: Redefining \frac on input line 234. +\uproot@=\count266 +\leftroot@=\count267 +LaTeX Info: Redefining \overline on input line 399. +LaTeX Info: Redefining \colon on input line 410. +\classnum@=\count268 +\DOTSCASE@=\count269 +LaTeX Info: Redefining \ldots on input line 496. +LaTeX Info: Redefining \dots on input line 499. +LaTeX Info: Redefining \cdots on input line 620. +\Mathstrutbox@=\box56 +\strutbox@=\box57 +LaTeX Info: Redefining \big on input line 722. +LaTeX Info: Redefining \Big on input line 723. +LaTeX Info: Redefining \bigg on input line 724. +LaTeX Info: Redefining \Bigg on input line 725. +\big@size=\dimen144 +LaTeX Font Info: Redeclaring font encoding OML on input line 743. +LaTeX Font Info: Redeclaring font encoding OMS on input line 744. +\macc@depth=\count270 +LaTeX Info: Redefining \bmod on input line 905. +LaTeX Info: Redefining \pmod on input line 910. +LaTeX Info: Redefining \smash on input line 940. +LaTeX Info: Redefining \relbar on input line 970. +LaTeX Info: Redefining \Relbar on input line 971. +\c@MaxMatrixCols=\count271 +\dotsspace@=\muskip17 +\c@parentequation=\count272 +\dspbrk@lvl=\count273 +\tag@help=\toks20 +\row@=\count274 +\column@=\count275 +\maxfields@=\count276 +\andhelp@=\toks21 +\eqnshift@=\dimen145 +\alignsep@=\dimen146 +\tagshift@=\dimen147 +\tagwidth@=\dimen148 +\totwidth@=\dimen149 +\lineht@=\dimen150 +\@envbody=\toks22 +\multlinegap=\skip55 +\multlinetaggap=\skip56 +\mathdisplay@stack=\toks23 +LaTeX Info: Redefining \[ on input line 2953. +LaTeX Info: Redefining \] on input line 2954. +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am +sfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup7 +\symAMSb=\mathgroup8 +LaTeX Font Info: Redeclaring math symbol \hbar on input line 98. +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am +ssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ma +thrsfs.sty +Package: mathrsfs 1996/01/01 Math RSFS package v1.0 (jk) +\symrsfs=\mathgroup9 +) +\ldescriptionwidth=\skip57 + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/iftex/ift +ex.sty +Package: iftex 2022/02/03 v1.0f TeX engine tests +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/fonten +c.sty +Package: fontenc 2021/04/29 v2.0v Standard LaTeX package +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/time +s.sty +Package: times 2020/03/25 PSNFSS-v9.3 (SPQR) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/zi4.sty +Package: zi4 2019/05/17 v1.12 + +`inconsolata-zi4' v1.12, 2019/05/17 Text macros for Inconsolata (msharpe) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/xkeyval/xke +yval.sty +Package: xkeyval 2022/06/16 v2.9 package option processing (HA) + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x +keyval.tex +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x +kvutils.tex +\XKV@toks=\toks24 +\XKV@tempa@toks=\toks25 + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/k +eyval.tex)) +\XKV@depth=\count277 +File: xkeyval.tex 2014/12/03 v2.7a key=value parser (HA) +)) +\zifour@ocount=\count278 +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/co +lor.sty +Package: color 2022/01/06 v1.3d Standard LaTeX Color (DPC) + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-cf +g/color.cfg +File: color.cfg 2016/01/02 v1.6 sample color configuration +) +Package color Info: Driver file: pdftex.def on input line 149. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-de +f/pdftex.def +File: pdftex.def 2022/09/22 v1.2b Graphics/color driver for pdftex +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/ma +thcolor.ltx)) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hy +perref.sty +Package: hyperref 2023-02-07 v7.00v Hypertext links for LaTeX + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/ltxcmds/l +txcmds.sty +Package: ltxcmds 2020-05-10 v1.25 LaTeX kernel commands for general use (HO) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdftexcmd +s/pdftexcmds.sty +Package: pdftexcmds 2020-06-27 v0.33 Utility functions of pdfTeX for LuaTeX (HO +) + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/infwarerr +/infwarerr.sty +Package: infwarerr 2019/12/03 v1.5 Providing info/warning/error messages (HO) +) +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode found. +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvsetkeys/k +vsetkeys.sty +Package: kvsetkeys 2022-10-05 v1.19 Key value parser (HO) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/kvdefinek +eys/kvdefinekeys.sty +Package: kvdefinekeys 2019-12-19 v1.6 Define keys (HO) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdfescape +/pdfescape.sty +Package: pdfescape 2019/12/09 v1.15 Implements pdfTeX's escape features (HO) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hycolor/hyc +olor.sty +Package: hycolor 2020-01-27 v1.10 Color options for hyperref/bookmark (HO) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/letltxmacro +/letltxmacro.sty +Package: letltxmacro 2019/12/03 v1.6 Let assignment for LaTeX macros (HO) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/auxhook/aux +hook.sty +Package: auxhook 2019-12-17 v1.6 Hooks for auxiliary files (HO) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/na +meref.sty +Package: nameref 2022-05-17 v2.50 Cross-referencing by name of section + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/refcount/re +fcount.sty +Package: refcount 2019/12/15 v3.6 Data extraction from label references (HO) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/gettitles +tring/gettitlestring.sty +Package: gettitlestring 2019/12/15 v1.6 Cleanup title references (HO) + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvoptions/k +voptions.sty +Package: kvoptions 2022-06-15 v3.15 Key value format for package options (HO) +)) +\c@section@level=\count279 +) +\@linkdim=\dimen151 +\Hy@linkcounter=\count280 +\Hy@pagecounter=\count281 + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pd +1enc.def +File: pd1enc.def 2023-02-07 v7.00v Hyperref: PDFDocEncoding definition (HO) +Now handling font encoding PD1 ... +... no UTF-8 mapping file for font encoding PD1 +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/intcalc/i +ntcalc.sty +Package: intcalc 2019/12/15 v1.3 Expandable calculations with integers (HO) +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/etexcmds/ +etexcmds.sty +Package: etexcmds 2019/12/15 v1.7 Avoid name clashes with e-TeX commands (HO) +) +\Hy@SavedSpaceFactor=\count282 + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pu +enc.def +File: puenc.def 2023-02-07 v7.00v Hyperref: PDF Unicode definition (HO) +Now handling font encoding PU ... +... no UTF-8 mapping file for font encoding PU +) +Package hyperref Info: Hyper figures OFF on input line 4177. +Package hyperref Info: Link nesting OFF on input line 4182. +Package hyperref Info: Hyper index ON on input line 4185. +Package hyperref Info: Plain pages OFF on input line 4192. +Package hyperref Info: Backreferencing OFF on input line 4197. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4425. +\c@Hy@tempcnt=\count283 +LaTeX Info: Redefining \url on input line 4763. +\XeTeXLinkMargin=\dimen152 + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bitset/bi +tset.sty +Package: bitset 2019/12/09 v1.3 Handle bit-vector datatype (HO) + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bigintcal +c/bigintcalc.sty +Package: bigintcalc 2019/12/15 v1.5 Expandable calculations on big integers (HO +) +)) +\Fld@menulength=\count284 +\Field@Width=\dimen153 +\Fld@charsize=\dimen154 +Package hyperref Info: Hyper figures OFF on input line 6042. +Package hyperref Info: Link nesting OFF on input line 6047. +Package hyperref Info: Hyper index ON on input line 6050. +Package hyperref Info: backreferencing OFF on input line 6057. +Package hyperref Info: Link coloring OFF on input line 6062. +Package hyperref Info: Link coloring with OCG OFF on input line 6067. +Package hyperref Info: PDF/A mode OFF on input line 6072. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atbegs +hi-ltx.sty +Package: atbegshi-ltx 2021/01/10 v1.0c Emulation of the original atbegshi +package with kernel methods +) +\Hy@abspage=\count285 +\c@Item=\count286 +\c@Hfootnote=\count287 +) +Package hyperref Info: Driver (autodetected): hpdftex. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hp +dftex.def +File: hpdftex.def 2023-02-07 v7.00v Hyperref driver for pdfTeX + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atvery +end-ltx.sty +Package: atveryend-ltx 2020/08/19 v1.0a Emulation of the original atveryend pac +kage +with kernel methods +) +\Fld@listcount=\count288 +\c@bookmark@seq@number=\count289 + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/rerunfilech +eck/rerunfilecheck.sty +Package: rerunfilecheck 2022-07-10 v1.10 Rerun checks for auxiliary files (HO) + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/uniquecou +nter/uniquecounter.sty +Package: uniquecounter 2019/12/15 v1.4 Provide unlimited unique counter (HO) +) +Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2 +85. +) +\Hy@SectionHShift=\skip58 +) +Package hyperref Info: Option `colorlinks' set `true' on input line 390. +Package hyperref Info: Option `linktocpage' set `true' on input line 390. +Package hyperref Info: Option `plainpages' set `false' on input line 390. +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/makeid +x.sty +Package: makeidx 2021/10/04 v1.0m Standard LaTeX package +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/inpute +nc.sty +Package: inputenc 2021/02/14 v1.3d Input encoding file +\inpenc@prehook=\toks26 +\inpenc@posthook=\toks27 +) +\@indexfile=\write3 +\openout3 = `Rd2.idx'. + + +Writing index file Rd2.idx +LaTeX Font Info: Trying to load font information for T1+ptm on input line 8. + + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1pt +m.fd +File: t1ptm.fd 2001/06/04 font definitions for T1/ptm. +) +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/l3backend/l +3backend-pdftex.def +File: l3backend-pdftex.def 2023-01-16 L3 backend support: PDF output (pdfTeX) +\l__color_backend_stack_int=\count290 +\l__pdf_internal_box=\box58 +) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.aux) +\openout1 = `Rd2.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 8. +LaTeX Font Info: ... okay on input line 8. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 8. +LaTeX Font Info: ... okay on input line 8. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 8. +LaTeX Font Info: ... okay on input line 8. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 8. +LaTeX Font Info: ... okay on input line 8. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 8. +LaTeX Font Info: ... okay on input line 8. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 8. +LaTeX Font Info: ... okay on input line 8. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 8. +LaTeX Font Info: ... okay on input line 8. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 8. +LaTeX Font Info: ... okay on input line 8. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 8. +LaTeX Font Info: ... okay on input line 8. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/context/base/mkii +/supp-pdf.mkii +[Loading MPS to PDF converter (version 2006.09.02).] +\scratchcounter=\count291 +\scratchdimen=\dimen155 +\scratchbox=\box59 +\nofMPsegments=\count292 +\nofMParguments=\count293 +\everyMPshowfont=\toks28 +\MPscratchCnt=\count294 +\MPscratchDim=\dimen156 +\MPnumerator=\count295 +\makeMPintoPDFobject=\count296 +\everyMPtoPDFconversion=\toks29 +) +Package hyperref Info: Link coloring ON on input line 8. + +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.out) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.out) +\@outlinefile=\write4 +\openout4 = `Rd2.out'. + +LaTeX Font Info: Trying to load font information for T1+zi4 on input line 33 +. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/t1zi4.fd +File: t1zi4.fd 2018/01/14 T1/zi4 (Inconsolata) +) +LaTeX Font Info: Font shape `T1/zi4/m/n' will be +(Font) scaled to size 10.0pt on input line 33. +LaTeX Font Info: Trying to load font information for U+msa on input line 33. + + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um +sa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Trying to load font information for U+msb on input line 33. + + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um +sb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Trying to load font information for U+rsfs on input line 33 +. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ur +sfs.fd +File: ursfs.fd 1998/03/24 rsfs font definition file (jk) +) +LaTeX Font Info: Trying to load font information for T1+phv on input line 36 +. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1ph +v.fd +File: t1phv.fd 2020/03/25 scalable font definitions for T1/phv. +) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.toc [1 + + +{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/map/pdftex/updm +ap/pdftex.map}{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/e +nc/dvips/base/8r.enc}{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/ +fonts/enc/dvips/inconsolata/i4-t1-0.enc}]) +\tf@toc=\write5 +\openout5 = `Rd2.toc'. + +LaTeX Font Info: Font shape `T1/zi4/m/n' will be +(Font) scaled to size 9.0pt on input line 69. +LaTeX Font Info: Trying to load font information for TS1+zi4 on input line 8 +0. + +(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata +/ts1zi4.fd +File: ts1zi4.fd 2018/01/14 TS1/zi4 (Inconsolata) +) +LaTeX Font Info: Font shape `TS1/zi4/m/n' will be +(Font) scaled to size 9.0pt on input line 80. + [2{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/enc/dvips/in +consolata/i4-ts1.enc}] [3] +Overfull \hbox (6.7171pt too wide) in paragraph at lines 143--144 +[]\T1/ptm/m/n/10 sf*/stars/SpatVector/SpatRaster ob-ject or a named nu-meric ve +c-tor with four names + [] + +[4] [5] [6] [7] +Overfull \hbox (50.24054pt too wide) in paragraph at lines 376--377 +[]\T1/zi4/m/n/10 "id_from:id_to" []\T1/ptm/m/n/10 for-mat or []\T1/zi4/m/n/10 c +(unique(grid_id)[id_from], unique(grid_id)[id_to]) + [] + +[8] [9] [10] [11] [12] [13] [14] [15] +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.ind [16] [17 + + +]) +(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 +56e679a5/Rd2.aux) +Package rerunfilecheck Info: File `Rd2.out' has not changed. +(rerunfilecheck) Checksum: C70573B6B3562A9A0AAA03892470A1FF;3666. + ) +Here is how much of TeX's memory you used: + 10599 strings out of 476025 + 168736 string characters out of 5779036 + 1866388 words of memory out of 5000000 + 30666 multiletter control sequences out of 15000+600000 + 549019 words of font info for 77 fonts, out of 8000000 for 9000 + 1141 hyphenation exceptions out of 8191 + 92i,6n,92p,475b,729s stack positions out of 10000i,1000n,20000p,200000b,200000s + +Output written on Rd2.pdf (17 pages, 116155 bytes). +PDF statistics: + 465 PDF objects out of 1000 (max. 8388607) + 428 compressed objects within 5 object streams + 192 named destinations out of 1000 (max. 500000) + 209 words of extra memory for PDF output out of 10000 (max. 10000000) + diff --git a/scomps.Rcheck/scomps-manual.pdf b/scomps.Rcheck/scomps-manual.pdf new file mode 100644 index 0000000000000000000000000000000000000000..400991eee523a64e71fe737ff6f44ea083d436c1 GIT binary patch literal 116155 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

2p0&Ndnn;8doG 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 literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/DESCRIPTION b/scomps.Rcheck/scomps/DESCRIPTION new file mode 100644 index 00000000..737d2c62 --- /dev/null +++ b/scomps.Rcheck/scomps/DESCRIPTION @@ -0,0 +1,22 @@ +Package: scomps +Title: Scalable R geospatial computation +Version: 0.0.3.10042023 +Authors@R: + person("Insang", "Song", , "geoissong@gmail.com", role = c("aut", "cre"), + comment = c(ORCID = "0000-0001-8732-3256")) +Description: A package for scalable geospatial computation for + environmental health research +License: MIT + file LICENSE +Encoding: UTF-8 +Roxygen: list(markdown = TRUE) +RoxygenNote: 7.2.3 +Imports: covr, dplyr, future, future.apply, methods, rlang, sf, stars, + terra, testthat, units +Suggests: future.batchtools, igraph, knitr, logr, rmarkdown, withr +VignetteBuilder: knitr +Config/testthat/edition: 3 +NeedsCompilation: no +Packaged: 2023-10-04 15:41:03 UTC; songi2 +Author: Insang Song [aut, cre] () +Maintainer: Insang Song +Built: R 4.3.1; ; 2023-10-04 15:41:20 UTC; unix diff --git a/scomps.Rcheck/scomps/INDEX b/scomps.Rcheck/scomps/INDEX new file mode 100644 index 00000000..80dc13d3 --- /dev/null +++ b/scomps.Rcheck/scomps/INDEX @@ -0,0 +1,39 @@ +aw_covariates Computing area weighted covariates using two + polygon sf or SpatVector objects +calculate_sedc Calculate SEDC covariates +check_bbox Check if the data extent is inside the + reference bounding box +check_crs Check Coordinate Reference System +check_crs2 check_crs2: Coordinate system checker +check_packbound Return the package the input object is based on +check_within_reference + Check if the boundary of the vector/raster + object is inside the reference +clip_as_extent Extent clipping +clip_as_extent_ras clip_as_extent_ras: Clip input raster. +clip_as_extent_ras2 clip_as_extent_ras2: Clip input raster (version + 2). +distribute_process Process a given function in the entire or + partial computational grids (under + construction) +estimate_demands Estimate computational demands from inputs (to + be written) +extent_to_polygon Generate a rectangular polygon from extent +extract_with Extract raster values with point buffers or + polygons +extract_with_buffer Extract summarized values from raster with + points and a buffer radius (to be written) +extract_with_polygons Extract summarized values from raster with + generic polygons +get_computational_regions + Get a set of computational regions +grid_merge grid_merge: Merge grid polygons with given + rules +initate_log Turn on logging +rast_short Quick call for SpatRaster with a window +set_clip_extent Setting the clipping extent +sp_index_grid sp_index_grid: Generate grid polygons +sp_indexing Create integer indices for grid +switch_packbound Switch spatial data class +validate_and_repair_vectors + Validate and repair input vector data diff --git a/scomps.Rcheck/scomps/LICENSE b/scomps.Rcheck/scomps/LICENSE new file mode 100644 index 00000000..74e6421f --- /dev/null +++ b/scomps.Rcheck/scomps/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2023 +COPYRIGHT HOLDER: I. Song diff --git a/scomps.Rcheck/scomps/Meta/Rd.rds b/scomps.Rcheck/scomps/Meta/Rd.rds new file mode 100644 index 0000000000000000000000000000000000000000..ac6f584a8d8d331ce9a42e195e4c615f4c00703c GIT binary patch literal 1232 zcmV;>1TXs^iwFP!000001Kn2LZyYrc-!_T36hccw5fKOsQlLd@iV6=XhzE3}6+%Uj zq!r?2<@5UX-0rPcw)ZZ_6aOv$1!4TPYkN0EJd%gK-J2QD=WoXI+pR3iwzBQ58`;(l zd}ce(&!0T}259^6X9CY1cn-4dY*&Bdbx!yS3x*YyN2i6Oze8|E+6sudqy_02dt^b$ zt9&-&7d`PUOC&-L1cCOrC*HNh29sAa-quCWIk22HQwvt-g3hU+HKCzL6>D-Vb9$j@ zt$N12n2`${c=6tl8Mt$=U{VP-Yaz@=a6)Bpbe~GamO29kUE;b3SnoP*isuclHYKln z-fiFsOq2;Fa3mz>vvv*v_T2X)uG1M9{IH}7>a=WHg%#s9t{_Dvi)8jn!HRrIMHyu6 zZB{d-W2kr;h(a1vE*D$`dAuvN4V|tu!*^tpv$~)cxi%3f_jFbV%J(G%K^9|0{%D0O zR%mx1pAbQVnaEd^C~lDxV{%z9qe$%RM}X>Z zJ%E|d#s~oYp&|Nw!c*w^9vI-xH(-dL4!=XhdEAe}&3EFJSo4|ef#xW01}O7FJ;Z#v z6MXq9N8s`b17vj|Okm~cAG`)r381q7{X355+0;}Ca)hv;7_BKQ7m60B?;6xf%~orU zT$z!aBQDTcgVhU@CB$bh;iD`6)HfJ9JNaRX1|9g_RQCsBbEFm&LFO^C1w~9ER!de; z!|6H)nR012`u6<9Dw%RFfTN9_cH(Cnsp!%P9`I`v zLTkW~KcaA50_sEuQ==i86kng%spSKQ#%}@PdWOL%2Klx_PMWylq4wOLmF;o~c>V+G z@6H=TPGzqPa#t7NnpFw>g0)wL^6h_6Uh1eBN&WluDOF$%Mx=&aoYQ#ve%VjoWAseF zOtm_N&WtI$XsfPmZ=dVVfW*R#E_+OV{%gws`*5pPXzu31Y2YtR6&S>P?WgS-Rc7F5 z6nS{ZWjc%o`Z4P29J%R)Kc2$iQo2JGEx{%nWJKo;TnX-jgEKSykp%BFTFulU74B}# z!x!!rFlDp1fNK-mzvjp_ybtzGJT|TyUJPKeCv`0`Y>DcsRDG#UfWMY_ZU57Pq8g!2%a^ zqD3w_6fAT}nbXBCL1Vn&B?iMqFUk2};fwkIviOCKkzIrLHH&BaX4aQ-r^d@}P)!_h z`w6T3Lbd%f2>9>wP2<0J&Y9|jCMPxFMSr!u@qNW$(eqctWXfT>G~J>*`H61Uuusa= u8GElJ=-1cB(OhUZV)0$U*GJy}J$P>Z2|t&Ymw&|6BxbZU%D5?rF*=c!no}R-ydxpz_-3Qu%b^-vSwlGux literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/Meta/hsearch.rds b/scomps.Rcheck/scomps/Meta/hsearch.rds new file mode 100644 index 0000000000000000000000000000000000000000..c7ab64314d561e959ca8a595fa4cbef8e7bf792a GIT binary patch literal 1124 zcmV-q1e^OGiwFP!000001MOH_ZyYrgp6sTi4U~jdMXGqfAO%_^XtPP%5X1x8E>%^E zLN=`sFC&k~JL`7F9@(DVgg?bUq#R#oCs`1nRzhVTqB%ac&v&lh?BwUoBuVro~!zIfNI3x-@tud47j1nzk>7Nd5G++y1NimvJR!lX`QQKXp zQD$4u1@h@YYJ!AB;~MMd)*2Go3lL(OhM^JBc=T|HE_CX*L(@lyO^}{a1Ri4K0!K_C z#udw{-H9EBY*@yPwv9h=MutL2*fC(o@%Z>mXQ3c?k!7KVmKeE&n69YXQh#=F zW*{cec?TWDSN`tt+GYoRky`y)5qA#fOw20Gl#I^1HAZ$}2o#?>AEXW_1DstWq~ zSE#?gZ-KnY))wTB=ir(%3Hv!~{w$Pl{(|0+$tSPk#PW!=U%!?Ng$O=Y``1e}Pqiu*5vD(wJ&X zIHrq2dw0vU(;>b?6zkk^(;xnL2*jn$glbvyQ%1 zH_Og*&z81qjxGI|xcRkLRxjYy3;1=ufc@9cYVq$D$$HQHZuiQ5&MH$j^IO?;3;b=I zJ8~J0a9qL6x(`mX_q!>fJ?qYF9Jv>NSpLAWBOH6T_xPcg)_(*;!JiYR%XT4Z7Uuu* zh!bIcyEr8KdHZBVBP$wtoiy^l`vU$i{Tt%M4 qBqN!&?3XM-N&Y6v#uIurhflaSjx!X%h_(JpoIe0s$v=tA6aWCQOd$XO literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/Meta/links.rds b/scomps.Rcheck/scomps/Meta/links.rds new file mode 100644 index 0000000000000000000000000000000000000000..903ef384997310223c74f8ba82c0030c06122b57 GIT binary patch literal 517 zcmV+g0{Z*0h%rBBU)Tv{kXV9=GF2eNU;jsHHvRh#?A$^> H5eEPO{$~Oh literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/Meta/nsInfo.rds b/scomps.Rcheck/scomps/Meta/nsInfo.rds new file mode 100644 index 0000000000000000000000000000000000000000..41a1f926f35ac5ec8ff3bf293a7cc436b1631f10 GIT binary patch literal 453 zcmV;$0XqI4iwFP!000001AUT9Yuqpp$CZ7s>~1#MW@#bxGvtz7dN1@=D1AV0LY5}> z5L+_Rc(eKPrK4DK?G4l*%lge|9)Hj8jSylk7V`@+U-G9|{`&dl?voI+10S}$;vSzp zuUoMYYuR+)L}7hLA7q zArLmPM+1$rCi8bG2szoh`lWO>87|r2m8RFKbLKIVMfb>!B-8teDTT^OZc8B6y=gmA zgwCp(MJVx~!>06TWCOm;qHNJ3#d2#`W+!fxWT>3a8eNANH>xp_ZWmgK*1$=|usL9c zXmh}Q;9_<4=68KOsv1p9&O&jetwJx4pvm#C?*~eZ25dZN|J#$_ES(oKeqE%LbAwH+ zJld1{g4drjx207L4&`a7R%6#|^WuRxU>24vUY vKlAM2)blX%JWIDSFSf>FsLApe9O1j`2<;Gb{o|oY0lD+P(QDDQ;R65wc0%9Y literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/Meta/package.rds b/scomps.Rcheck/scomps/Meta/package.rds new file mode 100644 index 0000000000000000000000000000000000000000..b905bea94dbf4e1c78c7c101742d0ff0b9771045 GIT binary patch literal 994 zcmV<810DPyiwFP!000001D#e|Z`(E$mL12JWLvuiMIXod$-(4%+6GBiq;ovLK$;Y? zQw$h}f|Y2Qh(rn`oi;yUe|y`JL@JizV3-6*yd9qNox6VDvn*@Js_j&)on4q(yVr}~ zy2r400E?z&RiDE6%&J)}80*sIVI=kH<=n*q{t^)6AfIp_i8tdJ^_7FS~5t6e`d&VSYe%nUvIZsBI0aGgB)Iak>OoJY9h6BMt;xEYU zwDDTS7hFNwhjzkEKR_4~rV^?vXEHm7S$hCa7v5p__|16K9gkkUZXX_MF!T2)!tM?B z30iW2q|t1t`Qk3-mKuQeby6n@lg~Q+=Xs zoi3gSRH{yh#f`_mG61}AuBQgx?wj7IXAHM+`K_>#7X^1PEZ1r+h#7l0f^8dxM6I|d z!CC>B)kbm&ufjswdx{8wZKQ})YK4`J){H9S(__u%3s&w*aUK8*>I)pLY;*&3ATZ!Q ze1$=3qpwu0gaMim=|#mLt}?D?Kg9vi9fBi{(D2pC(ePw2M%RnUDT@6}N1E&`4F?p* z0{R2|Y$NdUpQ!V8rBozO`h6~3>h-wr`&<0_&e-kcCZD%k;_00x>^SHs4$)I|iXK25 z4N{0;sBe~4tH!DseHjjkgvn-_G(M)GWM~#t1!mFs1Ob1a8m;$haFmc|j^5ZmC(;!( z+DMm-q*`Zt}>akFybQfadW=*eek|nKlwy`MwBAI zu4&*APG&DKAJmi3Tsp^@?F00AG#T9e$7~k&hO#Or9i?oXq$-!Z{oQ8wD#@dvdtO=XlTKOka#b$NicPw5 z*~>{UFL}9X3VT`M>3_rj%aHwCoaW*#A4l8bqTuJ8-|qd8vun;yMZNQSY}VEs=4RHK zr}K$3`?#20UFMsYX6$$*A}mAJGHdf!(>Twa7yEFbO}8#6yMZ>p;3=MJ(Z&b5pKbgx QjAAwZ1$uHj1k?)v0N9r6Y5)KL literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/Meta/vignette.rds b/scomps.Rcheck/scomps/Meta/vignette.rds new file mode 100644 index 0000000000000000000000000000000000000000..a7b7d0778fa83642cc773c17104480218a865adf GIT binary patch literal 277 zcmV+w0qXuAiwFP!000001C3C@PQx$^O=-KaNl2i50UB_lDmOl0>V*qJo5U@$TGK^J zng1&=9C^M?A9#s18nDQ7Rq1!zaX|9Yh@zwR`(O2Y zuXXM|W`D~!N40mu-qyB~j(sy^uH*I<<|j<=sMmwDw?lQk4;t*(`wt$qSl|TW8Y=WF z7&$P?ghWqR3j33U&x_23fwwqbpvIckcu3Em@MEV;yVjo2#Hd~3#V%TBUvxE1vp;r} bOW1fv9-J0nA$c=YPucz(YSVVYZUO)R^UQ>w literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/NAMESPACE b/scomps.Rcheck/scomps/NAMESPACE new file mode 100644 index 00000000..b8f3fc6a --- /dev/null +++ b/scomps.Rcheck/scomps/NAMESPACE @@ -0,0 +1,27 @@ +# Generated by roxygen2: do not edit by hand + +export(aw_covariates) +export(calculate_sedc) +export(check_bbox) +export(check_crs) +export(check_crs2) +export(check_packbound) +export(check_within_reference) +export(clip_as_extent) +export(clip_as_extent_ras) +export(clip_as_extent_ras2) +export(distribute_process) +export(estimate_demands) +export(extent_to_polygon) +export(extract_with) +export(extract_with_buffer) +export(extract_with_polygons) +export(get_computational_regions) +export(grid_merge) +export(initate_log) +export(rast_short) +export(set_clip_extent) +export(sp_index_grid) +export(sp_indexing) +export(switch_packbound) +export(validate_and_repair_vectors) diff --git a/scomps.Rcheck/scomps/R/scomps b/scomps.Rcheck/scomps/R/scomps new file mode 100644 index 00000000..66861563 --- /dev/null +++ b/scomps.Rcheck/scomps/R/scomps @@ -0,0 +1,27 @@ +# File share/R/nspackloader.R +# Part of the R package, https://www.R-project.org +# +# Copyright (C) 1995-2012 The R Core Team +# +# This program 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 2 of the License, or +# (at your option) any later version. +# +# This program 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. +# +# A copy of the GNU General Public License is available at +# https://www.r-project.org/Licenses/ + +local({ + info <- loadingNamespaceInfo() + pkg <- info$pkgname + ns <- .getNamespace(as.name(pkg)) + if (is.null(ns)) + stop("cannot find namespace environment for ", pkg, domain = NA); + dbbase <- file.path(info$libname, pkg, "R", pkg) + lazyLoad(dbbase, ns, filter = function(n) n != ".__NAMESPACE__.") +}) diff --git a/scomps.Rcheck/scomps/R/scomps.rdb b/scomps.Rcheck/scomps/R/scomps.rdb new file mode 100644 index 0000000000000000000000000000000000000000..f527b32d064d5e9f91cc313397ffd5e7bd68b064 GIT binary patch literal 35289 zcmc$_Q;?=Xx2FA;x@_C7>auOywv8^^w(Y7e+qP}nwrl#^@y8$gWJk=*$sFZDMrN)j zGOx__thjFg05I&96}fAuudi>aZ(wSyZwkhUsV*e6=}e1(krpI?Ljem)Bh4QW?;q@s zOp=qDmZ=G248c!=`3-a@Mll7Z3IQZ;9S0QklkcIP|I2~IVAgo3G}g#?v!5NQMZDrgBSIUffX3z#uApo$y43;+Ov{J)Q&%uuw9U7EpH)=aLQ z5kN|SD?E-^%$dIjtez~B^g(1GaK`!kM zrXaS;TkcpYmExw(P9;yvc2}rXLSo3n_Vl-@%QFkp#EpfZc#tqLAyW8UF3Ix+-Oi4u z^eMXLYwD_8ny^Gf_kn5G!gYpx23IAXD!%FsJ|3@!{p&8F4RVQ|kbLH;i)Lz5iGZ&U zLOJ6=Idqr1qoqXo!j!1ZW~-lNKV5gBFP~z$yk=oip|dEZl!e2ng|FHAP7z9RBh#h- zSLR)sgCum4VsFQYa3u1()q#62+4?q)5 zBjYJkw}q1jzA7PiR`gnPtWgSaXx&5fP>EuN8S6bWW6tiP%T$M7ih8zyoTuxez}2C} zLj65_+Y`Fg6WCr92A|vQvs5PV`?|u(9FEe{N+>Vgjcp+7zq_WWJh--9Vq&sJOA+Vw-S8TPze)i{GrzkS)ipWTVl*#0I z!=~N*d)^Et3&&E+)B7wS@@)ZjYQB7gr>aV7^33r24z7dJOg-0w+k6Q9q&uR_PB5CzR*@JQx#;&JZAGy#Pm>&()Gz?krC@WBv6pXMCYc3i zaw-_4WCP)|V~ZB{;#{#aa00kn1@A1Xbt0Ghy!vR{dkZ6?gHe<(%c{vee`?TFtH|xT zevA%5=DIB53Z#8stO|3+9*V{&I|OaVK77@`Izjz{W{U-zu8(k1vafpv!-WgLS(H{B z+F}PM`Uwzh2ymZkJTEO5;Do3*py!B$;&9N4>4%c-$=#zN#8K5HtG@W^c63ZjxvHK$ z6X>eR7)GxudyNphi`zw#ZjHmwI?7TDV&L3b$K5vG-_-Vw{{=Gg>i=kI% zB@zSZ4`7ib;XE2-jab$1)bz>lRYV|zeAHDKxi@O32f?YXgfPg1%gUjHy*@K{b<&Arm_$=Ww~z@WiQ#sp zmAJEE*pdEbmySMu>!qky?!dSQg8=X-^U&$xzkgFLlhkrbM@SJ=T(?ry0-H9^KSy)6-WMwmWKFnzIE z_M4Cne>NwG_`2icHo4qLlhC}#I(Y&K_IQPorL>$c;5~s&X1%nN+%WYe3;-*$8l5)? zTr@7yo$&}az$6|Ke-lwF;fEz4kDTc@RZwk3Da-=*w&nMrH11f^x7@g_`3S+ff3LIM zD8x1(Bs}`B=4J}I3o*z67f%ja2a6QI7=D!B`!f&kAa%=_00sSU1;u$BsbI@$l=b()Yr zj6ER7By7}3=M3y%Zf@lzjA*OFuBqcgu=pZAP>He5scLCti`>`{*ZZvpj(z-fiJyoc zCn7wAJ0~;k?bFcIkbWeU(a>0nq))pM1GB?&^-3y3-dFxQe^1HFvp1AAA~4o8yJh$gGXtN#u6=w zrhrfpP{W-%GKG}y^CE)K5J~-0fY;+T5Sx#Xc*_Ot8?f{{VD&~^ume0ry07k^um(SJ zj^5$=XsP(RUp;<$P03xxD8^-ia<16T# z@W-Z0%M<|`Lh4&o#SmQ{@c79>tLpi<%YMz^dhO%1yZ zQ3T!d6l;lY+#NBT+&UV)@PpNu4Q7jkU*49Hz_bLjXjf&kdvVUyz`;Mt+aI}`sYLvX z#q89uD;+45QVt5ry`fKzW@g>#JRFZRkb>fIK><*ZA!oTHp9k=AYOWC8g4DjqALs;x zNTnu&?A1xrFlEK{>DH!94LMV`HpXnM7P$cLa(=7*N=1syHsmhFf+jg_t4UiH>VRf` zLOQn$#>P*FYjN6>9klynYJcHPuVSm=3Q2`U9*gq#zoKs_jfUH`V54Rc0uek?e*45C zY(w@{#DvIAy9kVWkwAp_6oM#1s(HJ1G}s_(6r;letU&c3vv&BGowc6@;z~HZOeGDe zhA9R3<3O`pVhnK4A$g65r4+XQmk^6$`7;EgF@$)kJz^+{D6y12!Oxg(E@6)iypX%R zK$~X0+dv7(4m}{;#|STA6zKWdz|#{1T=36o+K;CEwy0-Qf^Bd%R(WP1XKTReo&*iB zj4$z%AaU*xo%8ZLf$ubrTfyBQWjDleUr^&U`7=hRP878xUY<}#Ed(E+Z_hY6JO_qG z(GRZlqSW-iRlW3(JZ*jC5DA~X$cySIl6Jy*>Z(F|@)RgqV?iB+%FB|SVv=K)D3Sgs z2zh1~@^IYw33DqiQ`=>O0;|Nm(NNS)=P8+WQaKcL?1|eb^>Yf!;_9eW^ITfr99x5S zIYzhIqsEM95l|4F6fCbET5eF;rG6u+^f^V!EgD@aMnlGNaq{go4#uHX;HA1DuWluu z!e?ewS0oHWG`SU=8LoKvIf80O(W9TA%w9OL*qN99dTenqI=U@|4)CeplWYwoAC*h| z9eyxQ_Zv4J`6(th1L4AjFeImR6T&FKpn)ixTVm}{qFt=C?shz*e8cHvyk83OWKn|a z&$A=vhcPQrN_63iA^fWfawntMJ=lQq#7M>#9wM#TWcx_PNy@hN)E9Nmi(}5q+k=-d zGZmxWme<+KsT9^n!o-7TF91>QtJTtY+kC`S#PuB4X4q<$xCRfL?g6Tf5VG#~)fQ%# zrK#-G`e3QfJU=B+Nl0FfwdkMK>~oABnau=wD13a>ad)#5NT2Eu8sB(BHbdg;!4P-D z!a)x5k+6#_YlN9x)SZij;ZyfF<(jNq!kE=zcC}pl77pSA1h#1@QWZL{S&|U4ws+;o z5JMI_$C#;K7um<>OtkCaNz*b*N$yM&OLi?-%>^!o$3BH49fPwtYCQ)tvtB9%t~nKS zjS@FRYI>F|^yTqP&|+dDa}WsX+?O1>!V|)s?a1y+%1q?#n)6v?!E8E}4nuz(=4R03 zT5W*sNaI^LE|Re;HtXgmgDl|_2U9KM3 zx#yALS*HHg5%HjU?Vx(yVqL60sUkbrEoO4z5*h~1q}&LvJwh0@JOv`bcLcxRjS=uT zh!k1rm_s|pt-_ea^c1e3%EXEN1zM-Kh)QzVG8n&}%#K2rw1W~A&}DM}0;8J`Tr-zS zV72v9$p&?yvgy%bdr1#QRwqmLV=ef-H%&5i`%~xd2 zNqt!7BKWf=pP)Yskz`;;5~xD56LdIG4zEktp_g!W64-x)hP7aA8@oe%QK!KwWi~NA z%>eah;tWvo!8i~_AYS(T5}0sHBE|wYT)>&bQ39^&I#3N@Cno)x!Pb! z&tX1=WcEK?nTJFqR{J?3?G@n!<)zzr(hQlKiMDP7sf*AV1(}oNPTStTh!&7)*20WL z-M6ASZ&^gW|50zeIA-4PSKlt0p}fW1X1DCt;x!9<*jZ6;_68XW$wqdC9B2Am6K~WL zbXT-R>XR7j#=M2S?dm;m5#X*$lt&$FVOnXE{ft#p_oK*Lx_f7-j3bxUiSqhfs1Yu)?fUsKqd?QPtoJ73a!1BMbx|Jq}; z(xT3dxB6t$spX=>4%wXeBU4?S*=RH5QA8%@qH*bpSQ;zCUWd#WfRIc8cPgmgVT3dr z7$;c9xq#*~x& zNB0oZ2usQWvZQz~zS!66`|=JQMpgeF{lP~f#gGGoDTX6kn}eD9slDsk{iSi`(f0n@Meqj4DNHr?gqJ7%sCZ=s(h0wj zx_=@aV~NRUkrdbx`GW<6^`<;0y| zBhL0FJOs zev|Z1mlkc1a=mUAdY3lV2+XJx=YlX!R`3m{h-AEGiGfHkA(ps%(O8fP zF+UKOT1}B{;-&Y)O+M3Fbf?l-5T?{SNgX)MN=q^mXChA)*^y=_L&%Ifl&T5DykXxR z$@RQ{gKuHVnjLiejQz1~n+3eTUl6u9yN*7Ih|Rt=K`VM6o`!s5vu*v|nxf89IU>My z{!Pr43pw6Upsl`xuu|xl11llA&u_y{j;Y!m+|d~wO%I+!MTEe192Cty6N(|p>yFge zn8Y54ATjMg2XoSonMP=_ku(Y|a9@yAoWQJ?!iu1yD_eugEPc29X_Mi4Qj7Yg=B^9l zp$YLo!`6d#=71G(`@O{v2=#QDHlX4?^hdgp-0Y{U~sow*wgQtGt5Or9AS^@Gv@cf08 zs3wh@V9VNlQ`$Om@IVxm_ThGX>&DCBG~i{wXreNjJsW+^)u^Ol7gs-% ztD%m1Z8eeTe3OaDy0S*>+TM7`*(dk!jPmgD^<;AZvyFPHX`3HL76;xwdn+5+&m-LKySj&}&d$#njV}`Z*%7@7VnD zsy$A4OMgvGUP1QUqGNa6`)5XZKbt05;TS5!TRuqkMp_mFu%5D^?VsH`cY&Vsjjh|` zKfbyVCu)j|dWCu{JGSw|lH9&%V2TBAW<+m9<3%&g{>^Q}YQIuAd4ED=c? zP?B%Wf?dnFdJb06lsc{;>jr(l7F7@VxBOCEEuyq(#`Vpj+g|xJ;a*qojV$I@6^zO4 z>2_u##b=`<9(1r?g88=<2sA;1jHmRq4D0mVnc6GQTD}y%8wv=1me;w%Hi>2^W1oPzu&0SMT^J)84%gik? zqwBTI@t^rh=_Um0oi6S6=kg*^Gin3qh|jX#j=9W4nMU3U$1xhz`xw(qBDG9^o-ZOl zajC5cgXjy()tJVb`AMWc-~V&Z6Z<>R`r&G%AWTCX~D8aock3Zw&n(w z0&S347rh{G7u8YTMh>e9Z3yPl2G<0-+W6z$^VeNj;cS?@?(V3u+wN}h@5QynzkL9` zb%5>YygKjN`Spao>7NUG`%^G_1u{(6^$Yo4<4%1d;1=aSIkNIWhT`FSH1K5`*>RQ! zjEiGEklRQz_04_0t2{Io5kTJM0{ai8;SY6E1&(Suir^P9*D$IupILg4Dywxr1ug$%7dWy)QTAqX?cdpwI0eTnr&_5x zZyFF{lU2zWr;<{)*^WPM>ziM3h!$CK_`=$k)h&X3=F=>S07%JgkV&n^=U5QydR-;@ z_555ImEAFGFn?*C`CCy&HK4e^`XCiu;d*qs@7s!8vB>D@yx3XY{aKEhLE91DCBdkg z7%Kfp%&}FL6F83-y1IEAIH}p0&1e1-+nLUV8oEILxf>yhqguH4U3X#c%6@0|dC0D< zKG=ONojr^B-nZ}WF!PnDzptBR&Xe-3@vPDR-d@FFOU}NIhd) zL{I9iem_3`MPSfqxEn&=XAOJx%k&cE#+=mxWW%UpJr2%Mqd{KkgkXu)*>7UK3|I@5 zl{2I4x{zqk77kBiV9B6x>fiQ)hn+~kb<3<~)Ux!N1;m~gsBye%);6t`4|9Xga5d^2 zF7R6wG|i%=G}ljhBEB!8<|VPVTWBn238rP$0w=8W31eZ*_L9?n1=lp){&*gN3;VFF zCK`o0*_@VqxZ|~EdG2d@b7ZzZPVCdj?iFF)0jwI=ISXf4LOK_Bs)P->*d#) z+lUmZIF?svH?>D%NyXHMDqO-ODd|&=?yrgaAJU^5-?1nXa3sN)-rE%OJMNCNU>D@l znz;vxu*G;xT30nW%sP%YbXs1Xr>t1km>()HwF;`lcNIjqP!Bt((B$+dkOv*R!u0hb z%5`R%b2;RX^~h9GLr#u!q$IH&>jV3XA|caZmF+uEm-^4ShqlLCmkHe3)6i z|HiJ}kMbz*QyO({-?tGTtS{fM$4X!a+K7z_z;nfrhUu1v7+RrR&%T6*J;hOCG&69Sr6 zC%#V}O(5c;l48(Al=Q;urF#XCVmrCE(S7IbU;*;^l~j3_hlq`OzHfI&Z2Y356MP8T zq!dEgo7B|?xpdlI7g1sdbA6{3cdtv|Za;pNl<^8+ZR?ww+HQw?lKPD>BRmdW;Vjwg zO847GZcq5zpPvhR6@gzhV-qa-u!4(&toi894Ec0lU;vOEXCmAYW}J%sRWelZQ-*x9 z{1XZ*KgZLoKVCU=UkLLKQHt<8s7Wd!8azo$M{ZR2%W*3w)|I=uej8=?sW;1hcaZ7z z;l*}(j!f>d6YNaUuH=K6#I9uGN`^&CrsyeqQ#O&Aa@WP!S+2n^RxvYUlsls%LRKdY zNto-KxEjb~B!6262GXWdiL{P6P*)0hRC!Ww@PAeVln7yv(@<+D_mshLNuqan>95#6AL|=KC?%OMTNq*d&{oHk*t* z&|^r`lAKe;D~dy2PAN=6?$eEd+3NZ#2-K9^?CyXfptEQ$O`P_=f9DpCFPlQRh}Ftu za6>w>7<|ny=iu)l&!nqgPr6J`oo!{IHG`%mX6%l7Ld0b(a1=OwNF=9|y&&_NIdtPS z%gi`ug%gNINBq4vggQ-fAT1e*a&-!!zHHb({#SY2BzRkBXJyeDNYBk+?*ZyND;Qk~ zeG=Eo@R}A{GFmN)(Pw#aWOpZ?K3fVlTBy$6-_R<@{M3`G!Abt1nC2l#<=)R0?r;m{1esolspNvZ8WN za)p(E#c%3+je1XkR5F@KwAX@=w`>zeG|S_BjJM7oPXRmq8}zg>#K_rh2EyCFd9LXX zPGLP3MPcwmCPiuJyX5GNKv?6$IbR4sM`?9%mh~;*Q^qKIo~zE`!%5O%FC{2J_-D}<#Lxy>-iL8Fg`2yk3Sh>DZYY=IIWv%NvOgjQ?`>v824lJJ&ox;hl_rj=eU9oJa zag|wLYu@yV_lF<26G9Q+LyQ~pYU;9^41Bbhvv#Kq$JnaBZ$NCWm{c}QCMMx;FY^** zjIcLNy%0SKC{Yx+HTzveZbdOKDTC^F4H45;$B%AITL*HsjGXCbOA0q+<7_x0R zBjOE4@&gPdnQsNKb2OLYUU4bGm|k^J0v-H%^cLRR-K;J?7gu`kTs&48nNJg>)~N!h6-`Lg;@^ zvtYf$zN4=5dsYa8I$#v-1oG`&!6YDiOxlTZLwk_eJvQtNLr_>T`Hp&qR29Og!TL-^ zwSfard;Y2+pvRh%LaQ%R zSG@vAbUl^yK-h^OE=R4X%DW$Pr=(QEo!NNFE`}Veiw5WC)_Iw@%*>X#z6}rsl?(o& z7Mx$EobGhvb$to1Vn5%e4yFn+8`jU|m3}X!?f+f7dGZABa{c=L`1<|^dQe#1fKvB9 zjII%Kd5GPMF$grs&hOi0T*PE8g$v@&EGIbR2pqn3#A5E=IZo_r9={Ff8#M209s%zrP}RrCKdTii-Nbx;7C$y52fv??a2x00YIoM@=lyw7HN6YH5~uxv6sAFfj`0Y`+sYe=&}J9$8;PszAk&DQNYcaEcx zvB1qKwOO7lK}_qhU;u{hw>&Z^lwifYHOtvr7Pnxq?0`TVX)g4f8pYtg$@jG6CAiZf zMuqBwJHL>cGI4A{J5_o^g{aV2eM&Pk8IoPXqfe7+)Ar`&hVh>@IbW>$76hGSCpGdl z6?$N{PPopjv|%~-r-%Iq_Go7uspUD6Hx}C}`ph*?4dn&h{0wmL7;XVwcP@+VX=r26 zNZuV|<1XO?CK0!hOlrDY#BjDn7i%V)W^OFIA}moK;ro#BOv!oc#1L(e5!9RH+m_z7 z-N}S+SbG`!r-W}Cdt7^3#t#jG(IL)zm2ifwT~zCIh=-=)2nZYHl6^ER0ewXP?0$!! zJ_}xQxc-dw(%-M#blkY_EAB2Fd8%OB4z`2dV&_B8$5k#TJMm6xJn<|%Nkrr1_%hlQ z^;~YnrLPl|{4|rGGbxmmYYOfR1;y+->pw4MhDb*c3JFp=0Ag^F&nX;~yPA`{Fkfo$ zc@?USN={BVP~yL)(M9kO)P+>Ra1h_hrr7Dm$(ftK|4!=`w6BG$OzE5PaU(k4*M--q zIO0~Bn7w@)MfavCto-X*Ne`k+Mx?fcc>Fs8=NCN{WVnL7_#zP zcubT!QM#%5Y;UFvc{O?-2)S-{J<7)8W~N@u71PMGcJE*b^2WneY=gn={PXnhEQMJX z22oPt5N>B*l0)%;Go)OeDV6gVFuC}-nylST>;)Lj3`K2?A=;up{e`3+a}p6NNXRo_ zP=Zf`wo8MX>N^6#l7acTWVw(EFBF5uCf~rM&z~?X>)lIU81ub|OC(|n*|LnXOU?aBq3U8&hfocEY@SjuJ;wV4ZlO8zu z4+nYNWVJfU{pddFzoPlWy{0BHu>#NTtyZKy6SJkZv(4eryN2y6GRMKLz`!bp3h`U`mVt0OrVll??2##87f{dTaHs z*|3d92)nul3ncIh%2ao#M9S~u8dXfBMEq8sG~ozRN~$wLKMy4ji_48U2Ydo&WX)VP zP{ef47U-R9cXBwmJX7@Qqv}AV$Y4^$?{aCL7Gih!e1>14az6(;CyXUb?;Iv@V|Jvq zC!w|qujdvDYdW^ZH1`;fuY$yojG#*yZrf!~qd6W=moj67}}Wp z?nS(oPbM3BDybJ6_c9ZIgN+ikX?#Fuoq*uwCtqsb)^In-fgf!~9~UqVtsoj2<9Qmj z{almPP)MVVDZtR9XqW*Maoph=VcK7lu0e5c9KFjy2PSCiM|=l$4v#(wlhJj=3N`Hg82wd`7yJ4=g;+Hu#X+o zrw{7$7u_iiG`m=jcjchg5EjhvN|y=r{tEq{Ns%a<^DeDyAdJ7!zS2~(Ri4T_Z>d9p)!esAsThJ*%k#x0#x2n_6 zduoA|fqA8e4VA$99EVN5thHb!#mft*A5rda>L2&+ih(<=oQH<(T{&0{A5_$XjB7H= zHq+OsrKK3t&@(HOi*dX!)(-hbSCGc3g@riweWcicyRDrlT?Oo=2nRX=I@Uciy0E7^ zhp-VDjTVpsjZdD-*6G~{UOmRL^Vwc4?-&*Zr~O`!G25PW;f8eqdWHxzIUo438))cy z8smZsP6J)yPYoEpcDp>KSB}0f?#R6w2#xS9AJ;J?&b#Z}FN6U-uzD(ElUHOPpCNTI zUf3wIVbI|s@&@DWmfqOzeesX#h|XniI77#Q1aVzhYzu-sf7ic@C+*?I-yd2$y)P=+ zSh`O-YLGhhHRMVgf3ojJy%{(gh9dVx#T?$KGKoVSC`t+`uW4D0o6bvw^Q5H>)452F zZ>oivsmZu5s@JO8X)%vT3yO&1AO!*l#^rv4&WB1M9MvEIp9LDz&+Bo3&VyI0cl2E~ zAO1G$a`)MbCL1nDI!XJ{AG2~<@MK<6(F>)N7U>%Uo@Dy@F~cp=ihBHMVD({g`N$o| zp)78Uuv#GcDy!`H^rZ8{1UiaHe&BePA>fK0|3N6Xl7al@putI7g;U*T+(hu*?w+Ht#2b;BtPVehZ0bqBfr=DIdvC3`!fo zS_^%Nj014oCUfH_uqpl~yp7vcU|+7u{{g5#nOp+^STg@IT6HZaEH)Ihj!m22|6HdU9|cvh5{F1-<2vcMLiZ?Lc%Tq|`Tt9Q@0&Nt6{C>Nh9YbHqgtTjtj z0ai*f=~bBQ{CkIkbKdfeLjqz>LLDBFryoz^a4Z(SW{b=^=+8Idv>dTPg1*h7rSo(< zn#Y-CvF2LErE(c?Z$ zDn>$_9DmG)ZUAqpmfsf2Ve1d@Omyrdl5u^UMu;@rJxA2lfrgkD?JA|;0@h_E)Vp>K zX0N(N{>47=s10;GzR_iUo>ni$%@5Jhjnb)i$g|U^ zZtymGfHjy;MO@qOBf3a;)o^3*w+)k5p*~-HmuJv#wz+M=&lW-_5U*>37`|Y3;UCh~ z4(Ojy7+*@qA5v?4$nTrNFDR!Mk{(|vpEvfJr_jN_Hr?b9>6e+aH}Z$bH4JCuWlb3g z#^Qv3SEhDI6l4gon$EXuwNjQ*=l5JD>cKR=*&m<({Kd!YAI83UT{W#VQJM7VpbZ<_ z2Tm?C|7MxLlv=9i(it;RP3w8;l8Ba_VZV4Rn=738sKVo6T}52xE4)-UmRo$i9y=I8 zJqTs3(pognnjdbEoDVILPF;wgFb|GFu@J{q%4D_n&>r|pqZvt6X(C!=x#e-NwjjI1 z{j8Bekiby0melBs%w}XejY*dt?m1-~K-C*7+Fya6n9BY)Om`zCAw7lL?8}m_EDa4M z$B^!vr@!p&V`V*5X+f}=X`?=_2D@G?MV!DB3AH8Ll`C7D6 z?(2|iqbZ94IqmA+R}|F1rh7j(|N?$ZB3=FmmrxPK147fg)yn5l&+*ZB@2g2 z(=hG7WWcgezVt13IpVJ#S;JKdC{ONYfG`Mk1dbVvi;ZQY))v-+aVWgIC;9~VKj}qQ zfAn^lR0$85*8`A|K0EfN`F#7)hOHw~Xp|=FigvK?B+fI$ecMrU#{;sPA>j z`=sjjvUif)z<>9?BE;c>SM`xWY6m9J=n-uX+Qs({q9B-VfBq|;sXO6`ZgvLC7p_po7nZ?MlBiLV$WZ5s_T zTIb_<+K8ozdqqJ!nag|smhhRIdt$`E=s}HS$6#{io|?^pwt>7%{E(JIOldo70Gf>q zEC7HuOwjJ%OGW1JOKfG%n!C~8H=Aq154p~&P9W4y{iU9WDYzv3<{pgI&wJuRY<|#i z7Y+mV#&JK^?qXz~XpTJnSSMr*hMZssM+tjX_FTRhE z8;?WBgsktt)rr^g{g$2UrXi3Gp3U4y;7n6UWc5@^kpsOIzKa9V%>Z2@-2tqo<5f+; z7Jo;K%LI9HP9zjMl@5K{e5j1!o%id}GwWPRA0b%o4&$eA){mTyZ_Tb8NWW4ZWEiA4 z1wvwN8NVpMsy`}_g+AsekULNXko{AHQY{CV34Uw)hLZgnc=a_Z0o~p?iZ-%655V?& z^C!yHPY1|T$=>J}4xj@``-gP*w>`zKIn*`SuGOx5Kkjay$n%n~ELm3s008q(H`k@2 zBex)r!TYtj9&OW)5mqn&-D#M<8%&sCE+{P>b|;8*lcG6YTjyMi4>^ea{m{xlw)kRg zw|16KjxAt)f9S4LmLVUxp7n1`oQx`F44HoB8>lsqt}Im6J(b^xxf)m}V0E-5 zZp4dE&~vzg&<=9s*S!Xw9D^zJONQSx&IhZb8v6%ajMbJ5z-k{VUJ9a$9R)oqq>@trw12r|ndxOvK3zQvq}EFp`(CSc2I@*iEi2=r zgU)8poyOh1ZrnSs81k7m71_-+NJaS+<38azx635&PFCqpT z+I#36Y)F_RaK`?*k=n3c#Z@GVOr;b3FFf}E)&ew)Kfh^+(n+Z=uVQFiSMmdpwaW5U zo!3zktW1zr+OcJ9W6~)4CMK(}-#lC{fXQ2q>@ry;-TzK7mq{_x6K51D$ir;@Rzh1B zNWO|Kb^1lE$E3BKt?p`-VCZUl@P;CTL1)7R9Z;vF5DouxOtZ26opdF)8Jk zTY7uIpuH2mRuih$Dl#(=HeAOBwJ+Dlz(d}!GmnI(I8tygSnG#Hr)BJKH1hs8;+@!ewbliasf18PaU^Tf^r;yE3>4LnpDxBQRu>{jtBfB!O zW=K_mY4%d1tV>Y+jNstJ$NH|Z+m`4H<~fnJ&>?EuGu^3H=j6%26BTvvGx9R)7S`HQ z{n9uSkO}9K?}E47UpF1h*LzDPmSd40{FWsJ&70;!cp6#ofYyW7d4yYW>zSSpUR(o&t z&v>|sorAfskigpA$;TNC9s_Q`jyGTXAdMppt+TqNbTv?gxE?SL;M^~oGCQuxB0R|Y z{@$J$Xk(LHANtl&(`38?fLEx4dJC*iyd#MB@&$3lQ4`Whii16R;?6ykM!RVR%;|Kw zF{*=j$;DnxXoh=>s-^E-MbV#34c(j8c)1p04U!3T9x8@&oz zGzg`!6#LHCuAcKqp{@9gAzRUi4mo$Y9Hkc>ec{%OSZHY1HF_*(luIbz>8;t!?@{^b zBs1eA~D{+GHaQ3 zWz@QBwm48vY8Mam2>)d&UdaCV;J+am-7$^V~?>n6qBe{7`wV?@)7;ORRfW>5H0 z(1~*+_VXF*0YS}`nG>rXy$US^Fsss_Kx+k;4(&Hg?H{L{A|uGbnh)G)nl2%+on#PE zp^`RG+0rqq+}1AGpCQtqKs_6+1(Jc`L6Cs)LXm*h>u}Dw0_*(=H6|vxg+STD9*W@C)|b&oY-R&B#$aqL>#gU9`rbKMOPU1#JjzdPCfDbJ=E8hDX{S6T z%TF|tI&iPf^!AjtF!c?ImUtR7vTgw8E4<;Zg}{df76Wzy=7ai#!v1g@_U`tVbNB82 zG~0V1z5fHj#lfA*>tbMq>Rn`uTgT1+0cp4ncp*IS`Lz){ht}&E#BTCKv|d`No4L#5 zKSgW$;B?!={{g&tg2fi;nVwoRmP75hjrderbVrUvjOr_NCJK`linVad*j9-Mf;U)Z zfr^#wkv%tr+6j6U&?GrCDg2v-O`w#w{6YxNfJ7K0xzMpf+hRqNw+;qbXqB3rOLl-~ z2!l0Vv0<~`Qe{eeumS@d9E<6^52tROwnBq#<2T5`U6EVuhWvALuh2sgc4nucaq70c zM0DrjwL#}+PpYm4eUd;=zE>)EG zIw6$VxesF*i*kv+24<(S&=sZnt0|#rFLDw;M{_*5DeFhe9hzDV3>S%HsRkv^_$MHS zS=fxj%&~RKY_vSH?)R&>I@>rLU1`vVT9ccwk!P&CLxkX27E6_~T{g+(hLyArHl^N2 zQ|*J&67FlnVE$J&@Z{kGvKz=tbVbUGuh9?#WUF(V+&#nW7lyQmFIH5 zj;O9Nb1`? zIi$b#WP#{4P0Hdbek^s7NOtX+;V-zz1&6&|j2A(r_Bf}B3b8^x389ctGYxGSoEMUF@ zUl&!h#-Bnc;oVBYFpCh@m^)7v!B(6}TIq)zDW((N6cde`ekAX{;E>dB1JXkMm+CM5 zXagevuZbHoKrUpEDdYs?mUIBE);pWyovx?hpX?d{B>6u%b}{^j_^0K5LFgO)ch{~w zUao(Re@A32U8#2Ix}5Ks!^^V0FDLmKkp8X`#;gH#)d7n2nODU6_*1NKGFyW zr$%OpEu}*iNWKh(4WgKX5@ehoG|`AgV)EsdxtR`*!vLvWFAGvlFSY$ri-R44;y~0_ zEDu-unh=9wv0MY!&)LTh$EDks%rC+ueodkfBnijJ1U=uUv1=h=kI?}=bLXM>5L1cF ze%cPt;62KXGPd*3r!Uci(>w=zaqImewqfV!ZY%ZQZ68{3lN&rQ4!M)$WF`surHeZYNESV8(G=6>?-X$NIX5Z7=@f~QHp zKs6%rKv^vUs9=HHneyaJz-|R@nDW@*uYgZy5Um9}aYpY6CIq?9OQmXMYsKY3mHBgz zm59}eUV*L6C&__FSZ+I@aB>}SB6oXaYJswH966PDP#o6+T(Cb=+O(-=OR24Q0-oVc zRX8>}{BWn6L2=F+ig&%?y|_W>w|l7EdSD%{o$7Y{yTPHfhCARqIO5BJwcQC@i^3ng-4is2zw`$&>{&b%kcG5l3wBDK`Q` zR;(l@VA@(G;!{h;Av>Ov9#JBd`IvuZt5qCypuZT^*bk&a8WGjcv@ih?EKvBOY&s& z`Tkq`$SW8go=d@>OHsuoK}IzMkD!(>_oA0dUKKh!nows~cIWyB+Y-DidA$?_FKn2G zMW*^ip&-lt1yK&pEE$|8KErLdjy;c# zWHFe8OrPi`hWbBG^Z=fpdP&)j!aRBTI0nY1ZQ;+Y3!@LDL=t(pRx1} zA#Bkqp79AN&+<)3Y6GA#nA9c1>Y;Iz{>8B`1`~+7OiNsH2QpDKI*biqR)iSK_zkBY zFqWZfbc^uhut!5BM=oIRd5vBeLvf*LNOccOrW&qt$c;~0gdmh>)XqP2)J!g#p5R5{) zIAzi+5|ZpZLgl51{7O^g7lT&`^}7h|8nhb{-rlnX)mjh7ejH_eitJh39P)lktU}x> z@_tKX-(Hf?$6}{}+a~hv*kwrt!vPVfi8Z(J@fL*|l1lkaN`GYX^x%mpCpg93-85MY0AFsv%DB48b`5rA?4bP1Sk zH2^yjFxwiSAb|0{7l8W#cpw3@-3`E=1kCn;1LJxafTI8$`+)g)6o6A7FdrXq*atj` zvVQ*oUPRdh000q*c$~#nOK;Oa5MIBMIPa22AH3Y6Hm6#lP{gJGIb0A@!)`nquNQCPNGY}SX}#W=Z@!%wul==%5K@q;NJ!D}Ez-Vxet&$1 z@Dn`wjiO6ND$?$1RRfmqX}aR#x{)Gz}?{dc3^!E#>X%|!FUe$1kYejU;x)H!_|i8RJQ^7 zJcNARL0{35NI$`uEc}ASG(&mlaF&vYa-TDl1%~S3&^=^qNf~FHuObR!B^?FrCp5`j zP8?_cjv&T@9jPZ1UFX%QqMZeyH(nC`?45r#8QE@VbjaJ&F@k|Nx$Ya6w&A%Lj?sZF zbPUfoI+56pSg1BKa;I$I$kpX99Z$txt+ z%j`PkXYF-?M$PSw>>%l^q=`!tSrm{;Z<2&@3hkS4o{m1pR1z@dg73r78ldz(Pia{~ zRu+)8Ao>O799)1;+TNMDyezRKe{8N2UyH>%LL^lLk{Ss~3zrOnXa`Y2REWme7qS+! zDk_0*hZCPW4jO5!67=B|Y+ES)43L^M7tGPoBta>uJ+@Wm_P4PeAn_&Ctm|Gt>c*Z5 zb^B)Q+d(kICH>&`?Hd$-Cs`47hFFE*3Oui)_@80XQ+zo^YULP2?cOY-z$u8C#@VUT ztf-8zO&os`oFs%>W0IpW6(U+bGF6&FUr5kvbl)0RCAik!d!ErzMF0NC$SD4yIbu3U z1OEbwJ1;}WsWZlJMaN~{2aT&k+&$oFf`0N*?=V_uxQKo__to^17x+JdrKylRvimTm6Tx`EXc`IwyyYfKw z{?BpM`-n?<*Qxu4<7;r}H7I`(#%dgEuAz(Z7UP(Se-82G70^)pKTlB*AjhG!1eGPI z0qQHzSQFH5cLShY`wR@g!8*143&G*Qn*ab70(hLwR$Fh|HW;PumSQ_jnyyLOBu?+^ z#qioa3>^jx7%*TMIuz&yeJfm>u7x_XC&_4vz2rZyFT;R(q;yzQgk&j2UC+P=>F~Rp z!;hrsmmVR+Af}-a!(y+*dj9O!`#%si!oWWy{prLcE_>Qhe{wR7fSTP-xAU;`UAO!F zgYJWeEJtUfnuwiF{2-3l+rNs(jAr35XWR~Z1Ams6q5FfJQR~l$zTx3bKKS#CGpNmy z4QD}L#wWBFsKjq+7|=0$`>1%_*S%oy&L701)S1{tX4}jf%-%DrGrN=|5ps~UlaM1$ z#q4I%z4Tp$Ct;j88NHsJH%+kuYXnf-{Ca2=b>9wWDf+--1Q0Nw$<2>cE3 zCE#7)J>Y%d%fMHF51?raH4Y_hhtSS@@dskWoQ{!uP0@8-(RD-7byLxGOVM>((#7pt z;5zUf;Jc`Gb&2i{){L(|A&U*7{e?+!#|Jp`0^KN{O#NXniIE^2$G?nd|82WJ?nP01 zGHk~q+V+F#EN-Uuqeqe^+2fqhcr+PA1#aDsF!C`Qq0g0!mXzf^ zo%Z4vv>#7GDO;_=1shqxby2mv6X}QHQzy)VnR|ZJ31%lW^!r)C=Db9jRUl3H?E=O+ zW9*N5VXq(4Fw1F`aXKZOwI#D;8-u=48SOGgx1gf#50yx-AW}P40yhc*on$G-9&IHX}`IPT%N>QF9@f&pv* ziydYHi`BP)9bgAotX1inH4F6GA&qBYke&WsUbVcco7t+n^PD`>kOuqd21!CYSU;g}pDUJbRi z)S7}zN9X0wt@I67UFr8*h%+H>M9)vXnYq3vWU$A=l^U*$253lVk(eYT(QA@G? zrFCdH`X)-hCeCIpI#~t(5rUOx@XVNe(rXEdDeaQociSGs1(@FrXy?a&~N{9Gm5jY zhl26EZ45>WkwrA^%-yJ20oi*dFj40NUVlOmRwahZ_Ch6Fui>2G*QY~nLa3JrflhIm3bUkn|NL_#E= zVNOJvd+{QIRh^r*ZA47wX~>~z!|0c=RnCR}k}6okOe{ZH{IDae*~KN$;rwFnVzwGUwBZ%d3M0X3tCRqcP@4%0#?aRp#W7>k8K?+DTPuW8M?IO%<-v zTEdE#KA9NyCC63cQmn5}arI0Fv+<=JmG8oOYfl$= zap4#ZuHRfA^H!9GlAqG(FEb)gi|e;D1}b{l^v*8@ap-41$}jiwcjSS~u5-$EGb+m) z^d)wjh$tN{%3kIu<8f~~6hvV`T){Ytwok;bv-D4xpvV)T_x{YD@ZPVGbySOG97M>- z+va>>TVXASqIXY%QeA;<9dPZ)Z=(IN;VlCkzHVO3Y}0W@Q_Fd24a^I&x=O}~P*R9EbrZ&=_6;{#{QQ>UH(kHg z0)7ImDtLTw&R>Dl1hSX3%4TJ^0$v%~qCjqNp0oKvGQF~k>^G%1LEP3h;!1FoGTyx3 z-wXO>l&=JP78@@?s|o6fPVFm5B|&OS36*bKQf(V?B{_g+rYINu5JR% zw}x_QkaRy{RkHdqdxG*W0(XOicj{&uouRA5wiLEFh3zy7@f{?=a#%jL)&`eDg1C3L z5jWsz08cIkF`rC1>m>VP;QxEUi=zzn(n)x6?2;6VV|5J-{(1+~_TNh;q$Aj{AZfZyHaAc+GHK9|U#PQA{~p*R+SieHU@* zH>>SNYW_WU2nl{Ruo_pPJwTe?C)A{7Km|dIK}~=rLMsOP8tfw+uE8CIqZk~o!2^Vo z7(5c-Cxpj(^zw|JbzSX*z?NE9B&c5aPxchd_{%B6(`O1M0%koFBB z@eUGik()RWNSt6N(C$hr{&RU*t%RA0kCWr+IKDK2NS`J%bIy0Zb3C4zvA`?ZH zh^*4DM1A|_)uTTN9ig57i1*15g%oI;b-Lrx#DQM9ebPR8cJid%e*U!m^cnTZ&{4^^ zos0+8)S=)0=VlaVX7>f-S=;ChW+IQwpeGnrKRf1oVSxV3>f-*$G%P;YC)2jfp}@Ov zYFNFmgWmLmH%Wd_=oHr|G>VTDC5qPEiI7|K5_+vdaWt=(XMdfAf;LBSK#_-j0s2Mo zVfEjp*a99Ae;I5w#9xK63i#Jn_&33}f&90jZNZ!lV>`gJ2WW!NA;mGpKJpEVcM~`d zP`q2v-iEnD;JG8jT^WsGat2#Ap+X$J=(vW@AhS48EtBec%1(m;snOJ@@|9NKg z;Pqk5E+Xa0StfEYlafos61P}YI_BBbw5A+|!WBmiQkFT&N>~V)vWrWgMP-qVnMH~1 zP@S$lo=nUh$C2aG$frz0Vf5lWWX`7%l~*BVUYcc$%+5TyFUF7~DH8EwRhg4RE-PH6 zXe&{rjcG^lHkG(aYbh(8qYK71x*>~3=iDL}Q8{L6O`IAn`e=NwmsOR>5-#pN^U zO@`-oSiUpsy*-}c#f4+kxPEyUr=wPN^(w(3jY8LZY;|C_Aa642PX@Ul4@_aRuWn+Aa~l&eFd@f;>-v-un}K z#CyL%)?qD{u@@pEYn#)VZ3VULi{3p6N_7FYRlubqlb=`~mlqz*{JFDTgdIg}cWEv} zc_*9%$Ea^lZRNTBx1}8*coXdojrlUb;j8A^#5NsgFt(i6R?j>m%d2FB2ql4tV>f18 zYF~5X#m{aie%8t`Ny5b;Tsvrf`42L8Vnyf}(bFP#Jz$2Li@IF{EyUv4FZ zTr4XGGFqIhon*57dt;21v)GecWc@3r0z4^K&XwMhdnnfo6f8EJyAZ|r!)0( zm86@2gG3(ryC07akv#vJXN;*Vt)`f&Ij>B6_4A9pub7kLB>rKepTg2C=R7l3t9RD7 zAXVOP?l+$_5BB$;KHh))#Hph=xhc?U{od(?<-B|#inKK_k0tp^=SWuic+hR(^jX{J zQd3={X`VSRc{g(;A01hAWW$k?Bkvq3I$+$xea))NwhAHb!P9Vn;?Uz6z zZoj;A9VY1y8M{1__lwXMn0(k5J65xGVwgs2WD7A$W9BlOMIX%6*GxWDa;;PAP<-t$ zQppFY(&D4(uy3^9zU~dWM{Ig%2N5iLVdtsKg&Cdmf{!h(U-8zjlKN_x{W+gzDIIEQ z-ml~q@#O;HP?HTWgrw7fun_DMg_f`SFq^Y}>)5T6SbY=Zt6DIxvE6$6+~%Y8&@q4F z4yHG~uGO@tM;Co~>wKGJcY0k^UO{|6jM6Ger%77F>8SpX(!LzDuYDw`7_jb4FJdxf z-m(wD0O38Jyyv5Qm9FfH0aX;LQD40JVWiT6W`wLaGG^Nzn7A*T-)ayF&8K?a_e&9d zy(S+^&Pr$+1ajF6xq=}-gWjN@s)5t>YrYiKFaK%`^M}I z`iKj~4zO{@cY0cbvopi&{N7F&Sa;bTzP^y)`Z)>LPi@Hy?9S|6^VI0R@lmSQ#TgOKuF{hHN(a)eFPr zD`lNUTYSso51qU65|kC6=4VFR4libH>RaV*2RP2E7pD#-#abo4Wn#S+Ynte$G^B-> zHPWryL$I^vwX>C^ogiMa({t_fzS*`cXA5e5-#u!dL$6FxbjR=| z(27Gb9ZvCJI3p|Xje)ST16IUO4UtTMM5&((5b}%FTE{zi;YE%8w`N9$$!CTx>BUGh zBg-NUJ9UW4U)8W1A8Iba3vr0$u8^4brsjV*A1cC&dE|8sd7XRlN91{4wg8?TBA;l) z^E2|P3O*$kZ&fU@HCBYJ#M+9(RXnXjI>#n!FHeiL zm)lta8zLl91Y6{yZ|c&GvA{j?DlL!W8#IW)rVk%$B)v{{skg|kbA#+kH-mPam=_72 zL^?a*Z;`?RmiDQo)pJ)RHh*!Z7N-vP^~Y#vxZpkTdK`>MrJkaWW*GjfcDAhpUrx zE*|bZ8LrGPB&fJc^@R{U4iHMheAjY^M&p2zxL%mQ9?Ez~;(L#1`$<%9%0CMsdK`O` z#K^AAePXZgGw?7i6|3QK!i!0up{^=jZfrB`AFPm2)rub&9c4Cf}me4E`q~+L=GXp znZ`=elc>zRW2C}jOrl8$P|#b9NzZR6b9xUD-8}PLri|&4=vw;~|~oC5*Uy z5tl>)cM)(uWoYXl==Vuq#$DtSg-uRu)EBebyU8haleWdFoj;clmz{`Qf==i7@;M(O zC5cp!i19QxNSV)p;q4fX#u+fCn)UF|CDrr;kF9Jdb7bv9X=xb0VtymjOyvilC~ zhAo?6OQ#S$KngxmMpE&S1tg+P^C05Vvxa2JM^->;MAkrVA=w1kLLzK#hsd3TMc_V4 zSOo54BnKc*;*7z60lB_VVgLXP1$dmTR!eWwKoH*e**MOlr4K-=*h++4iWOQ8NCgB3 zDskWjf?MR;+tg~Zj$)@u#HIfkE(ob%*Pcz+j-8|ukw*6He*4XQv%BN`un$L>}f<^I2=XbHM&mMIdxujyRT2WC#P(U!bU4Fs|R#6 ziP_8F+=Mm^eZrnCd8|JU{2Wf9Qyzqme0UCt8wRv@N!)lcCedQS`@#k0 z$o2hz_Sx%QKJN();(~G2ahy~ppF(@gn#}6V+RSWb2MHXZ!=%^1A25k3%(amOb#3gTJEu^_x!R;Hs|o>~b| zYX`KQ)vV5QYxS}qUT!Z6E>`J$J)>_0&;-#18?kC*jBL^kAxhAmeWDS&mN>q0V@#*V zn9h!|OMSd_ak0x_?qGle8k0U5FN$xL)J0|BTsB)JP%DTWpv{&*lMkNERLwH&%~A1v zsLV4Z zC@ZjK)tRf*i6?6nb&mU$z9)^9N75jp-9@zY0#=|;2t3283I6sT2bTR%c>_1%-v#-& zx5#wF4qX(4H2O?^GQCgA7D0ftA$&zj(niId{}2R-FTj~3!T=r+vn_bF&BUuRevSAi z^9}XphI2B4@KOq)ZZ6=HT4bQTT(rCZnI*AepQGE)4>5`cn zn6-h`*W2cr{sCenQJw$*U~PDu-COB%6vq|sU1@b834|m-fXzyP0D*)++#rDv2*hO! z5{D72N4q2Kz+UX^a@bBn4m*xx$8i!L_=@A$j*mF0R6gYo$oCxO|07lKB}J8$?w!{= zZ+g3DXT%E1*{WZ)diwS69evE3nbw5{LP!;}Vh{>B; z3Qb8P6`9txTt2ItmJs=tqMag3(M09Hp=Be*(n4oKo+x-iNO!?tLY7ce1KOZm#GIfQ zU^ak!9mO`_VFq+jEP%2R_*j%yf{tdm)&x2h0=L)xi{V-e^lt@wx5G8g)eiDYL4FBf znTx&^AiEst!(cK`Qmg`WgB;@x`{Z4XN+z>L;Ozq5wTO2e^w|Jq50o20j`iIH{ntbP zUNnZwpxg}c>Ia!ENXGzhZU?>{z_$&_>;n7tfb3q7*-a6r*h%p|#UyZ#!!=RYAoSl4 z&4@A8_MUv&s%7mUVv-QOYCNU zv$^|ys_!yz{s8*@5c=JL@nHML0pR!%8q1#$`JVAp=>HP3lOY?n9$g za1aUNhD8}IdQF?rBQZUvM{{~iAPgu77e?cH^jd`Vo=WFaF(-X+7R0|rC8iB3XoJSI zAX%l7928utofTYMgrq|`J)6}e#vtktCb$oyfZA&W1wm0hgyiqT-%``}>`{zH(41DZ z)S0=6W=0C_q7PmIUhD2lmFPlv`dK0!o;5MMx?L)hrg{UUu69WH8>o;B&BGF@U)ZVY9yY4RAG`a;@n>Ird8 zH49!YoTHcZ)XS`%&~myr4~zBUC}gx84N?la;}u)KwFiD>qQRdZyhS6MPG1uUTF9KH z`eL`KE~&S2d54#y)WIztyj<+j%Z8$t;?!;>@|94N)H0dGZ3SN->TGBc6t{^(T6cEr zG@ef26)(N@trs-4s|5EsRW=JIRC`^Y zOB4#|a!F^5=~Ox=#B5-k`w}+Ha4ww=C(<|j!lx6uX6oTw_I5aK%*6F!&$B{FK|f^T%q(szb>!aWxD;x%G=DrZa^C281`3TtZ;lEvFD#&(sWcinV8 z70nsx6q3jDGH?qzJdijh4W60K=HxPA!RhYVGF+jXaU&Wpr*N&2TI)hg6r&@S!7}Zl z9E)n0xQ^;-aTGe;1G3tS-I%Y-r~cJMF^BRg<9c3~^mfy}#;5kRKD=l0-3n_1LxSKs zm0PA{X^25a3#pI~N}OdsaU&4}BMZ=a_W;=$ti9-I0;^@>0?!7-!|FXwUNKFvJu*Z# z+}gn28mCiKGtN%2o{d6%le^x{Dm$u@W=^4^SE%>RQAKOP)5vr-os8(Q89iY*RN^fy zs3$<#W}?`4@U$t;x(m>&-`T5YR&Zg9g0<$19?M5{k#<^Co}DuI!*pRIW1L%^oNLN0 zodKu(THMZg+0W~)9*}M6UZ!9upEDAss*%pXDW3TY3r^g_tp#|1IDT{4zh&|wx6If^ z&FqWDwX7DUk1GOC@opM3viucFk=JRm=X(o#G45saSSoHFk))oSDwv4rwiCt3u5t4A zDKis`){GmOGM4Y~XnB27&(7!(BX&z5*r~9!ferzCq@F49ZkM7*D5WKJVfqbuP2zWZ z^rO-8LmKuyD#Of7!pJ!ZhXn;vLoxYYj|MKr21XLvRAC3iO#2jO(!>CEQY<}4Tz8{G z;%+oVD!UtnGMbqavX$a~QCy4Bbb_YFCVw%3pSc4Oi6$}9suFv)-+cr|#Yh}*%8Mz` zsNWed?5^JqM&Xe;ofl@D!T`X4!H;EnCQe|B+u%j#N)j#Mze;jqOmrgn#rc~c<;nIjtKRm?mADX-^b;X zNiAzUhu_Cx;xVCqY>tZR3f@GfZcFsYf_j|DXGWk?5Io@&JS`HP6dX9^?f}ZG5?X3T z(O6~PP9jHqOiWej*osn-!VVk*lb;e?I6cQP2;khwi$PrB)5P1hvA{a@!EMJBXNc=g zRx^teErGw335ok7ai_qFVsl4X!2025v_rDr?_q8$e!L;XtXxssIWl9TMb zI1?rX-!IS6clPN*`N+?RuLz1F4-w?3R`NWGgRI(c8cvLzI(&Bg%-E?TE<+(R{#oK} zNESPWB$LxivOSF`cJ9qc5D6?72W(13&?5*&oq|{7kARB^|H=FbW(;|p&$;DNZsx~S z=3j9txajwZRb>oQsymg|i$+Z=j0(Q+f*?6V+&9*^f~hL0iO*$*Q?$o#wt7{eDm0x) zr^RjH8u2h0_W$iJ`@JjlO*s2@$-c*lhPoM^RK-Y3-4;YsPSF*D>Pfj9{~jp(JeY&H zOHM1K6=v4n)Uqj~B>BM`&CT(+9?lkCP{qRR#b7?CvCjfpf?l1Wf0*I8c0(_GnPSZe z{Z`nFYZ=|_3y;uNBc^A=Mk-40B_`Emf2K0S>1;R;*K}GjW(>y4wjHzZ4a>^_WE7s& zWc6G=i$7iv$OS~U08PW#^?TOeg-?L&D>^&j!9MY~6`8FAC$tP=c`92~kiTQg0UQTq zL(zn0nnH9J>9;a89wv+9SSqI9vW=?cO8AIK&#c@7tL_n=Sz5QBdk`0~qjiczyoyhd zu%02GaR`-P}X^~r)n0-SJ0j!Z>?2d$mbpWo@y%zdhda-n39 z9Oq-0P_xg0YOY|wN{qt?YyxmTB>*Qp?tzi4Z1HJy%X}J*&&veh_{qJZ5Lv?Ot=^1Y zisc{Sl4yBMdfVnhFO^>glc$~YF9sf7Z@20lyxwNjSMvH2WPcObzZ~po1N-^O+924) z{M?3otN||AomX-0Wk`23Dg7|R7d~3x|DviU{>B;Q#OuVT0pe_TJ$-YZ*y{({OWx20o$VXk_=v|tHvzDl z$8RCA$Bo&;U(GZ_EP@aVo@uezj-#0H^$+!K*pt@FGXDlejPZZ0ao!Md z)bA1Q@g4J_m-93LkB8r!_!kOx;$M{l5394%`xEA_F6H)nzgW%3^9d+Bp$uE?J-nSA z@bWM}R%7`}%@4-c1?5_+|0b?yolm>gRnRUEdVA+XFXQWmat)L{q%@(mPicuQ&J$X! z{{~XJSNeGp#d}&UaBj5f#V62BzHEfEUEHYlIT*!mj5Q!r3-vm|*ak4JS1`8Em$8ad zV%+#N`B%xpvK>eieL5*opPe zZle-a8xtUXZwnGtooUgII3;EA{=be14xt?b4 zdMe^qrDIS1+3tAHalj_>Fz@&AdB2%dZr(rY*i!ojRPTD|--CF(+rg%XTz3y;ulVdU zM_c^HsE?2JdMLMB*AKvR^AK;}X4Mb!`cA7p!t1-N`Y^BWu4+jH@gQ8Y1PhAb3Yn;E=_EXAG-|oiT8` zS(YGq*L76!ZfcBYIm*Mp0qFd=5(F`0DHs<3%ej(9P~zkF|9tlzV1JnZqeSvl zz|U=$jG29AoAqVq!uh_yHnh1O17I6jEpcvS{2THS;(WY0>c?Kk;qUo6urMZAc+8K5 z_|&+EEw;FF$4KSxTYiQRKasKk?S&!SD;dJ$LV!-m0>lram%L814x+PuCne2jmNStP zC@ifImU5|MNP=1b`h90kVu+uNy$q+ALaSqwpO46rDEPhYoy94E z*U|U*^ZlZm&&V^DZN(36XNf&R?CcNzxHkqiRT2AR{w^>8kIXo6ZUz&`f7!=!9+L%k zY_5P1hYEbepWya9ZPm~7`gtfX63GI#58N}63&hhtSX6a^RP_1e9Opd;5P1g$Gw?J89Qu&Zy;=5 z@)f>o*8q6lQisq`22BzyLMYe2MS?a!oq#0@bRaA*gOxteiBOKW%Llp<*3SWb2+IJQ z0sVlj2-`ehcNy$N*aG17eF#Hka1db_FoM9jdHoQ=r~*e3IOiC`@iN#0I0fMSo3rGCC{(00xP+4sUfZHkmA-fnf%9+DfT6C zSX3ykac5ctbM~fQojbvnl+q}mg%6J} zp;G8#^AKwUeeB{NxMc;&h%GLP$Q0^6O^n7 zZVu`NXzoDU0M)ktp#A|e=a#+z00Vk>oRv{cOT$1Ao&Bmcs1(}br6PFnW>{Mf(jOr7 zuHZG)Knt3NY{7yT|8u>FkT{#2ZPQ3;3_Lb7@6F8H+2;TN1W3U^DEtNW^!RXd517H= z8{Ef1!ZDsLGhMu;hN3ea>Tnd^YJE4Ezh zAs>$`l~qRJg|lc6DeXcim+xwL;bKv^*q@soxwE5eeofXogg?XUgde=7W_?<;q(%2O zM%|(r8S;A6ic*Z1}P zy3~&!fNF;3UVZ^?T2W;H01$+DoUK>eZqq;zo!D{i&HdKW0&VGq(ng^LgeppTLgF1H z-lD{DL{&(lI8h_mVv}ZXgev=GqvT1_~oS z!tfkCJnt4_xQ&C47r%}iD;P^4M^ea|P}TQ@Hook6?lrqyl{ej`|s zR`a0ME?QEg?iG0^l@hv@N=pmTM&Ii7>IyLebxuryJ&X@eTl#j z2(EFjtmX97gLfeTg~h4ou3KV_rlDQdh=j zbwvJ4 zoh0|BO}UxkUZ-H9QRNBS{aT~Z844u`gmd?5+8v*nw^uXdy`$uKAuc8JWPN!2=H=Y} zwCvCO_{WJzy^)otz?>Iwq-6g^;^nca3TkEEb5${m%vbQ}e!F7IwZzdCSD--4?WiKT zk3@-lk3`nhuZ?ibS_2p`qpX)aNtPvk;X=~W+S+;%AY1{AGO=~z46>^dg z%|0LRycI`KHA1BUEXD|ZktgDf$=$}1#TxUAE#EF)U(Dgru&%&;0gmQ}fTMX6a5QfL+rT3MJ9Dt7z++%lf}`hP znLY9kj!%~j001CyW4G0DeYfqq9f_b8L2$AC#%-UrIQAdCVYd?|pBv%wE7DT3xiHydd z1-g>Vvu6=xav@WMRQLRrA|-VTewJ#-V$SW<8)fC_q%m+jUv2Aahu7>5 zdT+g8(zrg^?w#SJ9=D4#RB5DoWItY>TW@%s1EbqJwy*=(OV9(Tnm8LYY& z{ekOwtc39nc`Tj^l^0C-Q$x@LqGJKD9@ojcf$w7)T#*tgvjgF3d>573MMXtbE-Kgs z9ODUqSG#$bR;&E|1q274SGd1Ja40#CZ3f>(;BdYbhz|UU!ZtQK%5|%v;7lrH7U_YY zbfki_I+ErMsV^nUB)&^h5Rrq#vIr_tsH}ZT5Ru!MkeXb zq^+4+Te)D*66_2}40iWNkS@LnzBa-J(h;}p9emgE{c|FhiSjH2{jpDI=nES9fRNKh zIWs(&^w7{(1-}~d%O$`(WDzo0$vS7%(WbeGw-$uYMjqP&kz*&NEldSi1o8-l1Sk;@ zICe%|uOQ^j1sYFonuD#tCh!ol=in{WqXE+|S_SMEA)KR2F#RGW)34y#GNE6^u|)~L zj_<-B|HphS-)`0u^5z|!7gw_l?8n~56!|_;kBs?W)?+h5kJzh~q8^w@UYuNxOIqS1yki3 z^m_?=_EaC@6vX#O3VN3ij@x`=_;)5Q;3hHRYcyh-e4@Hjh&tG^cbjao55`r}k|?@dOdx$}`seho+r++XHYq#9{RYmA_rgfEFME?OhnaKc zobQ}Da~Z<#5yqIsY%9R5ApgjM?@oT(ea-j`AN<4IXNK7<%w@t?ItoHkp0@UNx}wa#xlPS;n{b2aQ6$0A3SBgXNCBg&B- ztYBOIm@xiF$Wuw>XIOdbp?)jjtu7BB3_(hjpG^OiZuzW$>8$` zjugiZN0MWK;{;u}_J|{LevX{Cv1SK3zW{c@ zzXtxMee)7>pSgW=fblDgf5MtN{2!9~93sXMbNf&9Fk_<*4}3&0q4)}=m*LEtU1BLd z_O+D(vhpi*o}P}5R8K=q@Z#pO*Y;6{u5LSLod#yVsm_OFhOVyLr_Bp6v3!_VPU9~v znmA*DU;bwDp$Xc4HT**}4En{pXkK{~QRXv_2O~N!NyCTK@FBWUl+JAXto6Qe+SQiN z`mhfU%r)aVznW}#Ba)7OI8A+ymGYRLALCm4NxwQwvKM(SGqe7S4e#}* z{HCrsDG?{c*{tSlP8)|Q*>QIayX(dju~wM(8!&R_)HuV&`v$$&h!v|oD=ak;{-iX5 zmQEyedG=@H(t+bLGw4^3D-N6Ro>NlqjZ$AzWa}l_s(@Qcxj5SeR2O3_k_%llzX)e zpf{yGx3vcLpGJ0o^6NHuetG6NTKHt6d(&<>PV>6uylq`Hy2wY8h_L%VdWF*x$W#fr zAV`7aVCUlO{*FoCN%$^ceFkgg4?q#;1J)#9FN$(PVuldYcE>SUm>?;X7YA9iB#JgO z2K2E3I>l|)`-XLuaU-9Y>GL4}Jm*NCsZD}fCFFP(a?YJk!9FhavZnJswUc{$NA&u) zqCpc|)W?J-HqQSJc0*3bBThn>fQ)GzqL2}HenHNMAr~Oiu0D^N<)mE-atShTRs*|F z>>slRMaTkVPK%d?Ty*CPay|oDGUGq&vC<>*mvPffeLo1!^4()Y2HEI~Uwp-i-mWtB zJt6^m2Zi{#$h}-~$0h9Hip*ivEaw!pf9#x1&dXE8o#s7XW@hhslbp(rn9~n<#|~~Q zGEQ2HV?7Yx$z{3Ep8m|NG4C_8&W!dsPwju;nX#WT?lfnn!oK^=40EbHVov|FGgC$% z7iBG%AvXxeFW@-tZYU5mK!hL)gn<}Alpslv08#`CfE;HgK>ElMf&q5M7BBB~jm&Y}Iz0$WH5~aU-Zn4@H2YHv_p8 zMZeLDK}!_O#t{WAohI$2m;7SoQWUVdE54PM+a)OmN(4MCxifF(aX$z8)h2`(#58im zD6mIT`02;=sS+#evI}L_}!PdpQ7(n;tHL7Odenk z_%}X;_6Nwtxo0F?2LsG4UoV8L7gO#p1muRdFzOu3H1Mb1c;W{j2*cSkz8rh>%D=fD z^)B6>KVca6=(y+4dOu8^;9<|d{M{V}eH%G)F*yup@>-FTmt6U~5kt*CeJU|!OYwyp zT=^p!W6paNJ-1Ph{6b+gWfmQ4SZ^^ILZBqHs6;C%@8!iis3_3Dnd#(nA%zbp#OBld zGn-<67Nf@c&}zPSXyD3f)K*qkBr&_=YocE@<>58G5a+NQsT32bF}!kz&o8FV@cE^G zGZ|?#3_1X2%Gthr&iq;Ban6U6l=WmFOQ{z%q>#el^g}aG7XZrNZ0$1t+1IBV>EdR&9JG%8j&>5lgp^9Ro2wRD)i^1azd>gh3Y~_sn8fhQ> zD;L6Agl$obqk%Z`g(8&@swpfV<`5_*z=ZgYl-LN{{6g|)zQ)r3@3kKgE%}Gn4y8)! zru%9-b1C)w34Jyhxx6&I)k$1#qB&$`k!Yq%JY2k^s?~;@V=}V{E4)Wx(OQOQvofl) z-nY6{Z6mUrBa8SMDX1}FZ8kdv90*l0oBS}$GW#X6z1h#9 z=;3jT;d@=Y+ZlD)+tpPQam#3{WW8Dq>F9}+O6F>b%pqN+h{`Nl5UqLgS=}I-b4Ao- zszKCaoLJ8|cJ(ce9go-2=|hz^M}HQ5%`NNOLEF*j46hTlSFYDMvz_q^+FSmDJ>Aj} zSB`2>>bp6#XVJgAMg2LHdpvF>d_NHHU1+L7121#FBjJBWazFpS=Nl6KwBtE zJ0Nb6vA1fJ)``4MsKllJIlWX!Nq6j7vg_DNBN6G-?9R@7^Lae${A>b%1FmC%!{id! z_itZ5jzN0l<`MFr4K6gK^+Y(oT?pEB{GmU*7@qt7r;$IpkU6&WT6Ef)#*1Y-S@AHP zCvyK+Vk2=TfkoRAV~mq{mE{4v&BOqF$Z7(-lyC_HvR9}>qDJS46N(=ZS6$*A)j|7$ zI8oOds?#Q4t0K2cwnuRtE%%gsdR^4f*R=NOnO>9L4fRs>$NEFbceT| z@lKb3t-Yo2jb?RP+oW~36|x$u;AR>H`?{P8U7q+o zO~Y%GjwyN-#ZsOm0a3Xc74BIDwS9SM(l#np-v%@O1C^INez85eE?ZoY2(KWjW{PSS zO1G+{v_(2WHIvmdt*#*YSgYN(@&)^?({)#P9 zr{ZO-lf~cf;t0kEgM~MN5Rl(EA=cT9Ed3NQ`oAH+L=#sRcSpmIA0a8d%5JJ8T4oE_80C-};^nT2Q0 Ang9R* literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/R/scomps.rdx b/scomps.Rcheck/scomps/R/scomps.rdx new file mode 100644 index 0000000000000000000000000000000000000000..d01a9901054e564b923e191e1b706cd798babb14 GIT binary patch literal 729 zcmV;~0w(<*iwFP!0000018tN`Zxb;P$DM8hG^HdoJX#(Cao}-iB$^6nB_35(gb=Mj zZ6%OE#__rvtDD`$>!hg=96$&z+_)eiq~5r2feSY{Ax?1N1Heb%fJ6^GW*^REX`@*7 z??3igc`HY(0t`uEapB_V8AAFhu_5UXK^uhD2mc$;k0V>9|9BeuS`W7g z*>)Fs;0N$leDsiyZP% zLB0j~vd$vkeoILCJMtaaJNFeiYykJ?>F#iSjEf*9T3Y({Dkv9ZiruDktNtOOY;VR5d0b#7` zDpqW!nO+UduBAkc!m0Z$&ran%iM%3pLwZz+C831JMc0)p1Ij`wI$C%-Rfn=FRm=oa z*=R9Q4cRi(O4eI&!a(_4gl17$gjzPEliQ-nJlp6yQzzP|f$y$5zGspO2F19Jqc%JD zYP8;3f`g={;Z01{B}jE@-?y24Stw7q>5Sc(8EG&k%n?UuxX)(Lf_zKgV=ko8kvO5~ zC~4ECP>xCKfb^t}4($4lnFOiQG;H|FgjEV7zfnFj$sY^@Dm`0tXyn#7G@|s3!*U40 z^2UY>-`{4gw4==-)evdGq@r!XwXdT0{wMta=CMF>hoMa%$G- + +R: Vignettes and other documentation + + + +

diff --git a/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.R b/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.R new file mode 100644 index 00000000..c639e81d --- /dev/null +++ b/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.R @@ -0,0 +1,4 @@ +## ----------------------------------------------------------------------------- +knitr::opts_chunk$set(warning = FALSE, message = FALSE) + + diff --git a/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.Rmd b/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.Rmd new file mode 100644 index 00000000..8966a59d --- /dev/null +++ b/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.Rmd @@ -0,0 +1,39 @@ +--- +title: "Good practice of scomps with HPC" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{good_practice_hpc} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + + +```{r} +knitr::opts_chunk$set(warning = FALSE, message = FALSE) + +``` + +## Assumptions +- Users have an accessible HPC at your work +- Data are stored in distributed file systems (usually incorporated into the HPC system) + + +## Basic workflow + +### Practice for minimizing errors +- Consider using `try()` or `tryCatch()` not to a tiny error will halt all the work without any results + - Especially with the higher-level functions +- "IPDE -- Inspect, Predict, Decide, Execute" all the time + +### Raster-Vector overlay +- Make `sp_index_grid()` to get padded grid objects +- Convert sf/SpatVector objects into `terra::ext()` compatible named numeric vector + - For example: `c(xmin=0, ymin=0, xmax=10, ymax=10)` +- Make list objects with: + - An extent vector in each element + - Preprocessed vector objects with respect to each extent vector in the first list + - Preferably all lists are named +- Write a `future.apply` script running through the extent list object +- Run a small amount of data to estimate the total computational demand +- Submit a job with a proper amount of computational assets diff --git a/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.html b/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.html new file mode 100644 index 00000000..da4506f4 --- /dev/null +++ b/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.html @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + +Good practice of scomps with HPC + + + + + + + + + + + + + + + + + + + + + + + + + + +

Good practice of scomps with HPC

+

2023-10-04

+ + + +
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
+
+

Assumptions

+
    +
  • Users have an accessible HPC at your work
  • +
  • Data are stored in distributed file systems (usually incorporated +into the HPC system)
  • +
+
+
+

Basic workflow

+
+

Practice for minimizing errors

+
    +
  • Consider using try() or tryCatch() not to +a tiny error will halt all the work without any results +
      +
    • Especially with the higher-level functions
    • +
  • +
  • “IPDE – Inspect, Predict, Decide, Execute” all the time
  • +
+
+
+

Raster-Vector overlay

+
    +
  • Make sp_index_grid() to get padded grid objects
  • +
  • Convert sf/SpatVector objects into terra::ext() +compatible named numeric vector +
      +
    • For example: c(xmin=0, ymin=0, xmax=10, ymax=10)
    • +
  • +
  • Make list objects with: +
      +
    • An extent vector in each element
    • +
    • Preprocessed vector objects with respect to each extent vector in +the first list
    • +
    • Preferably all lists are named
    • +
  • +
  • Write a future.apply script running through the extent +list object
  • +
  • Run a small amount of data to estimate the total computational +demand
  • +
  • Submit a job with a proper amount of computational assets
  • +
+
+
+ + + + + + + + + + + diff --git a/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.R b/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.R new file mode 100644 index 00000000..aa3d29fc --- /dev/null +++ b/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.R @@ -0,0 +1,22 @@ +## ----------------------------------------------------------------------------- +knitr::opts_chunk$set(warning = FALSE, message = FALSE) + + +## ----------------------------------------------------------------------------- +library(scomps) +library(sf) +library(terra) +library(stars) +library(dplyr) + + +## ----------------------------------------------------------------------------- +# your_grid = scomps::sp_index_grid() + + +## ----------------------------------------------------------------------------- +# library(mapsf) +# mf_map(your_grid$geometry) + + + diff --git a/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.Rmd b/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.Rmd new file mode 100644 index 00000000..4bc1aaf2 --- /dev/null +++ b/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.Rmd @@ -0,0 +1,46 @@ +--- +title: "Generate computational grids" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{computational_grids} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + + +```{r} +knitr::opts_chunk$set(warning = FALSE, message = FALSE) + +``` + + +## Prepare input data +```{r} +library(scomps) +library(sf) +library(terra) +library(stars) +library(dplyr) + +``` + +## Computational grids +```{r} +# your_grid = scomps::sp_index_grid() + +``` + + +## Visualize computational grids +```{r} +# library(mapsf) +# mf_map(your_grid$geometry) + + +``` + + + +## Notes +- Computational grids are the exhaustive split of the entire study region. You should take a square buffer of each grid to clip the target raster or vector. diff --git a/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.html b/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.html new file mode 100644 index 00000000..c2d963b8 --- /dev/null +++ b/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.html @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + +Generate computational grids + + + + + + + + + + + + + + + + + + + + + + + + + + +

Generate computational grids

+

2023-10-04

+ + + +
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
+
+

Prepare input data

+
library(scomps)
+library(sf)
+library(terra)
+library(stars)
+library(dplyr)
+
+
+

Computational grids

+
# your_grid = scomps::sp_index_grid()
+
+
+

Visualize computational grids

+
# library(mapsf)
+# mf_map(your_grid$geometry)
+
+
+

Notes

+
    +
  • Computational grids are the exhaustive split of the entire study +region. You should take a square buffer of each grid to clip the target +raster or vector.
  • +
+
+ + + + + + + + + + + diff --git a/scomps.Rcheck/scomps/help/AnIndex b/scomps.Rcheck/scomps/help/AnIndex new file mode 100644 index 00000000..a7b8aefb --- /dev/null +++ b/scomps.Rcheck/scomps/help/AnIndex @@ -0,0 +1,25 @@ +aw_covariates aw_covariates +calculate_sedc calculate_sedc +check_bbox check_bbox +check_crs check_crs +check_crs2 check_crs2 +check_packbound check_packbound +check_within_reference check_within_reference +clip_as_extent clip_as_extent +clip_as_extent_ras clip_as_extent_ras +clip_as_extent_ras2 clip_as_extent_ras2 +distribute_process distribute_process +estimate_demands estimate_demands +extent_to_polygon extent_to_polygon +extract_with extract_with +extract_with_buffer extract_with_buffer +extract_with_polygons extract_with_polygons +get_computational_regions get_computational_regions +grid_merge grid_merge +initate_log initate_log +rast_short rast_short +set_clip_extent set_clip_extent +sp_indexing sp_indexing +sp_index_grid sp_index_grid +switch_packbound switch_packbound +validate_and_repair_vectors validate_and_repair_vectors diff --git a/scomps.Rcheck/scomps/help/aliases.rds b/scomps.Rcheck/scomps/help/aliases.rds new file mode 100644 index 0000000000000000000000000000000000000000..35dd2b9ebc768c1c42366370307d274bee18e960 GIT binary patch literal 350 zcmV-k0ipgMiwFP!000001MQN}PQx$^#^RChCKtikHcZ&H!y zWaG?7>1+yIalnI$-(6?rzf2bGmIq0pyIv@j$|9Q*Bl})AZG=e9f?*R%`c0UXp0upd zm)Vp#S&Ch|#+5mV2aPgR&S#I7p{v`u(X(zI8c9~;k!-%Z$Vhfd*^|J{s_N{y9`;~J wcj9amciI4XxknWpKfM?aIc1PiCl+d6B(8PYvdfnJ{(~D zjvaZN?eg-7NxM~2#L+%Pu@ftw9FPCx`-M_!rPix6wc1EiZSKE)djCp#i8jQv~4`j$d5XRNnCv*Vr*xmt%D5O z?Atg7J4;kYdZgS@fP_0t7!1~|I8Os;20UhY&J1B)2$Eh@#jZZKtvEGHoD;R9Y}+A4 zgS?oUDUBg#>ZgRTC|$dtY;o%O?d1qV^uJvUvjr8bq)mP*{fdRLWS|{)vcYDptE!#e z;bOsjY0qJXsW)bwDF*E&LL9v^iwCevWTD687Af_sG(v&$RP#Q%ic^u8$iQ7px#G8k zr!|`5>EFaH{?oz(P_TG}X^AQ>&Wl6ARm?q>O=PYzQ@soW%AWd{wK5**Ov k`1~iM*5{(0o%GF)5@%_=eY&XBS2_Ot1t=ar)Tjyo0P33CssI20 literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/help/scomps.rdb b/scomps.Rcheck/scomps/help/scomps.rdb new file mode 100644 index 0000000000000000000000000000000000000000..6ddc3f1a5122e9bc3272d87f20f248371dac4ee5 GIT binary patch literal 35998 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 literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/help/scomps.rdx b/scomps.Rcheck/scomps/help/scomps.rdx new file mode 100644 index 0000000000000000000000000000000000000000..57f62f66e7ab44a13d877be5cf2a40ec4261c111 GIT binary patch literal 769 zcmV+c1OEIUiwFP!0000017*}bY|}s#0N`_z{sq#OmR1x*5g_r~LgW6W6$lkXk)YjL z3BhnU_BA=xv0eL;rbPlFK(HXeg2V^|6B2vHP>>iH7#Kh-Y)G&(uu-04yRR>eWX0cm zmv=vo-}MY*EXC3(jis95mNhTT&kW@mYwD>dqVImVvT!vqrk!D|r3c;S!f)o#9lyYb z(Y-k+^8vm8Aow@>kPgnGj|Sjn^oef9(wERf55a9{eFNNw&Zohj(dRdz-ZS*Y_uvim zmA5ed6MF6q?C%A7VGZ_k9DVaE?3ts*Ey#aI+ZNPcM=xIm&!Q_I!LQJ3&%uAuch~89 zAKV6?MnC=mhCQU=o@p%2+QWzD7-azm$GYkdD+*?f6>hp!!LsbTR5D3_Q7Aa~vR6@tlCERea0o?- z12RQlTD&a$Vsa?Eq$5?hT-z-sgJ7eI2PM}}&Zsj8>xQR6jxHN`TsoGh@vv-CFbPU0 zDcBXjV$ITy$914;*wP9ohl7HZdWQ6QRhY{4!#~u&ogE(?+wtrf;Uh*i(V~K-wF3OguZ_b zJdA$y8a#o{z5{Q2WA{S0(oUlH{Q;js4>Z&IM=sF)9s5bwKe!OhA9et3v*D$05l(e# zDi^CY(lBL1R;L`H9Hkti9H*S1%u`O1HPUHyx<;L@QEwPb*QnDq>SJV{5u#BdI&z$7 zf+$Zk8NC@SQ}4m`i#&}~(nagtw_tCz-^^A&#J&ox!iU}^tgz^Rl^kP7kOu$&$<%l# literal 0 HcmV?d00001 diff --git a/scomps.Rcheck/scomps/html/00Index.html b/scomps.Rcheck/scomps/html/00Index.html new file mode 100644 index 00000000..9c12d593 --- /dev/null +++ b/scomps.Rcheck/scomps/html/00Index.html @@ -0,0 +1,76 @@ + + +R: Scalable R geospatial computation + + + +
+

Scalable R geospatial computation + +

+
+
+[Up] +[Top] +

Documentation for package ‘scomps’ version 0.0.3.10042023

+ + + +

Help Pages

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aw_covariatesComputing area weighted covariates using two polygon sf or SpatVector objects
calculate_sedcCalculate SEDC covariates
check_bboxCheck if the data extent is inside the reference bounding box
check_crsCheck Coordinate Reference System
check_crs2check_crs2: Coordinate system checker
check_packboundReturn the package the input object is based on
check_within_referenceCheck if the boundary of the vector/raster object is inside the reference
clip_as_extentExtent clipping
clip_as_extent_rasclip_as_extent_ras: Clip input raster.
clip_as_extent_ras2clip_as_extent_ras2: Clip input raster (version 2).
distribute_processProcess a given function in the entire or partial computational grids (under construction)
estimate_demandsEstimate computational demands from inputs (to be written)
extent_to_polygonGenerate a rectangular polygon from extent
extract_withExtract raster values with point buffers or polygons
extract_with_bufferExtract summarized values from raster with points and a buffer radius (to be written)
extract_with_polygonsExtract summarized values from raster with generic polygons
get_computational_regionsGet a set of computational regions
grid_mergegrid_merge: Merge grid polygons with given rules
initate_logTurn on logging
rast_shortQuick call for SpatRaster with a window
set_clip_extentSetting the clipping extent
sp_indexingCreate integer indices for grid
sp_index_gridsp_index_grid: Generate grid polygons
switch_packboundSwitch spatial data class
validate_and_repair_vectorsValidate and repair input vector data
+
diff --git a/scomps.Rcheck/scomps/html/R.css b/scomps.Rcheck/scomps/html/R.css new file mode 100644 index 00000000..c2289098 --- /dev/null +++ b/scomps.Rcheck/scomps/html/R.css @@ -0,0 +1,130 @@ +@media screen { + .container { + padding-right: 10px; + padding-left: 10px; + margin-right: auto; + margin-left: auto; + max-width: 900px; + } +} + +.rimage img { /* from knitr - for examples and demos */ + width: 96%; + margin-left: 2%; +} + +.katex { font-size: 1.1em; } + +code { + color: inherit; + background: inherit; +} + +body { + line-height: 1.4; + background: white; + color: black; +} + +a:link { + background: white; + color: blue; +} + +a:visited { + background: white; + color: rgb(50%, 0%, 50%); +} + +h1 { + background: white; + color: rgb(55%, 55%, 55%); + font-family: monospace; + font-size: 1.4em; /* x-large; */ + text-align: center; +} + +h2 { + background: white; + color: rgb(40%, 40%, 40%); + font-family: monospace; + font-size: 1.2em; /* large; */ + text-align: center; +} + +h3 { + background: white; + color: rgb(40%, 40%, 40%); + font-family: monospace; + font-size: 1.2em; /* large; */ +} + +h4 { + background: white; + color: rgb(40%, 40%, 40%); + font-family: monospace; + font-style: italic; + font-size: 1.2em; /* large; */ +} + +h5 { + background: white; + color: rgb(40%, 40%, 40%); + font-family: monospace; +} + +h6 { + background: white; + color: rgb(40%, 40%, 40%); + font-family: monospace; + font-style: italic; +} + +img.toplogo { + width: 4em; + vertical-align: middle; +} + +img.arrow { + width: 30px; + height: 30px; + border: 0; +} + +span.acronym { + font-size: small; +} + +span.env { + font-family: monospace; +} + +span.file { + font-family: monospace; +} + +span.option{ + font-family: monospace; +} + +span.pkg { + font-weight: bold; +} + +span.samp{ + font-family: monospace; +} + +div.vignettes a:hover { + background: rgb(85%, 85%, 85%); +} + +tr { + vertical-align: top; +} + +span.rlang { + font-family: Courier New, Courier; + color: #666666; +} + diff --git a/scomps.Rcheck/tests/startup.Rs b/scomps.Rcheck/tests/startup.Rs new file mode 100644 index 00000000..8ad6d250 --- /dev/null +++ b/scomps.Rcheck/tests/startup.Rs @@ -0,0 +1,4 @@ +## A custom startup file for tests +## Run as if a system Rprofile, so no packages, no assignments +options(useFancyQuotes = FALSE) + diff --git a/scomps.Rcheck/tests/testthat.R b/scomps.Rcheck/tests/testthat.R new file mode 100644 index 00000000..b465b524 --- /dev/null +++ b/scomps.Rcheck/tests/testthat.R @@ -0,0 +1,12 @@ +# This file is part of the standard setup for testthat. +# It is recommended that you do not modify it. +# +# Where should you do additional test configuration? +# Learn more about the roles of various files in: +# * https://r-pkgs.org/testing-design.html#sec-tests-files-overview +# * https://testthat.r-lib.org/articles/special-files.html + +library(testthat) +library(scomps) + +test_check("scomps") diff --git a/scomps.Rcheck/tests/testthat.Rout b/scomps.Rcheck/tests/testthat.Rout new file mode 100644 index 00000000..dfb13fbb --- /dev/null +++ b/scomps.Rcheck/tests/testthat.Rout @@ -0,0 +1,37 @@ + +R version 4.3.1 (2023-06-16) -- "Beagle Scouts" +Copyright (C) 2023 The R Foundation for Statistical Computing +Platform: aarch64-apple-darwin20 (64-bit) + +R is free software and comes with ABSOLUTELY NO WARRANTY. +You are welcome to redistribute it under certain conditions. +Type 'license()' or 'licence()' for distribution details. + +R is a collaborative project with many contributors. +Type 'contributors()' for more information and +'citation()' on how to cite R or R packages in publications. + +Type 'demo()' for some demos, 'help()' for on-line help, or +'help.start()' for an HTML browser interface to help. +Type 'q()' to quit R. + +> # This file is part of the standard setup for testthat. +> # It is recommended that you do not modify it. +> # +> # Where should you do additional test configuration? +> # Learn more about the roles of various files in: +> # * https://r-pkgs.org/testing-design.html#sec-tests-files-overview +> # * https://testthat.r-lib.org/articles/special-files.html +> +> library(testthat) +> library(scomps) +> +> test_check("scomps") +pr, tas, +pr, tas, +pr, tas, +[ FAIL 0 | WARN 0 | SKIP 0 | PASS 8 ] +> +> proc.time() + user system elapsed + 1.703 0.063 1.763 diff --git a/scomps.Rcheck/tests/testthat/tests.R b/scomps.Rcheck/tests/testthat/tests.R new file mode 100644 index 00000000..6efa4142 --- /dev/null +++ b/scomps.Rcheck/tests/testthat/tests.R @@ -0,0 +1,65 @@ +# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand +testthat::test_that("What package does the input object belong?", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + + packbound_stars = check_packbound(bcsd_stars) + sprast_bcsd = terra::rast(bcsd_path) + packbound_terra = check_packbound(sprast_bcsd) + + testthat::expect_equal(packbound_stars, "sf") + testthat::expect_equal(packbound_terra, "terra") +}) + + +testthat::test_that("What package does the input object belong?", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + + nc = system.file(package = "sf", "shape/nc.shp") + nc = sf::read_sf(nc) + + datatype_stars = check_datatype(bcsd_stars) + datatype_sf = check_datatype(nc) + + testthat::expect_equal(datatype_stars, "raster") + testthat::expect_equal(datatype_sf, "vector") +}) + + +testthat::test_that("Format is well converted", +{ + withr::local_package("stars") + withr::local_package("terra") + withr::local_options(list(sf_use_s2 = FALSE)) + + # starts from sf/stars + bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars = stars::read_stars(bcsd_path) + nc = system.file(package = "sf", "shape/nc.shp") + nc = sf::read_sf(nc) + + stars_bcsd_tr = switch_packbound(bcsd_stars) + sf_nc_tr = switch_packbound(nc) + + testthat::expect_equal(check_packbound(stars_bcsd_tr), "terra") + testthat::expect_equal(check_packbound(sf_nc_tr), "terra") + + stars_bcsd_trb = switch_packbound(stars_bcsd_tr) + sf_nc_trb = switch_packbound(sf_nc_tr) + + testthat::expect_equal(check_packbound(stars_bcsd_trb), "sf") + testthat::expect_equal(check_packbound(sf_nc_trb), "sf") + +}) + + + diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index cc8b8d68..acb3b95d 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -1,6 +1,6 @@ Package: scomps Title: Scalable R geospatial computation -Version: 0.0.2.10032023 +Version: 0.0.3.10042023 Authors@R: person("Insang", "Song", , "geoissong@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-8732-3256")) @@ -15,11 +15,13 @@ Imports: dplyr, future, future.apply, + methods, rlang, sf, stars, terra, - testthat + testthat, + units Suggests: future.batchtools, igraph, @@ -30,4 +32,4 @@ Suggests: VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: 1af1eaeb8441cd422e37a21fe2e2deb1 +LitrId: 27d90205fd42be403e707a6a559e8eae diff --git a/scomps/NAMESPACE b/scomps/NAMESPACE index e7df8cf6..b8f3fc6a 100644 --- a/scomps/NAMESPACE +++ b/scomps/NAMESPACE @@ -12,10 +12,9 @@ export(clip_as_extent_ras) export(clip_as_extent_ras2) export(distribute_process) export(estimate_demands) +export(extent_to_polygon) export(extract_with) export(extract_with_buffer) -export(extract_with_buffer.flat) -export(extract_with_buffer.kernel) export(extract_with_polygons) export(get_computational_regions) export(grid_merge) diff --git a/scomps/R/check.R b/scomps/R/check.R index 3e8e20c6..2e1bbcf2 100644 --- a/scomps/R/check.R +++ b/scomps/R/check.R @@ -8,19 +8,19 @@ #' @export check_packbound <- function(input) { # cl_inobj = class(input)[1] - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) - if (is(input, "SpatVector") || is(input, "SpatRaster")) { + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) + if (methods::is(input, "SpatVector") || methods::is(input, "SpatRaster")) { return("terra") } return("sf") } check_datatype <- function(input) { - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) - if (any(is(input, "SpatVector"), is(input, "sf"))) { + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) + if (any(methods::is(input, "SpatVector"), methods::is(input, "sf"))) { return("vector") } - if (any(is(input, "SpatRaster"), is(input, "stars"))) { + if (any(methods::is(input, "SpatRaster"), methods::is(input, "stars"))) { return("raster") } } @@ -28,11 +28,12 @@ check_datatype <- function(input) { #' @title check_crs2: Coordinate system checker #' @description The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179. #' @param input Input object one of sf or terra::Spat* object +#' @param crs_standard character(1). A standard definition of coordinate reference system. Default is "EPSG:4326" Consult [epsg.io](https://epsg.io) for details of other CRS. #' @return A (reprojected) sf or SpatVector object. #' @export check_crs2 <- function(input, crs_standard = "EPSG:4326") { check_crs.sf <- function(input){ - if (is.na(st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} + if (is.na(sf::st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} if (sf::st_crs(input)$epsg == crs_standard ) { return(input) } @@ -53,6 +54,45 @@ check_crs2 <- function(input, crs_standard = "EPSG:4326") { sf = check_crs.sf(input)) } +#' Generate a rectangular polygon from extent +#' +#' @param extent input extent. A numeric vector with xmin/xmax/ymin/ymax, sf::st_bbox() or terra::ext() outputs. +#' @param output_class character(1). Class of the output polygon. One of "sf" or "terra" +#' @param crs character(1). Coordinate reference system definition. +#' @author Insang Song +#' @export +extent_to_polygon <- function(extent, output_class = "terra", crs = "EPSG:4326") { + if (!output_class %in% c("sf", "terra")) { + stop("output_class should be one of 'sf' or 'terra'.\n") + } + if (methods::is(extent, "numeric")) { + if (is.null(attr(extent, "names"))) { + stop("Your extent is an unnamed numeric vector. Please define names xmin/xmax/ymin/ymax explicitly.\n") + } + extent = switch( + output_class, + sf = sf::st_bbox(extent), + terra = terra::ext(extent) + ) + } + + extent_polygon = switch( + output_class, + sf = sf::st_as_sfc(extent), + terra = terra::vect(extent) + ) + + extent_polygon = switch( + output_class, + sf = sf::st_set_crs(extent_polygon, sf::st_crs(crs)), + terra = terra::set.crs(extent_polygon, terra::crs(crs)) + ) + + return(extent_polygon) + +} + + #' Check if the data extent is inside the reference bounding box #' #' @description One of the most common errors in spatial computation is rooted in the entirely or partly incomparable spatial extents of input datasets. This function returns whether your data is inside the target computational extent. It is assumed that you know and have the exact computational region. This function will return TRUE if the reference region completely contains your data's extent and FALSE otherwise. @@ -77,10 +117,11 @@ check_bbox <- function( if (is.na(query_crs) || is.null(query_crs)) { stop("The dataset you queried has no CRS. Please make sure your dataset has the correct CRS.\n") } + query_matched = sf::st_transform(data_query, sf::st_crs(ref_crs)) + - # ... - check_result + check_result = sf::st_within() return(check_result) } @@ -100,9 +141,9 @@ check_bbox <- function( #' #' @export check_crs <- function(x) { - stopifnot("Input is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) + stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) - if (is(x, "sf") || is(x, "stars")) { + if (methods::is(x, "sf") || methods::is(x, "stars")) { crs_wkt = sf::st_crs(x) } else { crs_wkt = terra::crs(x) @@ -119,8 +160,8 @@ check_crs <- function(x) { #' @author Insang Song \email{geoissong@@gmail.com} #' @export check_within_reference <- function(input_object, reference) { - stopifnot("Input is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) - stopifnot("Reference is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) + stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) + stopifnot("Reference is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) bbox_input <- input_object sf::st_bbox() |> diff --git a/scomps/R/estimate_demands.R b/scomps/R/estimate_demands.R index 6dff37d0..0c0bf6d7 100644 --- a/scomps/R/estimate_demands.R +++ b/scomps/R/estimate_demands.R @@ -6,6 +6,7 @@ #' @param nx integer(1). #' @param ny integer(1). #' @param padding numeric(1). Extrusion factor +#' @author Insang Song #' @export estimate_demands <- function( inputs, diff --git a/scomps/R/indexing.R b/scomps/R/indexing.R index 6fee582a..7555a3f9 100644 --- a/scomps/R/indexing.R +++ b/scomps/R/indexing.R @@ -10,7 +10,7 @@ sp_indexing <- function(points_in, ncutsx, ncutsy){ # pts <- data.table(pnts) points_in <- points_in |> - mutate(or_id = seq(1, dim(points_in)[1])) + dplyr::mutate(or_id = seq(1, dim(points_in)[1])) range_x <- range(points_in$x) limits_x <- (range_x[1] + seq(0, ncutsx) * (range_x[2] - range_x[1]) / ncutsx) @@ -18,7 +18,7 @@ sp_indexing <- function(points_in, ncutsx, ncutsy){ limits_y <- (range_y[1] + seq(0, ncutsy) * (range_y[2] - range_y[1]) / ncutsy) points_in_cut <- points_in |> - mutate(xcut = as.integer(cut(x, ncutsx, labels = seq(1, ncutsx))), + dplyr::mutate(xcut = as.integer(cut(x, ncutsx, labels = seq(1, ncutsx))), ycut = as.integer(cut(y, ncutsy, labels = seq(1, ncutsy)))) return(points_in_cut) diff --git a/scomps/R/interpret_computational_domain.R b/scomps/R/interpret_computational_domain.R index ebd48b57..90132a7f 100644 --- a/scomps/R/interpret_computational_domain.R +++ b/scomps/R/interpret_computational_domain.R @@ -8,7 +8,8 @@ #' @param ny integer(1). The number of grids along y-axis. #' @param grid_min_features integer(1). A threshold to merging adjacent grids #' @param padding numeric(1). A extrusion factor to make buffer to clip actual datasets. Depending on the length unit of the CRS of input. -#' @param unit character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See \link{units package vignette (web)}{https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html} for the list of acceptable unit forms. +#' @param unit character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See [units package vignette (web)](https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html) for the list of acceptable unit forms. +#' @param ... arguments passed to the internal function #' @return A set of polygons in the input class #' @description TODO. Using input points, the bounding box is split to the predefined numbers of columns and rows. Each grid will be buffered by the radius. #' @author Insang Song @@ -52,7 +53,7 @@ sp_index_grid <- function(points_in, ncutsx, ncutsy){ sp_index_grid.sf = function(points_in, ncutsx, ncutsy) { grid1 <- sf::st_make_grid(points_in, n = c(ncutsx, ncutsy)) |> as.data.frame() |> - st_as_sf() + sf::st_as_sf() grid1 <- grid1[points_in, ] return(grid1) } @@ -82,14 +83,14 @@ sp_index_grid <- function(points_in, ncutsx, ncutsy){ #' # library(sf) #' # library(igraph) #' # ligrary(dplyr) -#' # dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -#' # st_crs(dg) = 5070 -#' # dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) +#' # dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +#' # sf::st_crs(dg) = 5070 +#' # dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) #' # dgs$CGRIDID = seq(1, nrow(dgs)) #' # #' # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -#' # st_crs(dg_sample) = st_crs(dg) -#' # dg_merged = grid_merge(st_as_sf(sss), dgs, 100) +#' # sf::st_crs(dg_sample) = sf::st_crs(dg) +#' # dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) #' #### NOT RUN #### #' @export grid_merge <- function(points_in, grid_in, grid_min_features){ @@ -113,7 +114,7 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ identified = unique(identified) identified = identified[sapply(identified, length) > 1] - identified_graph = lapply(identified, \(x) t(combn(x, 2))) |> + identified_graph = lapply(identified, \(x) t(utils::combn(x, 2))) |> Reduce(f = rbind, x = _) |> unique() |> apply(X = _, 2, as.character) |> @@ -137,8 +138,8 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ # grid_out[["CGRIDID"]][target_idx] = paste("M_", paste(target_idx, collapse = "_"), sep = "") # } grid_out = grid_out |> - dplyr::group_by(CGRIDID) |> - dplyr::summarize(n_merged = n()) |> + dplyr::group_by(!!rlang::sym("CGRIDID")) |> + dplyr::summarize(n_merged = dplyr::n()) |> dplyr::ungroup() ## polsby-popper test for shape compactness @@ -175,7 +176,7 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ #' #' @description Should #' @param grids sf/SpatVector object. Computational grids. -#' @param grid_id character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. "id_from:id_to" format or c(unique(grid_id)[id_from], unique(grid_id)[id_to]) +#' @param grid_id character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. \code{"id_from:id_to"} format or \code{c(unique(grid_id)[id_from], unique(grid_id)[id_to])} #' @param fun function supported in scomps. #' @param ... Arguments passed to fun. #' @return a data.frame object with mean value @@ -183,8 +184,7 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ #' #' @export distribute_process <- function(grids, grid_id = NULL, fun, ...) { - require(future.apply) - + # subset using grids and grid_id if (!is.null(grid_id)) { if (is.character(grid_id)) { @@ -202,7 +202,7 @@ distribute_process <- function(grids, grid_id = NULL, fun, ...) { results_distributed = future.apply::future_lapply( \(x, ...) { fun(...) - }, grids_target_list, points_cutslist, SIMPLIFY = FALSE, + }, grids_target_list, future.seed = TRUE) results_distributed = do.call(rbind, results_distributed) return(results_distributed) diff --git a/scomps/R/preprocessing.R b/scomps/R/preprocessing.R index 8f8f6cb8..93b3ad93 100644 --- a/scomps/R/preprocessing.R +++ b/scomps/R/preprocessing.R @@ -27,7 +27,8 @@ set_clip_extent <- function(pnts, buffer_r) { #' #' @param rasterpath character(1). Path to the raster file. #' @param win Named integer vector (4) or terra::ext() results. -#' @param author Insang Song +#' @return SpatRaster object. +#' @author Insang Song #' @export rast_short <- function(rasterpath, win) { terra::rast(rasterpath, win = win) diff --git a/scomps/R/processing.R b/scomps/R/processing.R index 3b08a05c..00b3e1d3 100644 --- a/scomps/R/processing.R +++ b/scomps/R/processing.R @@ -90,8 +90,8 @@ extract_with_polygons <- function( polys, surf, id, func = mean, na.rm = TRUE ) { # type check - stopifnot("Check class of the input points.\n" = any(is(polys, "sf"), is(polys, "SpatVector"))) - stopifnot("Check class of the input raster.\n" = any(is(surf, "stars"), is(surf, "SpatRaster"))) + stopifnot("Check class of the input points.\n" = any(methods::is(polys, "sf"), methods::is(polys, "SpatVector"))) + stopifnot("Check class of the input raster.\n" = any(methods::is(surf, "stars"), methods::is(surf, "SpatRaster"))) stopifnot(is.character(id)) cls_polys = check_packbound(polys) @@ -113,9 +113,9 @@ extract_with_polygons <- function( extract_with_polygons.terra = function(polys, surf, id, func) { extracted = terra::extract(surf, polys) extracted = extracted |> - group_by(!!sym(id)) |> - summarize(across(-!!sym(id), ~func)) |> - ungroup() + dplyr::group_by(!!rlang::sym(id)) |> + dplyr::summarize(dplyr::across(-!!rlang::sym(id), ~func)) |> + dplyr::ungroup() return(extracted) } @@ -157,7 +157,8 @@ extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) #' Calculate SEDC covariates #' @param point_from SpatVector object. Locations where the sum of SEDCs are calculated. #' @param point_to SpatVector object. Locations where each SEDC is calculated. -#' @param sdec_bandwidth numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 %) +#' @param id character(1). Name of the unique id field in point_to. +#' @param sedc_bandwidth numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 %) #' @param threshold numeric(1). For computational efficiency, the nearest points in threshold will be selected #' @param target_fields character(varying). Field names in characters. #' @description NOTE: sf implementation is pending. Only available for terra. @@ -185,16 +186,16 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, # summary near_from_to = near_from_to |> - as_tibble() |> - left_join(data.frame(point_from)) |> - left_join(data.frame(point_to)) |> - left_join(dist_near_to_df) |> + dplyr::as_tibble() |> + dplyr::left_join(data.frame(point_from)) |> + dplyr::left_join(data.frame(point_to)) |> + dplyr::left_join(dist_near_to_df) |> # per the definition in https://mserre.sph.unc.edu/BMElab_web/SEDCtutorial/index.html # exp(-3) is about 0.05 - mutate(w_sedc = exp((-3 * dist) / sedc_bandwidth)) |> - group_by(!!sym(id)) |> - summarize(across(all_of(target_fields), list(sedc = ~sum(w_sedc * ., na.rm = TRUE)))) |> - ungroup() + dplyr::mutate(w_sedc = exp((-3 * dist) / sedc_bandwidth)) |> + dplyr::group_by(!!rlang::sym(id)) |> + dplyr::summarize(dplyr::across(dplyr::all_of(target_fields), list(sedc = ~sum(w_sedc * ., na.rm = TRUE)))) |> + dplyr::ungroup() invisible(near_from_to) @@ -213,13 +214,13 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' library(sf) #' #' # run -#' nc = st_read(system.file("shape/nc.shp", package="sf")) -#' nc = st_transform(nc, 5070) -#' pp = st_sample(nc, size = 300) -#' pp = st_as_sf(pp) +#' nc = sf::st_read(system.file("shape/nc.shp", package="sf")) +#' nc = sf::st_transform(nc, 5070) +#' pp = sf::st_sample(nc, size = 300) +#' pp = sf::st_as_sf(pp) #' pp[["id"]] = seq(1, nrow(pp)) -#' st_crs(pp) = "EPSG:5070" -#' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +#' sf::st_crs(pp) = "EPSG:5070" +#' ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' #' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) #' summary(ppb_nc_aw) @@ -227,7 +228,7 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' @export aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { stopifnot("Inputs have invalid classes.\n" = - is(poly_in, "sf") || is(poly_weight, "sf") || is(poly_in, "SpatVector") || is(poly_weight, "SpatVector")) + methods::is(poly_in, "sf") || methods::is(poly_weight, "sf") || methods::is(poly_in, "SpatVector") || methods::is(poly_weight, "SpatVector")) #check_crs() ## distinguish numeric and nonnumeric columns @@ -239,8 +240,8 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { poly_intersected[["area_segment_"]] = terra::expanse(poly_intersected) poly_intersected = data.frame(poly_intersected) |> dplyr::group_by(!!rlang::sym(id_poly_in)) |> - dplyr::summarize(across(is.numeric, - ~weighted.mean(., w = area_segment_))) |> + dplyr::summarize(dplyr::across(is.numeric, + ~stats::weighted.mean(., w = area_segment_))) |> dplyr::ungroup() return(poly_intersected) } @@ -270,54 +271,6 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { #ncbufagg = terra::aggregate(ncbuf, by = 'id', fun = weighted.mean, w = ncbuf_a$segarea) -#' Subfunction: extract with buffers (flat weight; simple mean) -#' -#' @export -extract_with_buffer.flat <- function( - points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL - ) { - # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) - # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) - # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = - surf_at_bufs |> - group_by(ID) |> - summarize(across(all_of(name_surf_val), ~mean, na.rm=T)) |> - ungroup() - return(surf_at_bufs_summary) -} - -#' Subfunction: extract with buffers (kernel weight; weighted mean) -#' -#' @export -extract_with_buffer.kernel <- function( - points, surf, radius, id, qsegs, func = mean, kernel, bandwidth - ) { - # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) - # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) - - # TODO: kernel implementation - - - # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = - surf_at_bufs |> - group_by(ID) |> - summarize(across(all_of(name_surf_val), ~mean, na.rm=T)) |> - ungroup() - return(surf_at_bufs_summary) -} - #' @title Extract summarized values from raster with points and a buffer radius (to be written) #' #' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. @@ -337,7 +290,7 @@ extract_with_buffer <- function( points, surf, radius, id, qsegs = 90, func = mean, kernel = NULL, bandwidth = NULL ) { # type check - stopifnot("Check class of the input points.\n" = is(points, "SpatVector")) + stopifnot("Check class of the input points.\n" = methods::is(points, "SpatVector")) stopifnot("Check class of the input radius.\n" = is.numeric(radius)) stopifnot(is.character(id)) stopifnot(is.integer(qsegs)) @@ -364,5 +317,48 @@ extract_with_buffer <- function( } +# Subfunction: extract with buffers (flat weight; simple mean) +extract_with_buffer.flat <- function( + points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL + ) { + # generate buffers + bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + # crop raster + bufs_extent = terra::ext(bufs) + surf_cropped = terra::crop(surf, bufs_extent) + name_surf_val = names(surf) + # extract raster values + surf_at_bufs = terra::extract(surf_cropped, bufs) + surf_at_bufs_summary = + surf_at_bufs |> + dplyr::group_by(ID) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::ungroup() + return(surf_at_bufs_summary) +} + + +# Subfunction: extract with buffers (kernel weight; weighted mean) +extract_with_buffer.kernel <- function( + points, surf, radius, id, qsegs, func = mean, kernel, bandwidth + ) { + # generate buffers + bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + # crop raster + bufs_extent = terra::ext(bufs) + surf_cropped = terra::crop(surf, bufs_extent) + name_surf_val = names(surf) + # TODO: kernel implementation + + + # extract raster values + surf_at_bufs = terra::extract(surf_cropped, bufs) + surf_at_bufs_summary = + surf_at_bufs |> + dplyr::group_by(ID) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::ungroup() + return(surf_at_bufs_summary) +} diff --git a/scomps/R/switch_format.R b/scomps/R/switch_format.R index 6616caf1..a0c38e8f 100644 --- a/scomps/R/switch_format.R +++ b/scomps/R/switch_format.R @@ -7,7 +7,7 @@ #' @return Data converted to the other package class (if sf, terra; if terra, sf) #' @export switch_packbound <- function(input) { - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) cls_input = check_packbound(input) type_input = check_datatype(input) diff --git a/scomps/man/aw_covariates.Rd b/scomps/man/aw_covariates.Rd index 4604c030..ca836de6 100644 --- a/scomps/man/aw_covariates.Rd +++ b/scomps/man/aw_covariates.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/processing.R \name{aw_covariates} \alias{aw_covariates} \title{Computing area weighted covariates using two polygon sf or SpatVector objects} @@ -24,13 +24,13 @@ When poly_in and poly_weight are different classes, poly_weight will be converte library(sf) # run -nc = st_read(system.file("shape/nc.shp", package="sf")) -nc = st_transform(nc, 5070) -pp = st_sample(nc, size = 300) -pp = st_as_sf(pp) +nc = sf::st_read(system.file("shape/nc.shp", package="sf")) +nc = sf::st_transform(nc, 5070) +pp = sf::st_sample(nc, size = 300) +pp = sf::st_as_sf(pp) pp[["id"]] = seq(1, nrow(pp)) -st_crs(pp) = "EPSG:5070" -ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +sf::st_crs(pp) = "EPSG:5070" +ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) summary(ppb_nc_aw) @@ -38,4 +38,4 @@ summary(ppb_nc_aw) } \author{ Insang Song \email{geoissong@gmail.com} -} \ No newline at end of file +} diff --git a/scomps/man/calculate_sedc.Rd b/scomps/man/calculate_sedc.Rd index 0a164fbf..21178a77 100644 --- a/scomps/man/calculate_sedc.Rd +++ b/scomps/man/calculate_sedc.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/processing.R \name{calculate_sedc} \alias{calculate_sedc} \title{Calculate SEDC covariates} @@ -18,15 +18,17 @@ calculate_sedc( \item{point_to}{SpatVector object. Locations where each SEDC is calculated.} +\item{id}{character(1). Name of the unique id field in point_to.} + +\item{sedc_bandwidth}{numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 \%)} + \item{threshold}{numeric(1). For computational efficiency, the nearest points in threshold will be selected} \item{target_fields}{character(varying). Field names in characters.} - -\item{sdec_bandwidth}{numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 \%)} } \description{ NOTE: sf implementation is pending. Only available for terra. } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/check_bbox.Rd b/scomps/man/check_bbox.Rd index f5d0fbde..444c934a 100644 --- a/scomps/man/check_bbox.Rd +++ b/scomps/man/check_bbox.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/check.R \name{check_bbox} \alias{check_bbox} \title{Check if the data extent is inside the reference bounding box} @@ -21,4 +21,4 @@ One of the most common errors in spatial computation is rooted in the entirely o } \author{ Insang Song \email{geoissong@gmail.com} -} \ No newline at end of file +} diff --git a/scomps/man/check_crs.Rd b/scomps/man/check_crs.Rd index ad8edfa3..6f9fa5b5 100644 --- a/scomps/man/check_crs.Rd +++ b/scomps/man/check_crs.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/check.R \name{check_crs} \alias{check_crs} \title{Check Coordinate Reference System} @@ -25,4 +25,4 @@ check_crs(nc) } \author{ Insang Song \email{geoissong@gmail.com} -} \ No newline at end of file +} diff --git a/scomps/man/check_crs2.Rd b/scomps/man/check_crs2.Rd index b4020d6f..c15652d6 100644 --- a/scomps/man/check_crs2.Rd +++ b/scomps/man/check_crs2.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/check.R \name{check_crs2} \alias{check_crs2} \title{check_crs2: Coordinate system checker} @@ -8,10 +8,12 @@ check_crs2(input, crs_standard = "EPSG:4326") } \arguments{ \item{input}{Input object one of sf or terra::Spat* object} + +\item{crs_standard}{character(1). A standard definition of coordinate reference system. Default is "EPSG:4326" Consult \href{https://epsg.io}{epsg.io} for details of other CRS.} } \value{ A (reprojected) sf or SpatVector object. } \description{ The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179. -} \ No newline at end of file +} diff --git a/scomps/man/check_packbound.Rd b/scomps/man/check_packbound.Rd index d2fcc528..6bda7485 100644 --- a/scomps/man/check_packbound.Rd +++ b/scomps/man/check_packbound.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/check.R \name{check_packbound} \alias{check_packbound} \title{Return the package the input object is based on} @@ -17,4 +17,4 @@ Detect whether the input object is sf or Spat* object. } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/check_within_reference.Rd b/scomps/man/check_within_reference.Rd index 493f1f8c..c193a975 100644 --- a/scomps/man/check_within_reference.Rd +++ b/scomps/man/check_within_reference.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/check.R \name{check_within_reference} \alias{check_within_reference} \title{Check if the boundary of the vector/raster object is inside the reference} @@ -19,4 +19,4 @@ Check if the boundary of the vector/raster object is inside the reference } \author{ Insang Song \email{geoissong@gmail.com} -} \ No newline at end of file +} diff --git a/scomps/man/clip_as_extent.Rd b/scomps/man/clip_as_extent.Rd index 00eaa5fa..06ec0bbf 100644 --- a/scomps/man/clip_as_extent.Rd +++ b/scomps/man/clip_as_extent.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/processing.R \name{clip_as_extent} \alias{clip_as_extent} \title{Extent clipping} @@ -23,4 +23,4 @@ Clip input vector by the expected maximum extent of computation. } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/clip_as_extent_ras.Rd b/scomps/man/clip_as_extent_ras.Rd index 3e756887..e6762901 100644 --- a/scomps/man/clip_as_extent_ras.Rd +++ b/scomps/man/clip_as_extent_ras.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/processing.R \name{clip_as_extent_ras} \alias{clip_as_extent_ras} \title{clip_as_extent_ras: Clip input raster.} @@ -20,4 +20,4 @@ Clip input raster by the expected maximum extent of computation. } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/clip_as_extent_ras2.Rd b/scomps/man/clip_as_extent_ras2.Rd index 8aa6a6d7..6d8c0e00 100644 --- a/scomps/man/clip_as_extent_ras2.Rd +++ b/scomps/man/clip_as_extent_ras2.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/processing.R \name{clip_as_extent_ras2} \alias{clip_as_extent_ras2} \title{clip_as_extent_ras2: Clip input raster (version 2).} @@ -20,4 +20,4 @@ Clip input raster by the expected maximum extent of computation. } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/distribute_process.Rd b/scomps/man/distribute_process.Rd index b5403e59..ebb58e82 100644 --- a/scomps/man/distribute_process.Rd +++ b/scomps/man/distribute_process.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/interpret_computational_domain.R \name{distribute_process} \alias{distribute_process} \title{Process a given function in the entire or partial computational grids (under construction)} @@ -9,7 +9,7 @@ distribute_process(grids, grid_id = NULL, fun, ...) \arguments{ \item{grids}{sf/SpatVector object. Computational grids.} -\item{grid_id}{character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. "id_from:id_to" format or c(unique(grid_id)\link{id_from}, unique(grid_id)\link{id_to})} +\item{grid_id}{character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. \code{"id_from:id_to"} format or \code{c(unique(grid_id)[id_from], unique(grid_id)[id_to])}} \item{fun}{function supported in scomps.} @@ -23,4 +23,4 @@ Should } \author{ Insang Song \email{geoissong@gmail.com} -} \ No newline at end of file +} diff --git a/scomps/man/estimate_demands.Rd b/scomps/man/estimate_demands.Rd index e269257e..787ad77f 100644 --- a/scomps/man/estimate_demands.Rd +++ b/scomps/man/estimate_demands.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/estimate_demands.R \name{estimate_demands} \alias{estimate_demands} \title{Estimate computational demands from inputs (to be written)} @@ -17,4 +17,7 @@ estimate_demands(inputs, nx, ny, padding) } \description{ Estimate computational demands from inputs (to be written) -} \ No newline at end of file +} +\author{ +Insang Song +} diff --git a/scomps/man/extent_to_polygon.Rd b/scomps/man/extent_to_polygon.Rd new file mode 100644 index 00000000..2874461e --- /dev/null +++ b/scomps/man/extent_to_polygon.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check.R +\name{extent_to_polygon} +\alias{extent_to_polygon} +\title{Generate a rectangular polygon from extent} +\usage{ +extent_to_polygon(extent, output_class = "terra", crs = "EPSG:4326") +} +\arguments{ +\item{extent}{input extent. A numeric vector with xmin/xmax/ymin/ymax, sf::st_bbox() or terra::ext() outputs.} + +\item{output_class}{character(1). Class of the output polygon. One of "sf" or "terra"} + +\item{crs}{character(1). Coordinate reference system definition.} +} +\description{ +Generate a rectangular polygon from extent +} +\author{ +Insang Song +} diff --git a/scomps/man/extract_with.Rd b/scomps/man/extract_with.Rd index d95b9bbb..8794f571 100644 --- a/scomps/man/extract_with.Rd +++ b/scomps/man/extract_with.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/processing.R \name{extract_with} \alias{extract_with} \title{Extract raster values with point buffers or polygons} @@ -24,4 +24,4 @@ Extract raster values with point buffers or polygons } \author{ Insang Song \email{geoissong@gmail.com} -} \ No newline at end of file +} diff --git a/scomps/man/extract_with_buffer.Rd b/scomps/man/extract_with_buffer.Rd index 662fc6e6..f0c3943d 100644 --- a/scomps/man/extract_with_buffer.Rd +++ b/scomps/man/extract_with_buffer.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/processing.R \name{extract_with_buffer} \alias{extract_with_buffer} \title{Extract summarized values from raster with points and a buffer radius (to be written)} @@ -40,4 +40,4 @@ For simplicity, it is assumed that the coordinate systems of the points and the } \author{ Insang Song \email{geoissong@gmail.com} -} \ No newline at end of file +} diff --git a/scomps/man/extract_with_buffer.flat.Rd b/scomps/man/extract_with_buffer.flat.Rd deleted file mode 100644 index 15215897..00000000 --- a/scomps/man/extract_with_buffer.flat.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. -\name{extract_with_buffer.flat} -\alias{extract_with_buffer.flat} -\title{Subfunction: extract with buffers (flat weight; simple mean)} -\usage{ -extract_with_buffer.flat( - points, - surf, - radius, - id, - qsegs, - func = mean, - kernel = NULL, - bandwidth = NULL -) -} -\description{ -Subfunction: extract with buffers (flat weight; simple mean) -} \ No newline at end of file diff --git a/scomps/man/extract_with_buffer.kernel.Rd b/scomps/man/extract_with_buffer.kernel.Rd deleted file mode 100644 index f00f2640..00000000 --- a/scomps/man/extract_with_buffer.kernel.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. -\name{extract_with_buffer.kernel} -\alias{extract_with_buffer.kernel} -\title{Subfunction: extract with buffers (kernel weight; weighted mean)} -\usage{ -extract_with_buffer.kernel( - points, - surf, - radius, - id, - qsegs, - func = mean, - kernel, - bandwidth -) -} -\description{ -Subfunction: extract with buffers (kernel weight; weighted mean) -} \ No newline at end of file diff --git a/scomps/man/extract_with_polygons.Rd b/scomps/man/extract_with_polygons.Rd index ca56635e..adaa9c6a 100644 --- a/scomps/man/extract_with_polygons.Rd +++ b/scomps/man/extract_with_polygons.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/processing.R \name{extract_with_polygons} \alias{extract_with_polygons} \title{Extract summarized values from raster with generic polygons} @@ -25,4 +25,4 @@ For simplicity, it is assumed that the coordinate systems of the points and the } \author{ Insang Song \email{geoissong@gmail.com} -} \ No newline at end of file +} diff --git a/scomps/man/get_computational_regions.Rd b/scomps/man/get_computational_regions.Rd index 91f578d9..6a864a55 100644 --- a/scomps/man/get_computational_regions.Rd +++ b/scomps/man/get_computational_regions.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/interpret_computational_domain.R \name{get_computational_regions} \alias{get_computational_regions} \title{Get a set of computational regions} @@ -28,7 +28,9 @@ get_computational_regions( \item{padding}{numeric(1). A extrusion factor to make buffer to clip actual datasets. Depending on the length unit of the CRS of input.} -\item{unit}{character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See \link{units package vignette (web)}{https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html} for the list of acceptable unit forms.} +\item{unit}{character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See \href{https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html}{units package vignette (web)} for the list of acceptable unit forms.} + +\item{...}{arguments passed to the internal function} } \value{ A set of polygons in the input class @@ -48,4 +50,4 @@ nc = st_transform(nc, "EPSG:5070") } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/grid_merge.Rd b/scomps/man/grid_merge.Rd index 614e7ba9..0361cece 100644 --- a/scomps/man/grid_merge.Rd +++ b/scomps/man/grid_merge.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/interpret_computational_domain.R \name{grid_merge} \alias{grid_merge} \title{grid_merge: Merge grid polygons with given rules} @@ -23,16 +23,16 @@ Merge boundary-sharing (in "Rook" contiguity) grids with fewer target features t # library(sf) # library(igraph) # ligrary(dplyr) -# dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -# st_crs(dg) = 5070 -# dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) +# dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +# sf::st_crs(dg) = 5070 +# dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) # dgs$CGRIDID = seq(1, nrow(dgs)) # # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -# st_crs(dg_sample) = st_crs(dg) -# dg_merged = grid_merge(st_as_sf(sss), dgs, 100) +# sf::st_crs(dg_sample) = sf::st_crs(dg) +# dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) #### NOT RUN #### } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/initate_log.Rd b/scomps/man/initate_log.Rd index a4f1fb02..6e64c090 100644 --- a/scomps/man/initate_log.Rd +++ b/scomps/man/initate_log.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/logging.R \name{initate_log} \alias{initate_log} \title{Turn on logging} @@ -21,4 +21,4 @@ Turn on logging } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/rast_short.Rd b/scomps/man/rast_short.Rd index 02a91ccb..de4acd9f 100644 --- a/scomps/man/rast_short.Rd +++ b/scomps/man/rast_short.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/preprocessing.R \name{rast_short} \alias{rast_short} \title{Quick call for SpatRaster with a window} @@ -10,9 +10,13 @@ rast_short(rasterpath, win) \item{rasterpath}{character(1). Path to the raster file.} \item{win}{Named integer vector (4) or terra::ext() results.} - -\item{author}{Insang Song} +} +\value{ +SpatRaster object. } \description{ Quick call for SpatRaster with a window -} \ No newline at end of file +} +\author{ +Insang Song +} diff --git a/scomps/man/set_clip_extent.Rd b/scomps/man/set_clip_extent.Rd index 5d9267d4..4fb91191 100644 --- a/scomps/man/set_clip_extent.Rd +++ b/scomps/man/set_clip_extent.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/preprocessing.R \name{set_clip_extent} \alias{set_clip_extent} \title{Setting the clipping extent} @@ -19,4 +19,4 @@ Return clipping extent with buffer radius. It assumes the input CRS is projected } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/sp_index_grid.Rd b/scomps/man/sp_index_grid.Rd index 9a492214..bf0d4ac5 100644 --- a/scomps/man/sp_index_grid.Rd +++ b/scomps/man/sp_index_grid.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/interpret_computational_domain.R \name{sp_index_grid} \alias{sp_index_grid} \title{sp_index_grid: Generate grid polygons} @@ -21,4 +21,4 @@ Returns a sf object that includes x- and y- index by using two inputs ncutsx and } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/sp_indexing.Rd b/scomps/man/sp_indexing.Rd index 56dccd96..f4da1434 100644 --- a/scomps/man/sp_indexing.Rd +++ b/scomps/man/sp_indexing.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/indexing.R \name{sp_indexing} \alias{sp_indexing} \title{Create integer indices for grid} @@ -18,4 +18,4 @@ Returns a tibble object that includes x- and y- index by using two inputs ncutsx } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/switch_packbound.Rd b/scomps/man/switch_packbound.Rd index 084fb468..18eafb22 100644 --- a/scomps/man/switch_packbound.Rd +++ b/scomps/man/switch_packbound.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/switch_format.R \name{switch_packbound} \alias{switch_packbound} \title{Switch spatial data class} @@ -17,4 +17,4 @@ Convert stars into SpatRaster and vice versa; sf into SpatVector and vice versa. } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/man/validate_and_repair_vectors.Rd b/scomps/man/validate_and_repair_vectors.Rd index 539ef863..e8447ca9 100644 --- a/scomps/man/validate_and_repair_vectors.Rd +++ b/scomps/man/validate_and_repair_vectors.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in scomps_rmarkdown_litr.rmd. +% Please edit documentation in R/validate.R \name{validate_and_repair_vectors} \alias{validate_and_repair_vectors} \title{Validate and repair input vector data} @@ -17,4 +17,4 @@ It tries repairing input vector data. Vector validity violation usually appears } \author{ Insang Song -} \ No newline at end of file +} diff --git a/scomps/vignettes/v00_good_practice_parallelization.Rmd b/scomps/vignettes/v00_good_practice_parallelization.Rmd new file mode 100644 index 00000000..8966a59d --- /dev/null +++ b/scomps/vignettes/v00_good_practice_parallelization.Rmd @@ -0,0 +1,39 @@ +--- +title: "Good practice of scomps with HPC" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{good_practice_hpc} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + + +```{r} +knitr::opts_chunk$set(warning = FALSE, message = FALSE) + +``` + +## Assumptions +- Users have an accessible HPC at your work +- Data are stored in distributed file systems (usually incorporated into the HPC system) + + +## Basic workflow + +### Practice for minimizing errors +- Consider using `try()` or `tryCatch()` not to a tiny error will halt all the work without any results + - Especially with the higher-level functions +- "IPDE -- Inspect, Predict, Decide, Execute" all the time + +### Raster-Vector overlay +- Make `sp_index_grid()` to get padded grid objects +- Convert sf/SpatVector objects into `terra::ext()` compatible named numeric vector + - For example: `c(xmin=0, ymin=0, xmax=10, ymax=10)` +- Make list objects with: + - An extent vector in each element + - Preprocessed vector objects with respect to each extent vector in the first list + - Preferably all lists are named +- Write a `future.apply` script running through the extent list object +- Run a small amount of data to estimate the total computational demand +- Submit a job with a proper amount of computational assets diff --git a/scomps/vignettes/v01_generate_computational_grid.Rmd b/scomps/vignettes/v01_generate_computational_grid.Rmd new file mode 100644 index 00000000..4bc1aaf2 --- /dev/null +++ b/scomps/vignettes/v01_generate_computational_grid.Rmd @@ -0,0 +1,46 @@ +--- +title: "Generate computational grids" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{computational_grids} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + + +```{r} +knitr::opts_chunk$set(warning = FALSE, message = FALSE) + +``` + + +## Prepare input data +```{r} +library(scomps) +library(sf) +library(terra) +library(stars) +library(dplyr) + +``` + +## Computational grids +```{r} +# your_grid = scomps::sp_index_grid() + +``` + + +## Visualize computational grids +```{r} +# library(mapsf) +# mf_map(your_grid$geometry) + + +``` + + + +## Notes +- Computational grids are the exhaustive split of the entire study region. You should take a square buffer of each grid to clip the target raster or vector. diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index 55aba55e..44adce73 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -11,7 +11,7 @@ - + Creating the scomps R package @@ -353,7 +353,7 @@

Creating the scomps R package

Insang Song

-

2023-09-03

+

2023-10-04

@@ -368,7 +368,7 @@

Package setup

path = ".", fields = list( Package = params$package_name, - Version = "0.0.2.10032023", + Version = "0.0.3.10042023", Title = "Scalable R geospatial computation", Description = "A package for scalable geospatial computation for environmental health research", `Authors@R` = person( @@ -388,6 +388,8 @@

Package setup

usethis::use_package("stars") usethis::use_package("rlang") # Default is "Imports" usethis::use_package("testthat") +usethis::use_package("units") +usethis::use_package("methods") usethis::use_package("logr", "Suggests") # Default is "Imports" usethis::use_package("future") # Default is "Imports" usethis::use_package("future.apply") # Default is "Imports" @@ -407,11 +409,11 @@

Package setup

Vignettes 1

-
litr::add_vignettes("../tools/vignettes-sources/00_good_practice_parallelization.Rmd")
+
litr::add_vignettes("../tools/vignettes-sources/v00_good_practice_parallelization.Rmd")

Vignettes 2

-
litr::add_vignettes("../tools/vignettes-sources/01_generate_computational_grid.Rmd")
+
litr::add_vignettes("../tools/vignettes-sources/v01_generate_computational_grid.Rmd")
@@ -426,19 +428,19 @@

Create functions

#' @export check_packbound <- function(input) { # cl_inobj = class(input)[1] - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) - if (is(input, "SpatVector") || is(input, "SpatRaster")) { + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) + if (methods::is(input, "SpatVector") || methods::is(input, "SpatRaster")) { return("terra") } return("sf") } check_datatype <- function(input) { - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) - if (any(is(input, "SpatVector"), is(input, "sf"))) { + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) + if (any(methods::is(input, "SpatVector"), methods::is(input, "sf"))) { return("vector") } - if (any(is(input, "SpatRaster"), is(input, "stars"))) { + if (any(methods::is(input, "SpatRaster"), methods::is(input, "stars"))) { return("raster") } }
@@ -487,7 +489,7 @@

Create functions

#' @return Data converted to the other package class (if sf, terra; if terra, sf) #' @export switch_packbound <- function(input) { - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) cls_input = check_packbound(input) type_input = check_datatype(input) @@ -536,11 +538,12 @@

Create functions

#' @title check_crs2: Coordinate system checker
 #' @description The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179.
 #' @param input Input object one of sf or terra::Spat* object
+#' @param crs_standard character(1). A standard definition of coordinate reference system. Default is "EPSG:4326" Consult [epsg.io](https://epsg.io) for details of other CRS.
 #' @return A (reprojected) sf or SpatVector object.
 #' @export
 check_crs2 <- function(input, crs_standard = "EPSG:4326") {
   check_crs.sf <- function(input){
-    if (is.na(st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)}
+    if (is.na(sf::st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)}
     if (sf::st_crs(input)$epsg == crs_standard ) {
       return(input)
     } 
@@ -697,7 +700,7 @@ 

Create functions

sp_indexing <- function(points_in, ncutsx, ncutsy){ # pts <- data.table(pnts) points_in <- points_in |> - mutate(or_id = seq(1, dim(points_in)[1])) + dplyr::mutate(or_id = seq(1, dim(points_in)[1])) range_x <- range(points_in$x) limits_x <- (range_x[1] + seq(0, ncutsx) * (range_x[2] - range_x[1]) / ncutsx) @@ -705,7 +708,7 @@

Create functions

limits_y <- (range_y[1] + seq(0, ncutsy) * (range_y[2] - range_y[1]) / ncutsy) points_in_cut <- points_in |> - mutate(xcut = as.integer(cut(x, ncutsx, labels = seq(1, ncutsx))), + dplyr::mutate(xcut = as.integer(cut(x, ncutsx, labels = seq(1, ncutsx))), ycut = as.integer(cut(y, ncutsy, labels = seq(1, ncutsy)))) return(points_in_cut) @@ -714,7 +717,8 @@

Create functions

#' #' @param rasterpath character(1). Path to the raster file. #' @param win Named integer vector (4) or terra::ext() results. -#' @param author Insang Song +#' @return SpatRaster object. +#' @author Insang Song #' @export rast_short <- function(rasterpath, win) { terra::rast(rasterpath, win = win) @@ -726,6 +730,7 @@

Create functions

#' @param nx integer(1). #' @param ny integer(1). #' @param padding numeric(1). Extrusion factor +#' @author Insang Song #' @export estimate_demands <- function( inputs, @@ -749,7 +754,8 @@

Create functions

#' @param ny integer(1). The number of grids along y-axis. #' @param grid_min_features integer(1). A threshold to merging adjacent grids #' @param padding numeric(1). A extrusion factor to make buffer to clip actual datasets. Depending on the length unit of the CRS of input. -#' @param unit character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See \link{units package vignette (web)}{https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html} for the list of acceptable unit forms. +#' @param unit character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See [units package vignette (web)](https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html) for the list of acceptable unit forms. +#' @param ... arguments passed to the internal function #' @return A set of polygons in the input class #' @description TODO. Using input points, the bounding box is split to the predefined numbers of columns and rows. Each grid will be buffered by the radius. #' @author Insang Song @@ -793,7 +799,7 @@

Create functions

sp_index_grid.sf = function(points_in, ncutsx, ncutsy) { grid1 <- sf::st_make_grid(points_in, n = c(ncutsx, ncutsy)) |> as.data.frame() |> - st_as_sf() + sf::st_as_sf() grid1 <- grid1[points_in, ] return(grid1) } @@ -823,14 +829,14 @@

Create functions

#' # library(sf) #' # library(igraph) #' # ligrary(dplyr) -#' # dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -#' # st_crs(dg) = 5070 -#' # dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) +#' # dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +#' # sf::st_crs(dg) = 5070 +#' # dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) #' # dgs$CGRIDID = seq(1, nrow(dgs)) #' # #' # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -#' # st_crs(dg_sample) = st_crs(dg) -#' # dg_merged = grid_merge(st_as_sf(sss), dgs, 100) +#' # sf::st_crs(dg_sample) = sf::st_crs(dg) +#' # dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) #' #### NOT RUN #### #' @export grid_merge <- function(points_in, grid_in, grid_min_features){ @@ -854,7 +860,7 @@

Create functions

identified = unique(identified) identified = identified[sapply(identified, length) > 1] - identified_graph = lapply(identified, \(x) t(combn(x, 2))) |> + identified_graph = lapply(identified, \(x) t(utils::combn(x, 2))) |> Reduce(f = rbind, x = _) |> unique() |> apply(X = _, 2, as.character) |> @@ -878,8 +884,8 @@

Create functions

# grid_out[["CGRIDID"]][target_idx] = paste("M_", paste(target_idx, collapse = "_"), sep = "") # } grid_out = grid_out |> - dplyr::group_by(CGRIDID) |> - dplyr::summarize(n_merged = n()) |> + dplyr::group_by(!!rlang::sym("CGRIDID")) |> + dplyr::summarize(n_merged = dplyr::n()) |> dplyr::ungroup() ## polsby-popper test for shape compactness @@ -910,6 +916,44 @@

Create functions

} +
+
#' Generate a rectangular polygon from extent
+#' 
+#' @param extent input extent. A numeric vector with xmin/xmax/ymin/ymax, sf::st_bbox() or terra::ext() outputs.
+#' @param output_class character(1). Class of the output polygon. One of "sf" or "terra"
+#' @param crs character(1). Coordinate reference system definition.
+#' @author Insang Song
+#' @export
+extent_to_polygon <- function(extent, output_class = "terra", crs = "EPSG:4326") {
+  if (!output_class %in% c("sf", "terra")) {
+    stop("output_class should be one of 'sf' or 'terra'.\n")
+  }
+  if (methods::is(extent, "numeric")) {
+    if (is.null(attr(extent, "names"))) {
+      stop("Your extent is an unnamed numeric vector. Please define names xmin/xmax/ymin/ymax explicitly.\n")
+    }
+    extent = switch(
+      output_class,
+      sf = sf::st_bbox(extent),
+      terra = terra::ext(extent)
+    )
+  }
+
+  extent_polygon = switch(
+    output_class,
+    sf = sf::st_as_sfc(extent),
+    terra = terra::vect(extent)
+  )
+
+  extent_polygon = switch(
+    output_class,
+    sf = sf::st_set_crs(extent_polygon, sf::st_crs(crs)),
+    terra = terra::set.crs(extent_polygon, terra::crs(crs))
+  )
+
+  return(extent_polygon)
+  
+}
 
#' Check if the data extent is inside the reference bounding box
 #' 
@@ -935,25 +979,14 @@ 

Create functions

if (is.na(query_crs) || is.null(query_crs)) { stop("The dataset you queried has no CRS. Please make sure your dataset has the correct CRS.\n") } + query_matched = sf::st_transform(data_query, sf::st_crs(ref_crs)) + - # ... - check_result + check_result = sf::st_within() return(check_result) } -
-
#' Check if the data extent is inside the reference bounding box
-#' 
-#' @description One of the most common errors in spatial computation is rooted in the entirely or partly incomparable spatial extents of input datasets. This function returns whether your data is inside the target computational extent. It is assumed that you know and have the exact computational region. This function will return TRUE if the reference region completely contains your data's extent and FALSE otherwise.
-#' @param data_query sf*/stars/SpatVector/SpatRaster object.
-#' @param reference sf*/stars/SpatVector/SpatRaster object or a named numeric vector with four names (xmin, ymin, xmax, and ymax).
-#' @param reference_crs Well-known-text-formatted or EPSG code of the reference's coordinate system. Only required when a named numeric vector is passed to reference. 
-#' @return TRUE (the queried data extent is completely within the reference bounding box) or FALSE 
-#' @author Insang Song \email{geoissong@@gmail.com}
-#' 
-#' @export
-
 
#' @title Extract summarized values from raster with generic polygons
 #' 
@@ -971,8 +1004,8 @@ 

Create functions

polys, surf, id, func = mean, na.rm = TRUE ) { # type check - stopifnot("Check class of the input points.\n" = any(is(polys, "sf"), is(polys, "SpatVector"))) - stopifnot("Check class of the input raster.\n" = any(is(surf, "stars"), is(surf, "SpatRaster"))) + stopifnot("Check class of the input points.\n" = any(methods::is(polys, "sf"), methods::is(polys, "SpatVector"))) + stopifnot("Check class of the input raster.\n" = any(methods::is(surf, "stars"), methods::is(surf, "SpatRaster"))) stopifnot(is.character(id)) cls_polys = check_packbound(polys) @@ -994,9 +1027,9 @@

Create functions

extract_with_polygons.terra = function(polys, surf, id, func) { extracted = terra::extract(surf, polys) extracted = extracted |> - group_by(!!sym(id)) |> - summarize(across(-!!sym(id), ~func)) |> - ungroup() + dplyr::group_by(!!rlang::sym(id)) |> + dplyr::summarize(dplyr::across(-!!rlang::sym(id), ~func)) |> + dplyr::ungroup() return(extracted) } @@ -1047,9 +1080,9 @@

Create functions

#' #' @export check_crs <- function(x) { - stopifnot("Input is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) + stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) - if (is(x, "sf") || is(x, "stars")) { + if (methods::is(x, "sf") || methods::is(x, "stars")) { crs_wkt = sf::st_crs(x) } else { crs_wkt = terra::crs(x) @@ -1065,8 +1098,8 @@

Create functions

#' @author Insang Song \email{geoissong@@gmail.com} #' @export check_within_reference <- function(input_object, reference) { - stopifnot("Input is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) - stopifnot("Reference is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) + stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) + stopifnot("Reference is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) bbox_input <- input_object sf::st_bbox() |> @@ -1086,7 +1119,8 @@

Create functions

#' Calculate SEDC covariates
 #' @param point_from SpatVector object. Locations where the sum of SEDCs are calculated.
 #' @param point_to SpatVector object. Locations where each SEDC is calculated.
-#' @param sdec_bandwidth numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 %)  
+#' @param id character(1). Name of the unique id field in point_to.
+#' @param sedc_bandwidth numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 %)  
 #' @param threshold numeric(1). For computational efficiency, the nearest points in threshold will be selected
 #' @param target_fields character(varying). Field names in characters.
 #' @description NOTE: sf implementation is pending. Only available for terra.
@@ -1114,16 +1148,16 @@ 

Create functions

# summary near_from_to = near_from_to |> - as_tibble() |> - left_join(data.frame(point_from)) |> - left_join(data.frame(point_to)) |> - left_join(dist_near_to_df) |> + dplyr::as_tibble() |> + dplyr::left_join(data.frame(point_from)) |> + dplyr::left_join(data.frame(point_to)) |> + dplyr::left_join(dist_near_to_df) |> # per the definition in https://mserre.sph.unc.edu/BMElab_web/SEDCtutorial/index.html # exp(-3) is about 0.05 - mutate(w_sedc = exp((-3 * dist) / sedc_bandwidth)) |> - group_by(!!sym(id)) |> - summarize(across(all_of(target_fields), list(sedc = ~sum(w_sedc * ., na.rm = TRUE)))) |> - ungroup() + dplyr::mutate(w_sedc = exp((-3 * dist) / sedc_bandwidth)) |> + dplyr::group_by(!!rlang::sym(id)) |> + dplyr::summarize(dplyr::across(dplyr::all_of(target_fields), list(sedc = ~sum(w_sedc * ., na.rm = TRUE)))) |> + dplyr::ungroup() invisible(near_from_to) @@ -1141,13 +1175,13 @@

Create functions

#' library(sf) #' #' # run -#' nc = st_read(system.file("shape/nc.shp", package="sf")) -#' nc = st_transform(nc, 5070) -#' pp = st_sample(nc, size = 300) -#' pp = st_as_sf(pp) +#' nc = sf::st_read(system.file("shape/nc.shp", package="sf")) +#' nc = sf::st_transform(nc, 5070) +#' pp = sf::st_sample(nc, size = 300) +#' pp = sf::st_as_sf(pp) #' pp[["id"]] = seq(1, nrow(pp)) -#' st_crs(pp) = "EPSG:5070" -#' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +#' sf::st_crs(pp) = "EPSG:5070" +#' ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' #' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) #' summary(ppb_nc_aw) @@ -1155,7 +1189,7 @@

Create functions

#' @export aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { stopifnot("Inputs have invalid classes.\n" = - is(poly_in, "sf") || is(poly_weight, "sf") || is(poly_in, "SpatVector") || is(poly_weight, "SpatVector")) + methods::is(poly_in, "sf") || methods::is(poly_weight, "sf") || methods::is(poly_in, "SpatVector") || methods::is(poly_weight, "SpatVector")) #check_crs() ## distinguish numeric and nonnumeric columns @@ -1167,8 +1201,8 @@

Create functions

poly_intersected[["area_segment_"]] = terra::expanse(poly_intersected) poly_intersected = data.frame(poly_intersected) |> dplyr::group_by(!!rlang::sym(id_poly_in)) |> - dplyr::summarize(across(is.numeric, - ~weighted.mean(., w = area_segment_))) |> + dplyr::summarize(dplyr::across(is.numeric, + ~stats::weighted.mean(., w = area_segment_))) |> dplyr::ungroup() return(poly_intersected) } @@ -1197,52 +1231,6 @@

Create functions

#ncbufagg = terra::aggregate(ncbuf, by = 'id', fun = weighted.mean, w = ncbuf_a$segarea)
-
#' Subfunction: extract with buffers (flat weight; simple mean)
-#' 
-#' @export 
-extract_with_buffer.flat <- function(
-        points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL
-    ) {
-    # generate buffers
-    bufs = terra::buffer(points, width = radius, quadsegs = qsegs)
-    # crop raster
-    bufs_extent = terra::ext(bufs)
-    surf_cropped = terra::crop(surf, bufs_extent)
-    name_surf_val = names(surf)
-    # extract raster values
-    surf_at_bufs = terra::extract(surf_cropped, bufs)
-    surf_at_bufs_summary = 
-        surf_at_bufs |> 
-            group_by(ID) |> 
-            summarize(across(all_of(name_surf_val), ~mean, na.rm=T)) |> 
-            ungroup()
-    return(surf_at_bufs_summary)
-}
-
#' Subfunction: extract with buffers (kernel weight; weighted mean)
-#'
-#' @export 
-extract_with_buffer.kernel <- function(
-        points, surf, radius, id, qsegs, func = mean, kernel, bandwidth
-    ) {
-        # generate buffers
-        bufs = terra::buffer(points, width = radius, quadsegs = qsegs)
-        # crop raster
-        bufs_extent = terra::ext(bufs)
-        surf_cropped = terra::crop(surf, bufs_extent)
-        name_surf_val = names(surf)
-
-        # TODO: kernel implementation
-
-
-        # extract raster values
-        surf_at_bufs = terra::extract(surf_cropped, bufs)
-        surf_at_bufs_summary = 
-            surf_at_bufs |> 
-                group_by(ID) |> 
-                summarize(across(all_of(name_surf_val), ~mean, na.rm=T)) |> 
-                ungroup()
-        return(surf_at_bufs_summary)
-}
#' @title Extract summarized values from raster with points and a buffer radius (to be written)
 #' 
 #' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. 
@@ -1262,7 +1250,7 @@ 

Create functions

points, surf, radius, id, qsegs = 90, func = mean, kernel = NULL, bandwidth = NULL ) { # type check - stopifnot("Check class of the input points.\n" = is(points, "SpatVector")) + stopifnot("Check class of the input points.\n" = methods::is(points, "SpatVector")) stopifnot("Check class of the input radius.\n" = is.numeric(radius)) stopifnot(is.character(id)) stopifnot(is.integer(qsegs)) @@ -1289,13 +1277,56 @@

Create functions

} +# Subfunction: extract with buffers (flat weight; simple mean) +extract_with_buffer.flat <- function( + points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL + ) { + # generate buffers + bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + # crop raster + bufs_extent = terra::ext(bufs) + surf_cropped = terra::crop(surf, bufs_extent) + name_surf_val = names(surf) + # extract raster values + surf_at_bufs = terra::extract(surf_cropped, bufs) + surf_at_bufs_summary = + surf_at_bufs |> + dplyr::group_by(ID) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::ungroup() + return(surf_at_bufs_summary) +} + + +# Subfunction: extract with buffers (kernel weight; weighted mean) +extract_with_buffer.kernel <- function( + points, surf, radius, id, qsegs, func = mean, kernel, bandwidth + ) { + # generate buffers + bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + # crop raster + bufs_extent = terra::ext(bufs) + surf_cropped = terra::crop(surf, bufs_extent) + name_surf_val = names(surf) + # TODO: kernel implementation + + + # extract raster values + surf_at_bufs = terra::extract(surf_cropped, bufs) + surf_at_bufs_summary = + surf_at_bufs |> + dplyr::group_by(ID) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::ungroup() + return(surf_at_bufs_summary) +}
#' @title Process a given function in the entire or partial computational grids (under construction)
 #' 
 #' @description Should 
 #' @param grids sf/SpatVector object. Computational grids.
-#' @param grid_id character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. "id_from:id_to" format or c(unique(grid_id)[id_from], unique(grid_id)[id_to])
+#' @param grid_id character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. \code{"id_from:id_to"} format or \code{c(unique(grid_id)[id_from], unique(grid_id)[id_to])}
 #' @param fun function supported in scomps. 
 #' @param ... Arguments passed to fun.
 #' @return a data.frame object with mean value
@@ -1303,8 +1334,7 @@ 

Create functions

#' #' @export distribute_process <- function(grids, grid_id = NULL, fun, ...) { - require(future.apply) - + # subset using grids and grid_id if (!is.null(grid_id)) { if (is.character(grid_id)) { @@ -1322,7 +1352,7 @@

Create functions

results_distributed = future.apply::future_lapply( \(x, ...) { fun(...) - }, grids_target_list, points_cutslist, SIMPLIFY = FALSE, + }, grids_target_list, future.seed = TRUE) results_distributed = do.call(rbind, results_distributed) return(results_distributed) @@ -1334,19 +1364,21 @@

Documenting the package and building

We finish by running commands that will document, build, and install the package. It may also be a good idea to check the package from within this file.

-
litr::document() # <-- use instead of devtools::document()
+
# litr::document() # <-- use instead of devtools::document()
+devtools::document(".")
 devtools::test()
 devtools::build()
-devtools::install(build_vignettes = TRUE, dependencies = F)
+devtools::install(dependencies = F, build_vignettes = TRUE)
 # devtools::check(document = FALSE)
 
## ℹ Updating scomps documentation
 ## ℹ Loading scomps
-
## Warning: [check.R:92] @description requires a value
+
## Warning: [check.R:133] @description requires a value
## Warning: [processing.R:139] @return requires a value
## Writing 'NAMESPACE'
 ## Writing 'check_packbound.Rd'
 ## Writing 'check_crs2.Rd'
+## Writing 'extent_to_polygon.Rd'
 ## Writing 'check_bbox.Rd'
 ## Writing 'check_crs.Rd'
 ## Writing 'check_within_reference.Rd'
@@ -1366,8 +1398,6 @@ 

Documenting the package and building

## Writing 'extract_with.Rd' ## Writing 'calculate_sedc.Rd' ## Writing 'aw_covariates.Rd' -## Writing 'extract_with_buffer.flat.Rd' -## Writing 'extract_with_buffer.kernel.Rd' ## Writing 'extract_with_buffer.Rd' ## Writing 'switch_packbound.Rd' ## Writing 'validate_and_repair_vectors.Rd'
@@ -1376,9 +1406,9 @@

Documenting the package and building

## ## ⠏ | 0 | tests pr, tas, ## pr, tas, +## pr, tas, ## -## ⠹ | 3 | tests pr, tas, -## +## ⠼ | 5 | tests ## ✔ | 8 | tests ## ## ══ Results ═════════════════════════════════════════════════════════════════════ @@ -1389,19 +1419,13 @@

Documenting the package and building

## * checking DESCRIPTION meta-information ... OK ## * installing the package to build vignettes ## * creating vignettes ... OK -## * excluding invalid files -## Subdirectory 'inst/doc' contains invalid file names: -## ‘00_good_practice_parallelization.Rmd’ -## ‘01_generate_computational_grid.Rmd’ -## ‘00_good_practice_parallelization.html’ -## ‘01_generate_computational_grid.html’ ## * checking for LF line-endings in source and make files and shell scripts ## * checking for empty or unneeded directories ## Removed empty directory ‘scomps/build’ -## * building ‘scomps_0.0.2.10032023.tar.gz’ +## * building ‘scomps_0.0.3.10042023.tar.gz’ ## Warning: invalid uid value replaced by that for user 'nobody' ## Warning: invalid gid value replaced by that for user 'nobody'
-
## [1] "/Users/songi2/Documents/GitHub/Scalable_GIS/scomps_0.0.2.10032023.tar.gz"
+
## [1] "/Users/songi2/Documents/GitHub/Scalable_GIS/scomps_0.0.3.10042023.tar.gz"
## Skipping 1 packages ahead of CRAN: data.table
## ── R CMD build ─────────────────────────────────────────────────────────────────
 ## * checking for file ‘/Users/songi2/Documents/GitHub/Scalable_GIS/scomps/DESCRIPTION’ ... OK
@@ -1409,21 +1433,15 @@ 

Documenting the package and building

## * checking DESCRIPTION meta-information ... OK ## * installing the package to build vignettes ## * creating vignettes ... OK -## * excluding invalid files -## Subdirectory 'inst/doc' contains invalid file names: -## ‘00_good_practice_parallelization.Rmd’ -## ‘01_generate_computational_grid.Rmd’ -## ‘00_good_practice_parallelization.html’ -## ‘01_generate_computational_grid.html’ ## * checking for LF line-endings in source and make files and shell scripts ## * checking for empty or unneeded directories ## Removed empty directory ‘scomps/build’ -## * building ‘scomps_0.0.2.10032023.tar.gz’ +## * building ‘scomps_0.0.3.10042023.tar.gz’ ## Warning: invalid uid value replaced by that for user 'nobody' ## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmptULHMx/scomps_0.0.2.10032023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpdIhnyr/scomps_0.0.3.10042023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index f0f3b5ed..854d21e4 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -1,7 +1,7 @@ --- title: "Creating the ``r params$package_name`` R package" author: "Insang Song" -date: "2023-09-03" +date: "2023-10-04" knit: litr::render output: litr::litr_html_document params: @@ -21,7 +21,7 @@ usethis::create_package( path = ".", fields = list( Package = params$package_name, - Version = "0.0.2.10032023", + Version = "0.0.3.10042023", Title = "Scalable R geospatial computation", Description = "A package for scalable geospatial computation for environmental health research", `Authors@R` = person( @@ -41,6 +41,8 @@ usethis::use_package("terra") # Default is "Imports" usethis::use_package("stars") usethis::use_package("rlang") # Default is "Imports" usethis::use_package("testthat") +usethis::use_package("units") +usethis::use_package("methods") usethis::use_package("logr", "Suggests") # Default is "Imports" usethis::use_package("future") # Default is "Imports" usethis::use_package("future.apply") # Default is "Imports" @@ -67,13 +69,13 @@ usethis::use_mit_license(copyright_holder = "I. Song") ### Vignettes 1 ```{r} -litr::add_vignettes("../tools/vignettes-sources/00_good_practice_parallelization.Rmd") +litr::add_vignettes("../tools/vignettes-sources/v00_good_practice_parallelization.Rmd") ``` ### Vignettes 2 ```{r} -litr::add_vignettes("../tools/vignettes-sources/01_generate_computational_grid.Rmd") +litr::add_vignettes("../tools/vignettes-sources/v01_generate_computational_grid.Rmd") ``` @@ -89,19 +91,19 @@ litr::add_vignettes("../tools/vignettes-sources/01_generate_computational_grid.R #' @export check_packbound <- function(input) { # cl_inobj = class(input)[1] - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) - if (is(input, "SpatVector") || is(input, "SpatRaster")) { + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) + if (methods::is(input, "SpatVector") || methods::is(input, "SpatRaster")) { return("terra") } return("sf") } check_datatype <- function(input) { - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) - if (any(is(input, "SpatVector"), is(input, "sf"))) { + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) + if (any(methods::is(input, "SpatVector"), methods::is(input, "sf"))) { return("vector") } - if (any(is(input, "SpatRaster"), is(input, "stars"))) { + if (any(methods::is(input, "SpatRaster"), methods::is(input, "stars"))) { return("raster") } } @@ -152,7 +154,7 @@ testthat::test_that("What package does the input object belong?", #' @return Data converted to the other package class (if sf, terra; if terra, sf) #' @export switch_packbound <- function(input) { - stopifnot("Input should be one of sf or Spat* object.\n" = any(is(input, "sf"), is(input, "stars"), is(input, "SpatVector"), is(input, "SpatRaster"))) + stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) cls_input = check_packbound(input) type_input = check_datatype(input) @@ -206,11 +208,12 @@ testthat::test_that("Format is well converted", #' @title check_crs2: Coordinate system checker #' @description The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179. #' @param input Input object one of sf or terra::Spat* object +#' @param crs_standard character(1). A standard definition of coordinate reference system. Default is "EPSG:4326" Consult [epsg.io](https://epsg.io) for details of other CRS. #' @return A (reprojected) sf or SpatVector object. #' @export check_crs2 <- function(input, crs_standard = "EPSG:4326") { check_crs.sf <- function(input){ - if (is.na(st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} + if (is.na(sf::st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} if (sf::st_crs(input)$epsg == crs_standard ) { return(input) } @@ -393,7 +396,7 @@ clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras){ sp_indexing <- function(points_in, ncutsx, ncutsy){ # pts <- data.table(pnts) points_in <- points_in |> - mutate(or_id = seq(1, dim(points_in)[1])) + dplyr::mutate(or_id = seq(1, dim(points_in)[1])) range_x <- range(points_in$x) limits_x <- (range_x[1] + seq(0, ncutsx) * (range_x[2] - range_x[1]) / ncutsx) @@ -401,7 +404,7 @@ sp_indexing <- function(points_in, ncutsx, ncutsy){ limits_y <- (range_y[1] + seq(0, ncutsy) * (range_y[2] - range_y[1]) / ncutsy) points_in_cut <- points_in |> - mutate(xcut = as.integer(cut(x, ncutsx, labels = seq(1, ncutsx))), + dplyr::mutate(xcut = as.integer(cut(x, ncutsx, labels = seq(1, ncutsx))), ycut = as.integer(cut(y, ncutsy, labels = seq(1, ncutsy)))) return(points_in_cut) @@ -413,7 +416,8 @@ sp_indexing <- function(points_in, ncutsx, ncutsy){ #' #' @param rasterpath character(1). Path to the raster file. #' @param win Named integer vector (4) or terra::ext() results. -#' @param author Insang Song +#' @return SpatRaster object. +#' @author Insang Song #' @export rast_short <- function(rasterpath, win) { terra::rast(rasterpath, win = win) @@ -430,6 +434,7 @@ rast_short <- function(rasterpath, win) { #' @param nx integer(1). #' @param ny integer(1). #' @param padding numeric(1). Extrusion factor +#' @author Insang Song #' @export estimate_demands <- function( inputs, @@ -457,7 +462,8 @@ estimate_demands <- function( #' @param ny integer(1). The number of grids along y-axis. #' @param grid_min_features integer(1). A threshold to merging adjacent grids #' @param padding numeric(1). A extrusion factor to make buffer to clip actual datasets. Depending on the length unit of the CRS of input. -#' @param unit character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See \link{units package vignette (web)}{https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html} for the list of acceptable unit forms. +#' @param unit character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See [units package vignette (web)](https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html) for the list of acceptable unit forms. +#' @param ... arguments passed to the internal function #' @return A set of polygons in the input class #' @description TODO. Using input points, the bounding box is split to the predefined numbers of columns and rows. Each grid will be buffered by the radius. #' @author Insang Song @@ -501,7 +507,7 @@ sp_index_grid <- function(points_in, ncutsx, ncutsy){ sp_index_grid.sf = function(points_in, ncutsx, ncutsy) { grid1 <- sf::st_make_grid(points_in, n = c(ncutsx, ncutsy)) |> as.data.frame() |> - st_as_sf() + sf::st_as_sf() grid1 <- grid1[points_in, ] return(grid1) } @@ -531,14 +537,14 @@ sp_index_grid <- function(points_in, ncutsx, ncutsy){ #' # library(sf) #' # library(igraph) #' # ligrary(dplyr) -#' # dg = st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -#' # st_crs(dg) = 5070 -#' # dgs = st_as_sf(st_make_grid(dg, n = c(20, 15))) +#' # dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) +#' # sf::st_crs(dg) = 5070 +#' # dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) #' # dgs$CGRIDID = seq(1, nrow(dgs)) #' # #' # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -#' # st_crs(dg_sample) = st_crs(dg) -#' # dg_merged = grid_merge(st_as_sf(sss), dgs, 100) +#' # sf::st_crs(dg_sample) = sf::st_crs(dg) +#' # dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) #' #### NOT RUN #### #' @export grid_merge <- function(points_in, grid_in, grid_min_features){ @@ -562,7 +568,7 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ identified = unique(identified) identified = identified[sapply(identified, length) > 1] - identified_graph = lapply(identified, \(x) t(combn(x, 2))) |> + identified_graph = lapply(identified, \(x) t(utils::combn(x, 2))) |> Reduce(f = rbind, x = _) |> unique() |> apply(X = _, 2, as.character) |> @@ -586,8 +592,8 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ # grid_out[["CGRIDID"]][target_idx] = paste("M_", paste(target_idx, collapse = "_"), sep = "") # } grid_out = grid_out |> - dplyr::group_by(CGRIDID) |> - dplyr::summarize(n_merged = n()) |> + dplyr::group_by(!!rlang::sym("CGRIDID")) |> + dplyr::summarize(n_merged = dplyr::n()) |> dplyr::ungroup() ## polsby-popper test for shape compactness @@ -621,7 +627,46 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ ``` +```{r, send_to = "R/check.R"} +#' Generate a rectangular polygon from extent +#' +#' @param extent input extent. A numeric vector with xmin/xmax/ymin/ymax, sf::st_bbox() or terra::ext() outputs. +#' @param output_class character(1). Class of the output polygon. One of "sf" or "terra" +#' @param crs character(1). Coordinate reference system definition. +#' @author Insang Song +#' @export +extent_to_polygon <- function(extent, output_class = "terra", crs = "EPSG:4326") { + if (!output_class %in% c("sf", "terra")) { + stop("output_class should be one of 'sf' or 'terra'.\n") + } + if (methods::is(extent, "numeric")) { + if (is.null(attr(extent, "names"))) { + stop("Your extent is an unnamed numeric vector. Please define names xmin/xmax/ymin/ymax explicitly.\n") + } + extent = switch( + output_class, + sf = sf::st_bbox(extent), + terra = terra::ext(extent) + ) + } + + extent_polygon = switch( + output_class, + sf = sf::st_as_sfc(extent), + terra = terra::vect(extent) + ) + + extent_polygon = switch( + output_class, + sf = sf::st_set_crs(extent_polygon, sf::st_crs(crs)), + terra = terra::set.crs(extent_polygon, terra::crs(crs)) + ) + return(extent_polygon) + +} + +``` ```{r, send_to = "R/check.R"} #' Check if the data extent is inside the reference bounding box @@ -648,10 +693,11 @@ check_bbox <- function( if (is.na(query_crs) || is.null(query_crs)) { stop("The dataset you queried has no CRS. Please make sure your dataset has the correct CRS.\n") } + query_matched = sf::st_transform(data_query, sf::st_crs(ref_crs)) + - # ... - check_result + check_result = sf::st_within() return(check_result) } @@ -659,7 +705,9 @@ check_bbox <- function( ``` -```{r} +```{r, include=FALSE} +# +# #' Check if the data extent is inside the reference bounding box #' #' @description One of the most common errors in spatial computation is rooted in the entirely or partly incomparable spatial extents of input datasets. This function returns whether your data is inside the target computational extent. It is assumed that you know and have the exact computational region. This function will return TRUE if the reference region completely contains your data's extent and FALSE otherwise. @@ -691,8 +739,8 @@ extract_with_polygons <- function( polys, surf, id, func = mean, na.rm = TRUE ) { # type check - stopifnot("Check class of the input points.\n" = any(is(polys, "sf"), is(polys, "SpatVector"))) - stopifnot("Check class of the input raster.\n" = any(is(surf, "stars"), is(surf, "SpatRaster"))) + stopifnot("Check class of the input points.\n" = any(methods::is(polys, "sf"), methods::is(polys, "SpatVector"))) + stopifnot("Check class of the input raster.\n" = any(methods::is(surf, "stars"), methods::is(surf, "SpatRaster"))) stopifnot(is.character(id)) cls_polys = check_packbound(polys) @@ -714,9 +762,9 @@ extract_with_polygons <- function( extract_with_polygons.terra = function(polys, surf, id, func) { extracted = terra::extract(surf, polys) extracted = extracted |> - group_by(!!sym(id)) |> - summarize(across(-!!sym(id), ~func)) |> - ungroup() + dplyr::group_by(!!rlang::sym(id)) |> + dplyr::summarize(dplyr::across(-!!rlang::sym(id), ~func)) |> + dplyr::ungroup() return(extracted) } @@ -773,9 +821,9 @@ extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) #' #' @export check_crs <- function(x) { - stopifnot("Input is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) + stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) - if (is(x, "sf") || is(x, "stars")) { + if (methods::is(x, "sf") || methods::is(x, "stars")) { crs_wkt = sf::st_crs(x) } else { crs_wkt = terra::crs(x) @@ -795,8 +843,8 @@ check_crs <- function(x) { #' @author Insang Song \email{geoissong@@gmail.com} #' @export check_within_reference <- function(input_object, reference) { - stopifnot("Input is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) - stopifnot("Reference is invalid.\n" = (is(x, "sf") || is(x, "stars") || is(x, "SpatVector") || is(x, "SpatRaster"))) + stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) + stopifnot("Reference is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) bbox_input <- input_object sf::st_bbox() |> @@ -820,7 +868,8 @@ check_within_reference <- function(input_object, reference) { #' Calculate SEDC covariates #' @param point_from SpatVector object. Locations where the sum of SEDCs are calculated. #' @param point_to SpatVector object. Locations where each SEDC is calculated. -#' @param sdec_bandwidth numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 %) +#' @param id character(1). Name of the unique id field in point_to. +#' @param sedc_bandwidth numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 %) #' @param threshold numeric(1). For computational efficiency, the nearest points in threshold will be selected #' @param target_fields character(varying). Field names in characters. #' @description NOTE: sf implementation is pending. Only available for terra. @@ -848,16 +897,16 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, # summary near_from_to = near_from_to |> - as_tibble() |> - left_join(data.frame(point_from)) |> - left_join(data.frame(point_to)) |> - left_join(dist_near_to_df) |> + dplyr::as_tibble() |> + dplyr::left_join(data.frame(point_from)) |> + dplyr::left_join(data.frame(point_to)) |> + dplyr::left_join(dist_near_to_df) |> # per the definition in https://mserre.sph.unc.edu/BMElab_web/SEDCtutorial/index.html # exp(-3) is about 0.05 - mutate(w_sedc = exp((-3 * dist) / sedc_bandwidth)) |> - group_by(!!sym(id)) |> - summarize(across(all_of(target_fields), list(sedc = ~sum(w_sedc * ., na.rm = TRUE)))) |> - ungroup() + dplyr::mutate(w_sedc = exp((-3 * dist) / sedc_bandwidth)) |> + dplyr::group_by(!!rlang::sym(id)) |> + dplyr::summarize(dplyr::across(dplyr::all_of(target_fields), list(sedc = ~sum(w_sedc * ., na.rm = TRUE)))) |> + dplyr::ungroup() invisible(near_from_to) @@ -878,13 +927,13 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' library(sf) #' #' # run -#' nc = st_read(system.file("shape/nc.shp", package="sf")) -#' nc = st_transform(nc, 5070) -#' pp = st_sample(nc, size = 300) -#' pp = st_as_sf(pp) +#' nc = sf::st_read(system.file("shape/nc.shp", package="sf")) +#' nc = sf::st_transform(nc, 5070) +#' pp = sf::st_sample(nc, size = 300) +#' pp = sf::st_as_sf(pp) #' pp[["id"]] = seq(1, nrow(pp)) -#' st_crs(pp) = "EPSG:5070" -#' ppb = st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +#' sf::st_crs(pp) = "EPSG:5070" +#' ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' #' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) #' summary(ppb_nc_aw) @@ -892,7 +941,7 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' @export aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { stopifnot("Inputs have invalid classes.\n" = - is(poly_in, "sf") || is(poly_weight, "sf") || is(poly_in, "SpatVector") || is(poly_weight, "SpatVector")) + methods::is(poly_in, "sf") || methods::is(poly_weight, "sf") || methods::is(poly_in, "SpatVector") || methods::is(poly_weight, "SpatVector")) #check_crs() ## distinguish numeric and nonnumeric columns @@ -904,8 +953,8 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { poly_intersected[["area_segment_"]] = terra::expanse(poly_intersected) poly_intersected = data.frame(poly_intersected) |> dplyr::group_by(!!rlang::sym(id_poly_in)) |> - dplyr::summarize(across(is.numeric, - ~weighted.mean(., w = area_segment_))) |> + dplyr::summarize(dplyr::across(is.numeric, + ~stats::weighted.mean(., w = area_segment_))) |> dplyr::ungroup() return(poly_intersected) } @@ -936,58 +985,6 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { ``` -```{r, send_to = "R/processing.R"} -#' Subfunction: extract with buffers (flat weight; simple mean) -#' -#' @export -extract_with_buffer.flat <- function( - points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL - ) { - # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) - # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) - # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = - surf_at_bufs |> - group_by(ID) |> - summarize(across(all_of(name_surf_val), ~mean, na.rm=T)) |> - ungroup() - return(surf_at_bufs_summary) -} -``` - -```{r, send_to = "R/processing.R"} -#' Subfunction: extract with buffers (kernel weight; weighted mean) -#' -#' @export -extract_with_buffer.kernel <- function( - points, surf, radius, id, qsegs, func = mean, kernel, bandwidth - ) { - # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) - # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) - - # TODO: kernel implementation - - - # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = - surf_at_bufs |> - group_by(ID) |> - summarize(across(all_of(name_surf_val), ~mean, na.rm=T)) |> - ungroup() - return(surf_at_bufs_summary) -} -``` - ```{r, send_to = "R/processing.R"} #' @title Extract summarized values from raster with points and a buffer radius (to be written) @@ -1009,7 +1006,7 @@ extract_with_buffer <- function( points, surf, radius, id, qsegs = 90, func = mean, kernel = NULL, bandwidth = NULL ) { # type check - stopifnot("Check class of the input points.\n" = is(points, "SpatVector")) + stopifnot("Check class of the input points.\n" = methods::is(points, "SpatVector")) stopifnot("Check class of the input radius.\n" = is.numeric(radius)) stopifnot(is.character(id)) stopifnot(is.integer(qsegs)) @@ -1036,7 +1033,50 @@ extract_with_buffer <- function( } +# Subfunction: extract with buffers (flat weight; simple mean) +extract_with_buffer.flat <- function( + points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL + ) { + # generate buffers + bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + # crop raster + bufs_extent = terra::ext(bufs) + surf_cropped = terra::crop(surf, bufs_extent) + name_surf_val = names(surf) + # extract raster values + surf_at_bufs = terra::extract(surf_cropped, bufs) + surf_at_bufs_summary = + surf_at_bufs |> + dplyr::group_by(ID) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::ungroup() + return(surf_at_bufs_summary) +} + +# Subfunction: extract with buffers (kernel weight; weighted mean) +extract_with_buffer.kernel <- function( + points, surf, radius, id, qsegs, func = mean, kernel, bandwidth + ) { + # generate buffers + bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + # crop raster + bufs_extent = terra::ext(bufs) + surf_cropped = terra::crop(surf, bufs_extent) + name_surf_val = names(surf) + + # TODO: kernel implementation + + + # extract raster values + surf_at_bufs = terra::extract(surf_cropped, bufs) + surf_at_bufs_summary = + surf_at_bufs |> + dplyr::group_by(ID) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::ungroup() + return(surf_at_bufs_summary) +} ``` @@ -1046,7 +1086,7 @@ extract_with_buffer <- function( #' #' @description Should #' @param grids sf/SpatVector object. Computational grids. -#' @param grid_id character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. "id_from:id_to" format or c(unique(grid_id)[id_from], unique(grid_id)[id_to]) +#' @param grid_id character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. \code{"id_from:id_to"} format or \code{c(unique(grid_id)[id_from], unique(grid_id)[id_to])} #' @param fun function supported in scomps. #' @param ... Arguments passed to fun. #' @return a data.frame object with mean value @@ -1054,8 +1094,7 @@ extract_with_buffer <- function( #' #' @export distribute_process <- function(grids, grid_id = NULL, fun, ...) { - require(future.apply) - + # subset using grids and grid_id if (!is.null(grid_id)) { if (is.character(grid_id)) { @@ -1073,7 +1112,7 @@ distribute_process <- function(grids, grid_id = NULL, fun, ...) { results_distributed = future.apply::future_lapply( \(x, ...) { fun(...) - }, grids_target_list, points_cutslist, SIMPLIFY = FALSE, + }, grids_target_list, future.seed = TRUE) results_distributed = do.call(rbind, results_distributed) return(results_distributed) @@ -1086,10 +1125,11 @@ distribute_process <- function(grids, grid_id = NULL, fun, ...) { We finish by running commands that will document, build, and install the package. It may also be a good idea to check the package from within this file. ```{r} -litr::document() # <-- use instead of devtools::document() +# litr::document() # <-- use instead of devtools::document() +devtools::document(".") devtools::test() devtools::build() -devtools::install(build_vignettes = TRUE, dependencies = F) +devtools::install(dependencies = F, build_vignettes = TRUE) # devtools::check(document = FALSE) ``` \ No newline at end of file diff --git a/tools/tarballs/scomps_0.0.3.10042023.tar.gz b/tools/tarballs/scomps_0.0.3.10042023.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..985b79de1e3f2475eff4cb27e057a411db827b1c GIT binary patch literal 22596 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

OmQ~g0 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 z zpi`v(dg894|EWyUWa~Y(K{DR%?o#;=J_h~of&Raai%Z}5?4~7d7U~#DMGi3-$C_BF{hM|GV`h>7i>ly~5 zc}&vDU!l?y5KBUU1T|gI^Vrir2Kj@8Bb8&0x{tz3A8LFlbQodWn!O$+6h4T+FqnR8D0>B zc*%(3IA)oS-YwU z_@Js0_xqE`b0-5;6*dSOOJIL2FTuHvD@t&Da^hfUuagW1^F$7ko^~B?aE&uB@dp)g zt7e=kb)hNhp|?fFqqAht{rc;#+o4xCps-!%fbBc|J_ohpcPDEEc0U%+j8<74zL`EZ zX5|36fn-MBj`$c#D}@LjnXqlpY~(6~HbANF-n5WP6wGYAVNjVjfuZ_iRxgk2tg5?q^VaC9%j>4zevoI4 zTTtI+L(D7lHmX&~e|avAKivKU&%3)jnE!9B|9>#~KcD~ePG>NRBA^`@AQ5;HR#c1$ zdM3d?*tC5-_3u>v@9pgF+wy;JXK#NU|MNjUtyZf>M=X6&{~o4Y=xL`j4_X|22=Mpk zhxHnssX)P3u{c>I?MLv-X}qe}_&Sol$drbDAGP6uUR5>yr7s=;1^eRHpVaTi=)H0j zrt#v+UUTD_cWsqCg4qe>)$0(n5#UF@&Z&N_wy_}|qSHL{{#uI{0q8*IcqT<@gOVgb zhaEtaU^_@GE~5A~l%)e@bh}AFn&EhW{Gv&pjW0U0premu0vJp@i&!?D {D;B zMq?SbCi2`!jfg#~KYsq`NVHnwaY#-`O&AO)ocQGtK=EZ$99>Ee@K(<{fTue=a6U_K z>9aME1SjqSp#Fd-L9cAzU>F~ajZW}fAI(?f_o{AoV;u2ueMO2-b$tKI4EuUT$4EdT z&r~e0U&tJ-&|zfM?2A{N1L8nsfH+Y39}c=5PW}L28n5&KI7gN00HU(5QT$K`hUjxY zox4qPeo0mAc^007Ios?3(bOo`7*rANwGdxGcfM$5ZX*?MV z(EXp|fNl(WHJoFfkG4CTO%|^NA7o-Cr;y`);%Gh^s|%&6Wn;(y=6D{W%Q5DQ6Ydm* z9I{o?K_&KB--kzQB1%ga!1B#_0Ow?WHVrV2`nTvz2iE~&=)&v_tX&rqeZjK$RL}oR z{@)$wBs2vtevS*7`fnrut&IQJ*)H<`?X~^y58(egwxZ(R-N_pJTzgA2Y8pC%e;NVNAZ}T{YFp<)mX~7}wpnm4 zRf1L!?oQ}y}(HXSX_0Q3O>?$c7E literal 0 HcmV?d00001 diff --git a/tools/vignettes-sources/v00_good_practice_parallelization.Rmd b/tools/vignettes-sources/v00_good_practice_parallelization.Rmd new file mode 100644 index 00000000..8966a59d --- /dev/null +++ b/tools/vignettes-sources/v00_good_practice_parallelization.Rmd @@ -0,0 +1,39 @@ +--- +title: "Good practice of scomps with HPC" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{good_practice_hpc} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + + +```{r} +knitr::opts_chunk$set(warning = FALSE, message = FALSE) + +``` + +## Assumptions +- Users have an accessible HPC at your work +- Data are stored in distributed file systems (usually incorporated into the HPC system) + + +## Basic workflow + +### Practice for minimizing errors +- Consider using `try()` or `tryCatch()` not to a tiny error will halt all the work without any results + - Especially with the higher-level functions +- "IPDE -- Inspect, Predict, Decide, Execute" all the time + +### Raster-Vector overlay +- Make `sp_index_grid()` to get padded grid objects +- Convert sf/SpatVector objects into `terra::ext()` compatible named numeric vector + - For example: `c(xmin=0, ymin=0, xmax=10, ymax=10)` +- Make list objects with: + - An extent vector in each element + - Preprocessed vector objects with respect to each extent vector in the first list + - Preferably all lists are named +- Write a `future.apply` script running through the extent list object +- Run a small amount of data to estimate the total computational demand +- Submit a job with a proper amount of computational assets diff --git a/tools/vignettes-sources/v01_generate_computational_grid.Rmd b/tools/vignettes-sources/v01_generate_computational_grid.Rmd new file mode 100644 index 00000000..4bc1aaf2 --- /dev/null +++ b/tools/vignettes-sources/v01_generate_computational_grid.Rmd @@ -0,0 +1,46 @@ +--- +title: "Generate computational grids" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{computational_grids} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + + +```{r} +knitr::opts_chunk$set(warning = FALSE, message = FALSE) + +``` + + +## Prepare input data +```{r} +library(scomps) +library(sf) +library(terra) +library(stars) +library(dplyr) + +``` + +## Computational grids +```{r} +# your_grid = scomps::sp_index_grid() + +``` + + +## Visualize computational grids +```{r} +# library(mapsf) +# mf_map(your_grid$geometry) + + +``` + + + +## Notes +- Computational grids are the exhaustive split of the entire study region. You should take a square buffer of each grid to clip the target raster or vector. From 1264a32fa0912f2433236d1a49a287841cfa94ef Mon Sep 17 00:00:00 2001 From: Insang Song Date: Wed, 4 Oct 2023 14:33:12 -0400 Subject: [PATCH 21/21] Linting - all = are replaced with <- - Other linting errors were fixed - function argument list and beginning bracket are separated - Exception - Two-space indentation - 80 character lines --- scomps.Rcheck/00_pkg_src/scomps/DESCRIPTION | 21 - scomps.Rcheck/00_pkg_src/scomps/LICENSE | 2 - scomps.Rcheck/00_pkg_src/scomps/NAMESPACE | 27 - scomps.Rcheck/00_pkg_src/scomps/R/check.R | 180 ------ .../00_pkg_src/scomps/R/estimate_demands.R | 24 - scomps.Rcheck/00_pkg_src/scomps/R/indexing.R | 25 - .../scomps/R/interpret_computational_domain.R | 210 ------- scomps.Rcheck/00_pkg_src/scomps/R/logging.R | 20 - .../00_pkg_src/scomps/R/preprocessing.R | 36 -- .../00_pkg_src/scomps/R/processing.R | 364 ----------- .../00_pkg_src/scomps/R/switch_format.R | 25 - scomps.Rcheck/00_pkg_src/scomps/R/validate.R | 18 - .../doc/v00_good_practice_parallelization.R | 4 - .../doc/v00_good_practice_parallelization.Rmd | 39 -- .../v00_good_practice_parallelization.html | 408 ------------- .../doc/v01_generate_computational_grid.R | 22 - .../doc/v01_generate_computational_grid.Rmd | 46 -- .../doc/v01_generate_computational_grid.html | 388 ------------ .../00_pkg_src/scomps/man/aw_covariates.Rd | 41 -- .../00_pkg_src/scomps/man/calculate_sedc.Rd | 34 -- .../00_pkg_src/scomps/man/check_bbox.Rd | 24 - .../00_pkg_src/scomps/man/check_crs.Rd | 28 - .../00_pkg_src/scomps/man/check_crs2.Rd | 19 - .../00_pkg_src/scomps/man/check_packbound.Rd | 20 - .../scomps/man/check_within_reference.Rd | 22 - .../00_pkg_src/scomps/man/clip_as_extent.Rd | 26 - .../scomps/man/clip_as_extent_ras.Rd | 23 - .../scomps/man/clip_as_extent_ras2.Rd | 23 - .../scomps/man/distribute_process.Rd | 26 - .../00_pkg_src/scomps/man/estimate_demands.Rd | 23 - .../scomps/man/extent_to_polygon.Rd | 21 - .../00_pkg_src/scomps/man/extract_with.Rd | 27 - .../scomps/man/extract_with_buffer.Rd | 43 -- .../scomps/man/extract_with_polygons.Rd | 28 - .../scomps/man/get_computational_regions.Rd | 53 -- .../00_pkg_src/scomps/man/grid_merge.Rd | 38 -- .../00_pkg_src/scomps/man/initate_log.Rd | 24 - .../00_pkg_src/scomps/man/rast_short.Rd | 22 - .../00_pkg_src/scomps/man/set_clip_extent.Rd | 22 - .../00_pkg_src/scomps/man/sp_index_grid.Rd | 24 - .../00_pkg_src/scomps/man/sp_indexing.Rd | 21 - .../00_pkg_src/scomps/man/switch_packbound.Rd | 20 - .../scomps/man/validate_and_repair_vectors.Rd | 20 - .../00_pkg_src/scomps/tests/testthat.R | 12 - .../00_pkg_src/scomps/tests/testthat/tests.R | 65 -- .../v00_good_practice_parallelization.Rmd | 39 -- .../v01_generate_computational_grid.Rmd | 46 -- scomps.Rcheck/00check.log | 79 --- scomps.Rcheck/00install.out | 13 - scomps.Rcheck/Rdlatex.log | 564 ----------------- scomps.Rcheck/scomps-Ex.R | 121 ---- scomps.Rcheck/scomps-Ex.Rout | 212 ------- scomps.Rcheck/scomps-Ex.pdf | Bin 3611 -> 0 bytes scomps.Rcheck/scomps-manual.log | 570 ------------------ scomps.Rcheck/scomps-manual.pdf | Bin 116155 -> 0 bytes scomps.Rcheck/scomps/DESCRIPTION | 22 - scomps.Rcheck/scomps/INDEX | 39 -- scomps.Rcheck/scomps/LICENSE | 2 - scomps.Rcheck/scomps/Meta/Rd.rds | Bin 1232 -> 0 bytes scomps.Rcheck/scomps/Meta/features.rds | Bin 123 -> 0 bytes scomps.Rcheck/scomps/Meta/hsearch.rds | Bin 1124 -> 0 bytes scomps.Rcheck/scomps/Meta/links.rds | Bin 517 -> 0 bytes scomps.Rcheck/scomps/Meta/nsInfo.rds | Bin 453 -> 0 bytes scomps.Rcheck/scomps/Meta/package.rds | Bin 994 -> 0 bytes scomps.Rcheck/scomps/Meta/vignette.rds | Bin 277 -> 0 bytes scomps.Rcheck/scomps/NAMESPACE | 27 - scomps.Rcheck/scomps/R/scomps | 27 - scomps.Rcheck/scomps/R/scomps.rdb | Bin 35289 -> 0 bytes scomps.Rcheck/scomps/R/scomps.rdx | Bin 729 -> 0 bytes scomps.Rcheck/scomps/doc/index.html | 34 -- .../doc/v00_good_practice_parallelization.R | 4 - .../doc/v00_good_practice_parallelization.Rmd | 39 -- .../v00_good_practice_parallelization.html | 408 ------------- .../doc/v01_generate_computational_grid.R | 22 - .../doc/v01_generate_computational_grid.Rmd | 46 -- .../doc/v01_generate_computational_grid.html | 388 ------------ scomps.Rcheck/scomps/help/AnIndex | 25 - scomps.Rcheck/scomps/help/aliases.rds | Bin 350 -> 0 bytes scomps.Rcheck/scomps/help/paths.rds | Bin 442 -> 0 bytes scomps.Rcheck/scomps/help/scomps.rdb | Bin 35998 -> 0 bytes scomps.Rcheck/scomps/help/scomps.rdx | Bin 769 -> 0 bytes scomps.Rcheck/scomps/html/00Index.html | 76 --- scomps.Rcheck/scomps/html/R.css | 130 ---- scomps.Rcheck/tests/startup.Rs | 4 - scomps.Rcheck/tests/testthat.R | 12 - scomps.Rcheck/tests/testthat.Rout | 37 -- scomps.Rcheck/tests/testthat/tests.R | 65 -- scomps/DESCRIPTION | 2 +- scomps/R/check.R | 53 +- scomps/R/estimate_demands.R | 2 +- scomps/R/indexing.R | 2 +- scomps/R/interpret_computational_domain.R | 102 ++-- scomps/R/preprocessing.R | 6 +- scomps/R/processing.R | 130 ++-- scomps/R/switch_format.R | 6 +- scomps/R/validate.R | 4 +- scomps/man/aw_covariates.Rd | 16 +- scomps/man/estimate_demands.Rd | 2 +- scomps/man/get_computational_regions.Rd | 8 +- scomps/tests/testthat/tests.R | 38 +- scomps_coverage_report.html | 8 +- scomps_rmarkdown_litr.html | 349 +++++------ scomps_rmarkdown_litr.rmd | 345 ++++++----- .../merra1h_aero_extract_local_stars.r | 40 +- tools/tarballs/scomps_0.0.3.10042023.tar.gz | Bin 22596 -> 22672 bytes 105 files changed, 576 insertions(+), 6196 deletions(-) delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/DESCRIPTION delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/LICENSE delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/NAMESPACE delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/check.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/estimate_demands.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/indexing.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/interpret_computational_domain.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/logging.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/preprocessing.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/processing.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/switch_format.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/R/validate.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.Rmd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.html delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.Rmd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.html delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/aw_covariates.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/calculate_sedc.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/check_bbox.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/check_crs.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/check_crs2.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/check_packbound.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/check_within_reference.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras2.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/distribute_process.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/estimate_demands.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/extent_to_polygon.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/extract_with.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/extract_with_buffer.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/extract_with_polygons.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/get_computational_regions.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/grid_merge.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/initate_log.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/rast_short.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/set_clip_extent.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/sp_index_grid.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/sp_indexing.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/switch_packbound.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/man/validate_and_repair_vectors.Rd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/tests/testthat.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/tests/testthat/tests.R delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/vignettes/v00_good_practice_parallelization.Rmd delete mode 100644 scomps.Rcheck/00_pkg_src/scomps/vignettes/v01_generate_computational_grid.Rmd delete mode 100644 scomps.Rcheck/00check.log delete mode 100644 scomps.Rcheck/00install.out delete mode 100644 scomps.Rcheck/Rdlatex.log delete mode 100644 scomps.Rcheck/scomps-Ex.R delete mode 100644 scomps.Rcheck/scomps-Ex.Rout delete mode 100644 scomps.Rcheck/scomps-Ex.pdf delete mode 100644 scomps.Rcheck/scomps-manual.log delete mode 100644 scomps.Rcheck/scomps-manual.pdf delete mode 100644 scomps.Rcheck/scomps/DESCRIPTION delete mode 100644 scomps.Rcheck/scomps/INDEX delete mode 100644 scomps.Rcheck/scomps/LICENSE delete mode 100644 scomps.Rcheck/scomps/Meta/Rd.rds delete mode 100644 scomps.Rcheck/scomps/Meta/features.rds delete mode 100644 scomps.Rcheck/scomps/Meta/hsearch.rds delete mode 100644 scomps.Rcheck/scomps/Meta/links.rds delete mode 100644 scomps.Rcheck/scomps/Meta/nsInfo.rds delete mode 100644 scomps.Rcheck/scomps/Meta/package.rds delete mode 100644 scomps.Rcheck/scomps/Meta/vignette.rds delete mode 100644 scomps.Rcheck/scomps/NAMESPACE delete mode 100644 scomps.Rcheck/scomps/R/scomps delete mode 100644 scomps.Rcheck/scomps/R/scomps.rdb delete mode 100644 scomps.Rcheck/scomps/R/scomps.rdx delete mode 100644 scomps.Rcheck/scomps/doc/index.html delete mode 100644 scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.R delete mode 100644 scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.Rmd delete mode 100644 scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.html delete mode 100644 scomps.Rcheck/scomps/doc/v01_generate_computational_grid.R delete mode 100644 scomps.Rcheck/scomps/doc/v01_generate_computational_grid.Rmd delete mode 100644 scomps.Rcheck/scomps/doc/v01_generate_computational_grid.html delete mode 100644 scomps.Rcheck/scomps/help/AnIndex delete mode 100644 scomps.Rcheck/scomps/help/aliases.rds delete mode 100644 scomps.Rcheck/scomps/help/paths.rds delete mode 100644 scomps.Rcheck/scomps/help/scomps.rdb delete mode 100644 scomps.Rcheck/scomps/help/scomps.rdx delete mode 100644 scomps.Rcheck/scomps/html/00Index.html delete mode 100644 scomps.Rcheck/scomps/html/R.css delete mode 100644 scomps.Rcheck/tests/startup.Rs delete mode 100644 scomps.Rcheck/tests/testthat.R delete mode 100644 scomps.Rcheck/tests/testthat.Rout delete mode 100644 scomps.Rcheck/tests/testthat/tests.R diff --git a/scomps.Rcheck/00_pkg_src/scomps/DESCRIPTION b/scomps.Rcheck/00_pkg_src/scomps/DESCRIPTION deleted file mode 100644 index eae7ecd6..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/DESCRIPTION +++ /dev/null @@ -1,21 +0,0 @@ -Package: scomps -Title: Scalable R geospatial computation -Version: 0.0.3.10042023 -Authors@R: - person("Insang", "Song", , "geoissong@gmail.com", role = c("aut", "cre"), - comment = c(ORCID = "0000-0001-8732-3256")) -Description: A package for scalable geospatial computation for - environmental health research -License: MIT + file LICENSE -Encoding: UTF-8 -Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.3 -Imports: covr, dplyr, future, future.apply, methods, rlang, sf, stars, - terra, testthat, units -Suggests: future.batchtools, igraph, knitr, logr, rmarkdown, withr -VignetteBuilder: knitr -Config/testthat/edition: 3 -NeedsCompilation: no -Packaged: 2023-10-04 15:41:03 UTC; songi2 -Author: Insang Song [aut, cre] () -Maintainer: Insang Song diff --git a/scomps.Rcheck/00_pkg_src/scomps/LICENSE b/scomps.Rcheck/00_pkg_src/scomps/LICENSE deleted file mode 100644 index 74e6421f..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/LICENSE +++ /dev/null @@ -1,2 +0,0 @@ -YEAR: 2023 -COPYRIGHT HOLDER: I. Song diff --git a/scomps.Rcheck/00_pkg_src/scomps/NAMESPACE b/scomps.Rcheck/00_pkg_src/scomps/NAMESPACE deleted file mode 100644 index b8f3fc6a..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/NAMESPACE +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by roxygen2: do not edit by hand - -export(aw_covariates) -export(calculate_sedc) -export(check_bbox) -export(check_crs) -export(check_crs2) -export(check_packbound) -export(check_within_reference) -export(clip_as_extent) -export(clip_as_extent_ras) -export(clip_as_extent_ras2) -export(distribute_process) -export(estimate_demands) -export(extent_to_polygon) -export(extract_with) -export(extract_with_buffer) -export(extract_with_polygons) -export(get_computational_regions) -export(grid_merge) -export(initate_log) -export(rast_short) -export(set_clip_extent) -export(sp_index_grid) -export(sp_indexing) -export(switch_packbound) -export(validate_and_repair_vectors) diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/check.R b/scomps.Rcheck/00_pkg_src/scomps/R/check.R deleted file mode 100644 index 2e1bbcf2..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/R/check.R +++ /dev/null @@ -1,180 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' @title Return the package the input object is based on -#' @description Detect whether the input object is sf or Spat* object. -#' @author Insang Song -#' @param input Spat* in terra or sf object. -#' @return A character object; one of 'terra' and 'sf' -#' @export -check_packbound <- function(input) { - # cl_inobj = class(input)[1] - stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) - if (methods::is(input, "SpatVector") || methods::is(input, "SpatRaster")) { - return("terra") - } - return("sf") -} - -check_datatype <- function(input) { - stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) - if (any(methods::is(input, "SpatVector"), methods::is(input, "sf"))) { - return("vector") - } - if (any(methods::is(input, "SpatRaster"), methods::is(input, "stars"))) { - return("raster") - } -} - -#' @title check_crs2: Coordinate system checker -#' @description The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179. -#' @param input Input object one of sf or terra::Spat* object -#' @param crs_standard character(1). A standard definition of coordinate reference system. Default is "EPSG:4326" Consult [epsg.io](https://epsg.io) for details of other CRS. -#' @return A (reprojected) sf or SpatVector object. -#' @export -check_crs2 <- function(input, crs_standard = "EPSG:4326") { - check_crs.sf <- function(input){ - if (is.na(sf::st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} - if (sf::st_crs(input)$epsg == crs_standard ) { - return(input) - } - input_transformed <- sf::st_transform(input, sf::st_crs(crs_standard)) - return(input_transformed) - } - - check_crs.terra <- function(input) { - if (terra::crs(input, describe = TRUE)$code == crs_standard) { - return(input) - } - input_transformed = terra::project(input, terra::crs(crs_standard)) - return(input_transformed) - } - detected = check_packbound(input) - switch(detected, - terra = check_crs.terra(input), - sf = check_crs.sf(input)) - } - -#' Generate a rectangular polygon from extent -#' -#' @param extent input extent. A numeric vector with xmin/xmax/ymin/ymax, sf::st_bbox() or terra::ext() outputs. -#' @param output_class character(1). Class of the output polygon. One of "sf" or "terra" -#' @param crs character(1). Coordinate reference system definition. -#' @author Insang Song -#' @export -extent_to_polygon <- function(extent, output_class = "terra", crs = "EPSG:4326") { - if (!output_class %in% c("sf", "terra")) { - stop("output_class should be one of 'sf' or 'terra'.\n") - } - if (methods::is(extent, "numeric")) { - if (is.null(attr(extent, "names"))) { - stop("Your extent is an unnamed numeric vector. Please define names xmin/xmax/ymin/ymax explicitly.\n") - } - extent = switch( - output_class, - sf = sf::st_bbox(extent), - terra = terra::ext(extent) - ) - } - - extent_polygon = switch( - output_class, - sf = sf::st_as_sfc(extent), - terra = terra::vect(extent) - ) - - extent_polygon = switch( - output_class, - sf = sf::st_set_crs(extent_polygon, sf::st_crs(crs)), - terra = terra::set.crs(extent_polygon, terra::crs(crs)) - ) - - return(extent_polygon) - -} - - -#' Check if the data extent is inside the reference bounding box -#' -#' @description One of the most common errors in spatial computation is rooted in the entirely or partly incomparable spatial extents of input datasets. This function returns whether your data is inside the target computational extent. It is assumed that you know and have the exact computational region. This function will return TRUE if the reference region completely contains your data's extent and FALSE otherwise. -#' @param data_query sf*/stars/SpatVector/SpatRaster object. -#' @param reference sf*/stars/SpatVector/SpatRaster object or a named numeric vector with four names (xmin, ymin, xmax, and ymax). -#' @param reference_crs Well-known-text-formatted or EPSG code of the reference's coordinate system. Only required when a named numeric vector is passed to reference. -#' @return TRUE (the queried data extent is completely within the reference bounding box) or FALSE -#' @author Insang Song \email{geoissong@@gmail.com} -#' -#' @export -check_bbox <- function( - data_query, reference, reference_crs = NULL -) { - if (is.numeric(reference) && is.null(reference_crs)) { - stop("CRS should be entered when the reference extent is a vector.\n") - } - if (is.numeric(reference) && !is.null(reference_crs)) { - reference = sf::st_as_sfc(sf::st_bbox(reference), crs = reference_crs) - } - query_crs = check_crs(data_query) - ref_crs = check_crs(reference) - if (is.na(query_crs) || is.null(query_crs)) { - stop("The dataset you queried has no CRS. Please make sure your dataset has the correct CRS.\n") - } - query_matched = sf::st_transform(data_query, sf::st_crs(ref_crs)) - - - - check_result = sf::st_within() - return(check_result) -} - - - -#' Check Coordinate Reference System -#' @param x sf/stars/SpatVector/SpatRaster object. -#' @return A st_crs or crs object. -#' @description -#' @author Insang Song \email{geoissong@@gmail.com} -#' @examples -#' # data -#' library(sf) -#' ncpath = system.file("shape/nc.shp", package = "sf") -#' nc = read_sf(ncpath) -#' check_crs(nc) -#' -#' @export -check_crs <- function(x) { - stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) - - if (methods::is(x, "sf") || methods::is(x, "stars")) { - crs_wkt = sf::st_crs(x) - } else { - crs_wkt = terra::crs(x) - } - - stopifnot("No CRS is defined in the input. Please consult the metadata or the data source.\n" = !is.na(crs_wkt) || crs_wkt != "") - return(crs_wkt) -} - -#' Check if the boundary of the vector/raster object is inside the reference -#' @param input_object sf/stars/SpatVector/SpatRaster object. -#' @param reference sf/stars/SpatVector/SpatRaster object. -#' @return logical -#' @author Insang Song \email{geoissong@@gmail.com} -#' @export -check_within_reference <- function(input_object, reference) { - stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) - stopifnot("Reference is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) - - bbox_input <- input_object - sf::st_bbox() |> - sf::st_as_sfc() - - bbox_reference = reference |> - sf::st_bbox() |> - sf::st_as_sfc() - - iswithin = sf::st_covered_by(bbox_input, bbox_reference) - iswithin = length(iswithin[[1]]) - iswithin = (iswithin == 1) - invisible(iswithin) -} - - diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/estimate_demands.R b/scomps.Rcheck/00_pkg_src/scomps/R/estimate_demands.R deleted file mode 100644 index 0c0bf6d7..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/R/estimate_demands.R +++ /dev/null @@ -1,24 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Estimate computational demands from inputs (to be written) -#' -#' @param inputs a list of sf/Spat* objects or file paths -#' @param nx integer(1). -#' @param ny integer(1). -#' @param padding numeric(1). Extrusion factor -#' @author Insang Song -#' @export -estimate_demands <- function( - inputs, - nx, ny, - padding -) { - ## cpu - ## memory - ## estimate maximum coverage - ## clipped data size - ## total distributed memory - ## return a list of total demands - ## print summary of results -} - diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/indexing.R b/scomps.Rcheck/00_pkg_src/scomps/R/indexing.R deleted file mode 100644 index 7555a3f9..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/R/indexing.R +++ /dev/null @@ -1,25 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' @title Create integer indices for grid -#' @description Returns a tibble object that includes x- and y- index by using two inputs ncutsx and ncutsy, which are x- and y-directional splits, respectively. -#' @author Insang Song -#' @param points_in sf object. -#' @param ncutsx integer(1). The number of splits along x-axis. -#' @param ncutsy integer(1). The number of splits along y-axis. -#' @export -sp_indexing <- function(points_in, ncutsx, ncutsy){ - # pts <- data.table(pnts) - points_in <- points_in |> - dplyr::mutate(or_id = seq(1, dim(points_in)[1])) - - range_x <- range(points_in$x) - limits_x <- (range_x[1] + seq(0, ncutsx) * (range_x[2] - range_x[1]) / ncutsx) - range_y <- range(points_in$y) - limits_y <- (range_y[1] + seq(0, ncutsy) * (range_y[2] - range_y[1]) / ncutsy) - - points_in_cut <- points_in |> - dplyr::mutate(xcut = as.integer(cut(x, ncutsx, labels = seq(1, ncutsx))), - ycut = as.integer(cut(y, ncutsy, labels = seq(1, ncutsy)))) - - return(points_in_cut) -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/interpret_computational_domain.R b/scomps.Rcheck/00_pkg_src/scomps/R/interpret_computational_domain.R deleted file mode 100644 index 90132a7f..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/R/interpret_computational_domain.R +++ /dev/null @@ -1,210 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Get a set of computational regions -#' -#' @param input sf or Spat* object. -#' @param mode character(1). Mode of region construction. One of "grid" (simple grid regardless of the number of features in each grid), "density" (clustering-based varying grids), "grid_advanced" (merging adjacent grids with smaller number of features than grid_min_features). -#' @param nx integer(1). The number of grids along x-axis. -#' @param ny integer(1). The number of grids along y-axis. -#' @param grid_min_features integer(1). A threshold to merging adjacent grids -#' @param padding numeric(1). A extrusion factor to make buffer to clip actual datasets. Depending on the length unit of the CRS of input. -#' @param unit character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See [units package vignette (web)](https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html) for the list of acceptable unit forms. -#' @param ... arguments passed to the internal function -#' @return A set of polygons in the input class -#' @description TODO. Using input points, the bounding box is split to the predefined numbers of columns and rows. Each grid will be buffered by the radius. -#' @author Insang Song -#' @examples -#' # data -#' library(sf) -#' ncpath = system.file("shape/nc.shp", package = "sf") -#' nc = read_sf(ncpath) -#' nc = st_transform(nc, "EPSG:5070") -#' # run -#' # nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) -#' -#' @export -get_computational_regions <- function(input, mode = "grid", nx = 10, ny = 10, grid_min_features = 30, padding = NULL, unit = NULL, ...) { - # type check - package_detected = check_packbound(input) - # stopifnot("Invalid input.\n" = !any(grepl("^(sf|Spat)", class(input)))) - stopifnot("Argument mode should be one of 'grid', 'grid_advanced', or 'density'.\n" = !mode %in% c("grid", "grid_advanced", "density")) - stopifnot("Ensure that nx, ny, and grid_min_features are all integer.\n" = all(is.integer(nx), is.integer(y), is.integer(grid_min_features))) - stopifnot("padding should be numeric. We convert padding to numeric...\n" = !is.numeric(padding)) - # valid unit compatible with units::set_units? - - # if (detected_pnts == "sf") { - # } - # if (detected_pnts == "terra") { - # grid1$ID = seq(1, nrow(grid1)) - # } - } - -#' @title sp_index_grid: Generate grid polygons -#' @description Returns a sf object that includes x- and y- index by using two inputs ncutsx and ncutsy, which are x- and y-directional splits, respectively. -#' @author Insang Song -#' @param points_in sf or SpatVector object. Target points of computation. -#' @param ncutsx integer(1). The number of splits along x-axis. -#' @param ncutsy integer(1). The number of splits along y-axis. -#' @return A sf or SpatVector object of computation grids with unique grid id (CGRIDID). -#' @export -sp_index_grid <- function(points_in, ncutsx, ncutsy){ - package_detected = check_packbound(points_in) - - sp_index_grid.sf = function(points_in, ncutsx, ncutsy) { - grid1 <- sf::st_make_grid(points_in, n = c(ncutsx, ncutsy)) |> - as.data.frame() |> - sf::st_as_sf() - grid1 <- grid1[points_in, ] - return(grid1) - } - sp_index_grid.terra = function(points_in, ncutsx, ncutsy) { - grid1 <- terra::rast(points_in, nrows = ncutsy, ncols = ncutsx) - grid1 <- terra::as.polygons(grid1) - return(grid1) - } - grid_out = switch(package_detected, - sf = sp_index_grid.sf(points_in, ncutsx, ncutsy), - terra = sp_index_grid.terra(points_in, ncutsx, ncutsy)) - - grid_out$CGRIDID = seq(1, nrow(x = grid_out)) - return(grid_out) - -} - - -#' @title grid_merge: Merge grid polygons with given rules -#' @description Merge boundary-sharing (in "Rook" contiguity) grids with fewer target features than the threshold. This function strongly assumes that the input is returned from the sp_index_grid, which has 'CGRIDID' as the unique id field. -#' @author Insang Song -#' @param points_in sf or SpatVector object. Target points of computation. -#' @param grid_in sf or SpatVector object. The grid generated by sp_index_grid -#' @param grid_min_features integer(1). Threshold to merge adjacent grids. -#' @return A sf or SpatVector object of computation grids. -#' @examples -#' # library(sf) -#' # library(igraph) -#' # ligrary(dplyr) -#' # dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -#' # sf::st_crs(dg) = 5070 -#' # dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) -#' # dgs$CGRIDID = seq(1, nrow(dgs)) -#' # -#' # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -#' # sf::st_crs(dg_sample) = sf::st_crs(dg) -#' # dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) -#' #### NOT RUN #### -#' @export -grid_merge <- function(points_in, grid_in, grid_min_features){ - package_detected = check_packbound(points_in) - if (package_detected == "terra") { - points_in = sf::st_as_sf(points_in) - grid_in = sf::st_as_sf(grid_in) - } - - n_points_in_grid = lengths(sf::st_intersects(grid_in, points_in)) - grid_self = sf::st_relate(grid_in, grid_in, pattern = "2********") - grid_rook = sf::st_relate(grid_in, grid_in, pattern = "F***1****") - grid_rooks = mapply(c, grid_self, grid_rook, SIMPLIFY = FALSE) - grid_lt_threshold = (n_points_in_grid < grid_min_features) - stopifnot("Threshold is too low. Please try higher threshold.\n" = sum(grid_lt_threshold) != 0) - grid_lt_threshold = seq(1, nrow(grid_in))[grid_lt_threshold] - - # This part does not work as expected. Should investigate edge list and actual row index of the grid object; - identified = lapply(grid_rooks, \(x) sort(x[which(x %in% grid_lt_threshold)])) - identified = identified[grid_lt_threshold] - identified = unique(identified) - identified = identified[sapply(identified, length) > 1] - - identified_graph = lapply(identified, \(x) t(utils::combn(x, 2))) |> - Reduce(f = rbind, x = _) |> - unique() |> - apply(X = _, 2, as.character) |> - igraph::graph_from_edgelist(el = _, directed = 0) |> - igraph::mst() |> - igraph::components() - # return(identified_graph) - - identified_graph_member = identified_graph$membership - - merge_idx = as.integer(names(identified_graph_member)) - merge_member = split(merge_idx, identified_graph_member) - merge_member_label = unlist(lapply(merge_member, \(x) paste(x, collapse = "_"))) - merge_member_label = merge_member_label[identified_graph_member] - - # sf object manipulation - grid_out = grid_in - grid_out[["CGRIDID"]][merge_idx] = merge_member_label - # for (k in seq_along(merge_member_label)) { - # target_idx = merge_member_label[[k]] - # grid_out[["CGRIDID"]][target_idx] = paste("M_", paste(target_idx, collapse = "_"), sep = "") - # } - grid_out = grid_out |> - dplyr::group_by(!!rlang::sym("CGRIDID")) |> - dplyr::summarize(n_merged = dplyr::n()) |> - dplyr::ungroup() - - ## polsby-popper test for shape compactness - grid_merged = grid_out[which(grid_out$n_merged > 1),] - grid_merged_area = as.numeric(sf::st_area(grid_merged)) - grid_merged_perimeter = as.numeric(sf::st_length(sf::st_cast(grid_merged, "LINESTRING"))) - grid_merged_pptest = (4 * pi * grid_merged_area) / (grid_merged_perimeter ^ 2) - - # pptest value is bounded [0,1]; 0.3 threshold is groundless at this moment, possibly will make it defined by users. - if (max(unique(identified_graph_member)) > floor(0.1 * nrow(grid_in)) || any(grid_merged_pptest < 0.3)) { - warning("The reduced computational regions have too complex shapes. Consider increasing thresholds or using the original grids.\n") - } - - return(grid_out) - - # union unique sets into one - # identified_relation = matrix(NA, length(identified), length(identified)) - # diag(identified_relation) = lengths(identified) - - # for (i in seq_len(length(identified))) { - # for (j in seq(i, length(identified))) { - # identified_relation[i, j] = length(intersect(identified[[i]], identified[[j]])) - # identified_relation[j, i] = identified_relation[i, j] - # } - # } - # # identified_relation = max(identified_relation) - identified_relation - # return(as.dist(identified_relation)) -} - - - - -#' @title Process a given function in the entire or partial computational grids (under construction) -#' -#' @description Should -#' @param grids sf/SpatVector object. Computational grids. -#' @param grid_id character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. \code{"id_from:id_to"} format or \code{c(unique(grid_id)[id_from], unique(grid_id)[id_to])} -#' @param fun function supported in scomps. -#' @param ... Arguments passed to fun. -#' @return a data.frame object with mean value -#' @author Insang Song \email{geoissong@@gmail.com} -#' -#' @export -distribute_process <- function(grids, grid_id = NULL, fun, ...) { - - # subset using grids and grid_id - if (!is.null(grid_id)) { - if (is.character(grid_id)) { - grid_id_parsed = strsplit(grid_id, ":", fixed = TRUE)[[1]] - grid_ids = c(which(unique(grids[["CGRIDID"]]) == grid_id_parsed[1]), - which(unique(grids[["CGRIDID"]]) == grid_id_parsed[2])) - } - if (is.numeric(grid_id)) { - grid_ids = unique(grids[["CGRIDID"]])[grid_id] - } - } - grids_target = grids[grid_ids,] - grids_target_list = split(grids_target, grids_target[["CGRIDID"]]) - - results_distributed = future.apply::future_lapply( - \(x, ...) { - fun(...) - }, grids_target_list, - future.seed = TRUE) - results_distributed = do.call(rbind, results_distributed) - return(results_distributed) -} - diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/logging.R b/scomps.Rcheck/00_pkg_src/scomps/R/logging.R deleted file mode 100644 index 87a7dab2..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/R/logging.R +++ /dev/null @@ -1,20 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Turn on logging -#' @author Insang Song -#' @param expr expression. Any function call to be logged. -#' @param dolog logical(1). Will the messages be logged. -#' @param logpath character(1). Log file path with the full log file name. -#' @return Nothing. It will export a log file in the specified path as logpath. -#' @export -initate_log <- function(expr, dolog = FALSE, logpath) { - if (!dolog) { - return(NULL) - } - logr::log_path(logpath) - try(expr) - logr::log_close() - return(NULL) -} - - diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/preprocessing.R b/scomps.Rcheck/00_pkg_src/scomps/R/preprocessing.R deleted file mode 100644 index 93b3ad93..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/R/preprocessing.R +++ /dev/null @@ -1,36 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Setting the clipping extent -#' @description Return clipping extent with buffer radius. It assumes the input CRS is projected and linear unit is meters. -#' @author Insang Song -#' @param pnts One of sf or vect class. Target points of computation. -#' @param buffer_r numeric(1). Buffer radius. It is assumed in metres -#' @return A terra::ext or sfc_POLYGON object of the computation extent. -#' @export -set_clip_extent <- function(pnts, buffer_r) { - detected = check_packbound(pnts) - if (detected == "terra") { - ext_input = terra::ext(pnts) - # Note that `+` operation on terra::ext output accounts for the operand as it is. - ext_input = ext_input + (1.1 * buffer_r + 30) - } - if (detected == "sf") { - ext_input <- pnts |> sf::st_bbox() - # Note that `+` operation on st_bbox output simply adds the number; we add a vector here. - ext_input <- ext_input + ((1.1 * c(-1, -1, 1, 1) * buffer_r) + 30) - ext_input <- sf::st_as_sfc(ext_input) - } - return(ext_input) -} - -#' Quick call for SpatRaster with a window -#' -#' @param rasterpath character(1). Path to the raster file. -#' @param win Named integer vector (4) or terra::ext() results. -#' @return SpatRaster object. -#' @author Insang Song -#' @export -rast_short <- function(rasterpath, win) { - terra::rast(rasterpath, win = win) -} - diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/processing.R b/scomps.Rcheck/00_pkg_src/scomps/R/processing.R deleted file mode 100644 index 00b3e1d3..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/R/processing.R +++ /dev/null @@ -1,364 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Extent clipping -#' @description Clip input vector by the expected maximum extent of computation. -#' @author Insang Song -#' @param pnts sf or SpatVector object -#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 -#' @param nqsegs integer(1). the number of points per a quarter circle; SOON TO BE DEPRECATED -#' @param target_input sf or SpatVector object to be clipped -#' @return A clipped sf or SpatVector object. -#' @export -clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input){ - if (any(sapply(list(pnts, buffer_r, target_input), is.null))) { - stop("One or more required arguments are NULL. Please check.\n") - } - detected_pnts = check_packbound(pnts) - detected_target = check_packbound(target_input) - - if (detected_pnts != detected_target) { - warning("Inputs are not the same class.\n") - target_input = switch(detected_target, - sf = terra::vect(target_input), - terra = sf::st_as_sf(target_input)) - } - - ext_input = set_clip_extent(pnts, buffer_r) - cat("Clip target features with the input feature extent...\n") - if (detected_pnts == "sf") { - cae = ext_input |> - sf::st_intersection(x = target_input) - } - if (detected_pnts == "terra") { - cae = terra::intersect(target_input, ext_input) - } - - return(cae) -} - -#' @title clip_as_extent_ras: Clip input raster. -#' @description Clip input raster by the expected maximum extent of computation. -#' @author Insang Song -#' @param pnts sf or SpatVector object -#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 -#' @param nqsegs integer(1). the number of points per a quarter circle -#' @param ras SpatRaster object to be clipped -#' @export -clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras){ - if (any(sapply(list(pnts, buffer_r, ras), is.null))) { - stop("Any of required arguments are NULL. Please check.\n") - } - ext_input = set_clip_extent(pnts, buffer_r) |> - terra::ext() - - cae <- terra::crop(ras, ext_input, snap = 'out') - return(cae) -} - -#' @title clip_as_extent_ras2: Clip input raster (version 2). -#' @description Clip input raster by the expected maximum extent of computation. -#' @author Insang Song -#' @param points_in sf or SpatVector object -#' @param buffer_r numeric(1). buffer radius. this value will be automatically multiplied by 1.25 -#' @param nqsegs integer(1). the number of points per a quarter circle -#' @param ras SpatRaster object to be clipped -#' @export -clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras){ - if (any(sapply(list(points_in, buffer_r, ras), is.null))) { - stop("Any of required arguments are NULL. Please check.\n") - } - ext_input = set_clip_extent(points_in, buffer_r) |> - terra::ext() - - cae <- terra::crop(ras, ext_input, snap = 'out') - return(cae) -} - -#' @title Extract summarized values from raster with generic polygons -#' -#' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. -#' @param polys sf/SpatVector object. Polygons. -#' @param surf stars/SpatRaster object. A raster of whatnot a summary will be calculated -#' @param id character(1). Unique identifier of each point. -#' @param func a function taking one argument. For example, function(x) mean(x, na.rm = TRUE) or \(x) mode(x, na.rm = TRUE) -#' @param na.rm logical(1). NA values are omitted when summary is calculated. -#' @return a data.frame object with function value -#' @author Insang Song \email{geoissong@@gmail.com} -#' -#' @export -extract_with_polygons <- function( - polys, surf, id, func = mean, na.rm = TRUE - ) { - # type check - stopifnot("Check class of the input points.\n" = any(methods::is(polys, "sf"), methods::is(polys, "SpatVector"))) - stopifnot("Check class of the input raster.\n" = any(methods::is(surf, "stars"), methods::is(surf, "SpatRaster"))) - stopifnot(is.character(id)) - - cls_polys = check_packbound(polys) - cls_surf = check_packbound(surf) - - if (cls_polys != cls_surf) { - polys = switch_packbound(polys) - } - - extract_with_polygons.sf = function(polys, surf, id, func) { - extracted = stars::st_extract(x = surf, at = polys, FUN = func) - # extracted = extracted |> - # group_by(!!sym(id)) |> - # summarize(across(-!!sym(id), ~func)) |> - # ungroup() - return(extracted) - } - - extract_with_polygons.terra = function(polys, surf, id, func) { - extracted = terra::extract(surf, polys) - extracted = extracted |> - dplyr::group_by(!!rlang::sym(id)) |> - dplyr::summarize(dplyr::across(-!!rlang::sym(id), ~func)) |> - dplyr::ungroup() - return(extracted) - } - - extracted_poly = switch( - cls_surf, - sf = extract_with_polygons.sf(polys = polys, surf = surf, id = id, func = func), - terra = extract_with_polygons.terra(polys = polys, surf = surf, id = id, func = func) - ) - return(extracted_poly) -} - - -#' Extract raster values with point buffers or polygons -#' -#' @param raster SpatRaster object. -#' @param vector SpatVector object. -#' @param id character(1). Unique identifier of each point. -#' @param func function taking one numeric vector argument. -#' @param mode one of "polygon" (generic polygons to extract raster values with) or "buffer" (point with buffer radius) -#' @param ... various. Passed to extract_with_buffer. See \code{?extract_with_buffer} for details. -#' @return -#' @author Insang Song \email{geoissong@@gmail.com} -#' @export -extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) { - if (!mode %in% c("polygon", "buffer")) { - stop("Argument 'mode' should be one of 'polygon' or 'buffer'.\n") - } - stopifnot(is.character(id)) - stopifnot(id %in% names(vector)) - - extracted = - switch(mode, - polygon = extract_with_polygons(vector, raster, id, func), - buffer = extract_with_buffer(vector, raster, id = id, func = func, ...)) - return(extracted) -} - - -#' Calculate SEDC covariates -#' @param point_from SpatVector object. Locations where the sum of SEDCs are calculated. -#' @param point_to SpatVector object. Locations where each SEDC is calculated. -#' @param id character(1). Name of the unique id field in point_to. -#' @param sedc_bandwidth numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 %) -#' @param threshold numeric(1). For computational efficiency, the nearest points in threshold will be selected -#' @param target_fields character(varying). Field names in characters. -#' @description NOTE: sf implementation is pending. Only available for terra. -#' @author Insang Song -#' @export -calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, target_fields) { - # define sources, set SEDC exponential decay range - len_point_from = seq_len(nrow(point_from)) - len_point_to = seq_len(nrow(point_to)) - - point_from$from_id = len_point_from - # select egrid_v only if closer than 3e5 meters from each aqs - point_from_buf = terra::buffer(point_from_buf, threshold = threshold, quadsegs = 90) - point_to = point_to[point_from_buf,] - point_to$to_id = len_point_to - - # near features with distance argument: only returns integer indices - near_from_to = terra::nearby(point_from, point_to, distance = threshold) - # attaching actual distance - dist_near_to = terra::distance(point_from, point_to) - dist_near_to_df = as.vector(dist_near_to) - # adding integer indices - dist_near_to_tdf = expand.grid(from_id = len_point_from, to_id = len_point_to) - dist_near_to_df = cbind(dist_near_to_tdf, dist = dist_near_to_df) - - # summary - near_from_to = near_from_to |> - dplyr::as_tibble() |> - dplyr::left_join(data.frame(point_from)) |> - dplyr::left_join(data.frame(point_to)) |> - dplyr::left_join(dist_near_to_df) |> - # per the definition in https://mserre.sph.unc.edu/BMElab_web/SEDCtutorial/index.html - # exp(-3) is about 0.05 - dplyr::mutate(w_sedc = exp((-3 * dist) / sedc_bandwidth)) |> - dplyr::group_by(!!rlang::sym(id)) |> - dplyr::summarize(dplyr::across(dplyr::all_of(target_fields), list(sedc = ~sum(w_sedc * ., na.rm = TRUE)))) |> - dplyr::ungroup() - - invisible(near_from_to) - -} - - -#' Computing area weighted covariates using two polygon sf or SpatVector objects -#' @param poly_in A sf/SpatVector object at weighted means will be calculated. -#' @param poly_weight A sf/SpatVector object from which weighted means will be calculated. -#' @param id_poly_in character(1). The unique identifier of each polygon in poly_in -#' @return A data.frame with all numeric fields of area-weighted means. -#' @description When poly_in and poly_weight are different classes, poly_weight will be converted to the class of poly_in. -#' @author Insang Song \email{geoissong@@gmail.com} -#' @examples -#' # package -#' library(sf) -#' -#' # run -#' nc = sf::st_read(system.file("shape/nc.shp", package="sf")) -#' nc = sf::st_transform(nc, 5070) -#' pp = sf::st_sample(nc, size = 300) -#' pp = sf::st_as_sf(pp) -#' pp[["id"]] = seq(1, nrow(pp)) -#' sf::st_crs(pp) = "EPSG:5070" -#' ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) -#' -#' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) -#' summary(ppb_nc_aw) -#' #### Example of aw_covariates ends #### -#' @export -aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { - stopifnot("Inputs have invalid classes.\n" = - methods::is(poly_in, "sf") || methods::is(poly_weight, "sf") || methods::is(poly_in, "SpatVector") || methods::is(poly_weight, "SpatVector")) - #check_crs() - - ## distinguish numeric and nonnumeric columns - index_numeric = grep("(integer|numeric)", unlist(sapply(poly_weight, class))) - - aw_covariates.terra = function(poly_in, poly_weight, id_poly_in = id_poly_in) { - - poly_intersected = terra::intersect(poly_in, poly_weight) - poly_intersected[["area_segment_"]] = terra::expanse(poly_intersected) - poly_intersected = data.frame(poly_intersected) |> - dplyr::group_by(!!rlang::sym(id_poly_in)) |> - dplyr::summarize(dplyr::across(is.numeric, - ~stats::weighted.mean(., w = area_segment_))) |> - dplyr::ungroup() - return(poly_intersected) - } - - class_poly_in = check_packbound(poly_in) - class_poly_weight = check_packbound(poly_weight) - - if (class_poly_in != class_poly_weight) { - class_poly_weight = switch_packbound(class_poly_weight) - } - - switch(class_poly_in, - sf = sf::st_interpolate_aw(poly_weight[,index_numeric], poly_in, extensive = FALSE), - terra = aw_covariates.terra(poly_in, poly_weight[,index_numeric], id_poly_in = id_poly_in)) - -} - -# ncbuf = terra::intersect(vect(ppb), vect(nc)) -# ncbuf_a = ncbuf -# ncbuf_a$segarea = expanse(ncbuf_a) -# ncbuf_k = data.frame(ncbuf_a) |> -# dplyr::group_by(id) |> -# dplyr::summarize(across(is.numeric, -# ~weighted.mean(., w = segarea))) |> -# dplyr::ungroup() - -#ncbufagg = terra::aggregate(ncbuf, by = 'id', fun = weighted.mean, w = ncbuf_a$segarea) - - -#' @title Extract summarized values from raster with points and a buffer radius (to be written) -#' -#' @description For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. -#' @param points SpatVector object. Coordinates where buffers will be generated -#' @param surf SpatRaster object. A raster of whatnot a summary will be calculated -#' @param radius numeric(1). Buffer radius. here we assume circular buffers only -#' @param id character(1). Unique identifier of each point. -#' @param qsegs integer(1). Number of vertices at a quarter of a circle. Default is 90. -#' @param func a function taking a numeric vector argument. -#' @param kernel character(1). Name of a kernel function (yet to be implemented) -#' @param bandwidth numeric(1). Kernel bandwidth. -#' @return a data.frame object with mean value -#' @author Insang Song \email{geoissong@@gmail.com} -#' -#' @export -extract_with_buffer <- function( - points, surf, radius, id, qsegs = 90, func = mean, kernel = NULL, bandwidth = NULL - ) { - # type check - stopifnot("Check class of the input points.\n" = methods::is(points, "SpatVector")) - stopifnot("Check class of the input radius.\n" = is.numeric(radius)) - stopifnot(is.character(id)) - stopifnot(is.integer(qsegs)) - - if (!is.null(kernel)) { - extracted = extract_with_buffer.flat(points = points, - surf = surf, - radius = radius, - id = id, - func = func, - qsegs = qsegs) - return(extracted) - } - - extracted = extract_with_buffer.kernel(points = points, - surf = surf, - radius = radius, - id = id, - func = func, - qsegs = qsegs, - kernel = kernel, - bandwidth = bandwidth) - return(extracted) - -} - -# Subfunction: extract with buffers (flat weight; simple mean) -extract_with_buffer.flat <- function( - points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL - ) { - # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) - # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) - # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = - surf_at_bufs |> - dplyr::group_by(ID) |> - dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> - dplyr::ungroup() - return(surf_at_bufs_summary) -} - - -# Subfunction: extract with buffers (kernel weight; weighted mean) -extract_with_buffer.kernel <- function( - points, surf, radius, id, qsegs, func = mean, kernel, bandwidth - ) { - # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) - # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) - - # TODO: kernel implementation - - - # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = - surf_at_bufs |> - dplyr::group_by(ID) |> - dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> - dplyr::ungroup() - return(surf_at_bufs_summary) -} - diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/switch_format.R b/scomps.Rcheck/00_pkg_src/scomps/R/switch_format.R deleted file mode 100644 index a0c38e8f..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/R/switch_format.R +++ /dev/null @@ -1,25 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' @title Switch spatial data class -#' @description Convert stars into SpatRaster and vice versa; sf into SpatVector and vice versa. -#' @author Insang Song -#' @param input Spat* in terra or sf object. -#' @return Data converted to the other package class (if sf, terra; if terra, sf) -#' @export -switch_packbound <- function(input) { - stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) - cls_input = check_packbound(input) - type_input = check_datatype(input) - - switched = - switch(cls_input, - sf = switch(type_input, - vector = terra::vect(input), - raster = terra::rast(input) - ), - terra = switch(type_input, - vector = sf::st_as_sf(input), - raster = stars::st_as_stars(input))) - - invisible(switched) -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/R/validate.R b/scomps.Rcheck/00_pkg_src/scomps/R/validate.R deleted file mode 100644 index 545869c2..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/R/validate.R +++ /dev/null @@ -1,18 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand - -#' Validate and repair input vector data -#' @description It tries repairing input vector data. Vector validity violation usually appears in polygon data with self-crossing or hole orders. This function will pass the input_vector object to sf::st_make_valid() (if input_vector is sf) or terra::makeValid() (if input_vector is SpatVector). May take some time depending on the geometry complexity. -#' @author Insang Song -#' @param input_vector One of sf or vect class. Target points of computation. -#' @return A repaired sf or SpatVector object depending on the class of input_vector. -#' @export -validate_and_repair_vectors <- function(input_vector) { - detected = check_packbound(input_vector) - - validated = switch(detected, - terra = terra::makeValid(input_vector), - sf = sf::st_make_valid(input_vector)) - - return(validated) -} - diff --git a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.R b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.R deleted file mode 100644 index c639e81d..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.R +++ /dev/null @@ -1,4 +0,0 @@ -## ----------------------------------------------------------------------------- -knitr::opts_chunk$set(warning = FALSE, message = FALSE) - - diff --git a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.Rmd b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.Rmd deleted file mode 100644 index 8966a59d..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.Rmd +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "Good practice of scomps with HPC" -date: "`r Sys.Date()`" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{good_practice_hpc} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - - -```{r} -knitr::opts_chunk$set(warning = FALSE, message = FALSE) - -``` - -## Assumptions -- Users have an accessible HPC at your work -- Data are stored in distributed file systems (usually incorporated into the HPC system) - - -## Basic workflow - -### Practice for minimizing errors -- Consider using `try()` or `tryCatch()` not to a tiny error will halt all the work without any results - - Especially with the higher-level functions -- "IPDE -- Inspect, Predict, Decide, Execute" all the time - -### Raster-Vector overlay -- Make `sp_index_grid()` to get padded grid objects -- Convert sf/SpatVector objects into `terra::ext()` compatible named numeric vector - - For example: `c(xmin=0, ymin=0, xmax=10, ymax=10)` -- Make list objects with: - - An extent vector in each element - - Preprocessed vector objects with respect to each extent vector in the first list - - Preferably all lists are named -- Write a `future.apply` script running through the extent list object -- Run a small amount of data to estimate the total computational demand -- Submit a job with a proper amount of computational assets diff --git a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.html b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.html deleted file mode 100644 index da4506f4..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v00_good_practice_parallelization.html +++ /dev/null @@ -1,408 +0,0 @@ - - - - - - - - - - - - - - - -Good practice of scomps with HPC - - - - - - - - - - - - - - - - - - - - - - - - - - -

Good practice of scomps with HPC

-

2023-10-04

- - - -
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
-
-

Assumptions

-
    -
  • Users have an accessible HPC at your work
  • -
  • Data are stored in distributed file systems (usually incorporated -into the HPC system)
  • -
-
-
-

Basic workflow

-
-

Practice for minimizing errors

-
    -
  • Consider using try() or tryCatch() not to -a tiny error will halt all the work without any results -
      -
    • Especially with the higher-level functions
    • -
  • -
  • “IPDE – Inspect, Predict, Decide, Execute” all the time
  • -
-
-
-

Raster-Vector overlay

-
    -
  • Make sp_index_grid() to get padded grid objects
  • -
  • Convert sf/SpatVector objects into terra::ext() -compatible named numeric vector -
      -
    • For example: c(xmin=0, ymin=0, xmax=10, ymax=10)
    • -
  • -
  • Make list objects with: -
      -
    • An extent vector in each element
    • -
    • Preprocessed vector objects with respect to each extent vector in -the first list
    • -
    • Preferably all lists are named
    • -
  • -
  • Write a future.apply script running through the extent -list object
  • -
  • Run a small amount of data to estimate the total computational -demand
  • -
  • Submit a job with a proper amount of computational assets
  • -
-
-
- - - - - - - - - - - diff --git a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.R b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.R deleted file mode 100644 index aa3d29fc..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.R +++ /dev/null @@ -1,22 +0,0 @@ -## ----------------------------------------------------------------------------- -knitr::opts_chunk$set(warning = FALSE, message = FALSE) - - -## ----------------------------------------------------------------------------- -library(scomps) -library(sf) -library(terra) -library(stars) -library(dplyr) - - -## ----------------------------------------------------------------------------- -# your_grid = scomps::sp_index_grid() - - -## ----------------------------------------------------------------------------- -# library(mapsf) -# mf_map(your_grid$geometry) - - - diff --git a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.Rmd b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.Rmd deleted file mode 100644 index 4bc1aaf2..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.Rmd +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "Generate computational grids" -date: "`r Sys.Date()`" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{computational_grids} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - - -```{r} -knitr::opts_chunk$set(warning = FALSE, message = FALSE) - -``` - - -## Prepare input data -```{r} -library(scomps) -library(sf) -library(terra) -library(stars) -library(dplyr) - -``` - -## Computational grids -```{r} -# your_grid = scomps::sp_index_grid() - -``` - - -## Visualize computational grids -```{r} -# library(mapsf) -# mf_map(your_grid$geometry) - - -``` - - - -## Notes -- Computational grids are the exhaustive split of the entire study region. You should take a square buffer of each grid to clip the target raster or vector. diff --git a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.html b/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.html deleted file mode 100644 index c2d963b8..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/inst/doc/v01_generate_computational_grid.html +++ /dev/null @@ -1,388 +0,0 @@ - - - - - - - - - - - - - - - -Generate computational grids - - - - - - - - - - - - - - - - - - - - - - - - - - -

Generate computational grids

-

2023-10-04

- - - -
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
-
-

Prepare input data

-
library(scomps)
-library(sf)
-library(terra)
-library(stars)
-library(dplyr)
-
-
-

Computational grids

-
# your_grid = scomps::sp_index_grid()
-
-
-

Visualize computational grids

-
# library(mapsf)
-# mf_map(your_grid$geometry)
-
-
-

Notes

-
    -
  • Computational grids are the exhaustive split of the entire study -region. You should take a square buffer of each grid to clip the target -raster or vector.
  • -
-
- - - - - - - - - - - diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/aw_covariates.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/aw_covariates.Rd deleted file mode 100644 index ca836de6..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/aw_covariates.Rd +++ /dev/null @@ -1,41 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/processing.R -\name{aw_covariates} -\alias{aw_covariates} -\title{Computing area weighted covariates using two polygon sf or SpatVector objects} -\usage{ -aw_covariates(poly_in, poly_weight, id_poly_in = "ID") -} -\arguments{ -\item{poly_in}{A sf/SpatVector object at weighted means will be calculated.} - -\item{poly_weight}{A sf/SpatVector object from which weighted means will be calculated.} - -\item{id_poly_in}{character(1). The unique identifier of each polygon in poly_in} -} -\value{ -A data.frame with all numeric fields of area-weighted means. -} -\description{ -When poly_in and poly_weight are different classes, poly_weight will be converted to the class of poly_in. -} -\examples{ -# package -library(sf) - -# run -nc = sf::st_read(system.file("shape/nc.shp", package="sf")) -nc = sf::st_transform(nc, 5070) -pp = sf::st_sample(nc, size = 300) -pp = sf::st_as_sf(pp) -pp[["id"]] = seq(1, nrow(pp)) -sf::st_crs(pp) = "EPSG:5070" -ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) - -system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) -summary(ppb_nc_aw) -#### Example of aw_covariates ends #### -} -\author{ -Insang Song \email{geoissong@gmail.com} -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/calculate_sedc.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/calculate_sedc.Rd deleted file mode 100644 index 21178a77..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/calculate_sedc.Rd +++ /dev/null @@ -1,34 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/processing.R -\name{calculate_sedc} -\alias{calculate_sedc} -\title{Calculate SEDC covariates} -\usage{ -calculate_sedc( - point_from, - point_to, - id, - sedc_bandwidth, - threshold, - target_fields -) -} -\arguments{ -\item{point_from}{SpatVector object. Locations where the sum of SEDCs are calculated.} - -\item{point_to}{SpatVector object. Locations where each SEDC is calculated.} - -\item{id}{character(1). Name of the unique id field in point_to.} - -\item{sedc_bandwidth}{numeric(1). Distance at which the source concentration is reduced to exp(-3) (approximately 95 \%)} - -\item{threshold}{numeric(1). For computational efficiency, the nearest points in threshold will be selected} - -\item{target_fields}{character(varying). Field names in characters.} -} -\description{ -NOTE: sf implementation is pending. Only available for terra. -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/check_bbox.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/check_bbox.Rd deleted file mode 100644 index 444c934a..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/check_bbox.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/check.R -\name{check_bbox} -\alias{check_bbox} -\title{Check if the data extent is inside the reference bounding box} -\usage{ -check_bbox(data_query, reference, reference_crs = NULL) -} -\arguments{ -\item{data_query}{sf*/stars/SpatVector/SpatRaster object.} - -\item{reference}{sf*/stars/SpatVector/SpatRaster object or a named numeric vector with four names (xmin, ymin, xmax, and ymax).} - -\item{reference_crs}{Well-known-text-formatted or EPSG code of the reference's coordinate system. Only required when a named numeric vector is passed to reference.} -} -\value{ -TRUE (the queried data extent is completely within the reference bounding box) or FALSE -} -\description{ -One of the most common errors in spatial computation is rooted in the entirely or partly incomparable spatial extents of input datasets. This function returns whether your data is inside the target computational extent. It is assumed that you know and have the exact computational region. This function will return TRUE if the reference region completely contains your data's extent and FALSE otherwise. -} -\author{ -Insang Song \email{geoissong@gmail.com} -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/check_crs.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/check_crs.Rd deleted file mode 100644 index 6f9fa5b5..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/check_crs.Rd +++ /dev/null @@ -1,28 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/check.R -\name{check_crs} -\alias{check_crs} -\title{Check Coordinate Reference System} -\usage{ -check_crs(x) -} -\arguments{ -\item{x}{sf/stars/SpatVector/SpatRaster object.} -} -\value{ -A st_crs or crs object. -} -\description{ -Check Coordinate Reference System -} -\examples{ -# data -library(sf) -ncpath = system.file("shape/nc.shp", package = "sf") -nc = read_sf(ncpath) -check_crs(nc) - -} -\author{ -Insang Song \email{geoissong@gmail.com} -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/check_crs2.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/check_crs2.Rd deleted file mode 100644 index c15652d6..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/check_crs2.Rd +++ /dev/null @@ -1,19 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/check.R -\name{check_crs2} -\alias{check_crs2} -\title{check_crs2: Coordinate system checker} -\usage{ -check_crs2(input, crs_standard = "EPSG:4326") -} -\arguments{ -\item{input}{Input object one of sf or terra::Spat* object} - -\item{crs_standard}{character(1). A standard definition of coordinate reference system. Default is "EPSG:4326" Consult \href{https://epsg.io}{epsg.io} for details of other CRS.} -} -\value{ -A (reprojected) sf or SpatVector object. -} -\description{ -The input is checked whether its coordinate system is present. If not, it is reprojected to EPSG:5179. -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/check_packbound.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/check_packbound.Rd deleted file mode 100644 index 6bda7485..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/check_packbound.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/check.R -\name{check_packbound} -\alias{check_packbound} -\title{Return the package the input object is based on} -\usage{ -check_packbound(input) -} -\arguments{ -\item{input}{Spat* in terra or sf object.} -} -\value{ -A character object; one of 'terra' and 'sf' -} -\description{ -Detect whether the input object is sf or Spat* object. -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/check_within_reference.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/check_within_reference.Rd deleted file mode 100644 index c193a975..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/check_within_reference.Rd +++ /dev/null @@ -1,22 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/check.R -\name{check_within_reference} -\alias{check_within_reference} -\title{Check if the boundary of the vector/raster object is inside the reference} -\usage{ -check_within_reference(input_object, reference) -} -\arguments{ -\item{input_object}{sf/stars/SpatVector/SpatRaster object.} - -\item{reference}{sf/stars/SpatVector/SpatRaster object.} -} -\value{ -logical -} -\description{ -Check if the boundary of the vector/raster object is inside the reference -} -\author{ -Insang Song \email{geoissong@gmail.com} -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent.Rd deleted file mode 100644 index 06ec0bbf..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent.Rd +++ /dev/null @@ -1,26 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/processing.R -\name{clip_as_extent} -\alias{clip_as_extent} -\title{Extent clipping} -\usage{ -clip_as_extent(pnts, buffer_r, nqsegs = NULL, target_input) -} -\arguments{ -\item{pnts}{sf or SpatVector object} - -\item{buffer_r}{numeric(1). buffer radius. this value will be automatically multiplied by 1.25} - -\item{nqsegs}{integer(1). the number of points per a quarter circle; SOON TO BE DEPRECATED} - -\item{target_input}{sf or SpatVector object to be clipped} -} -\value{ -A clipped sf or SpatVector object. -} -\description{ -Clip input vector by the expected maximum extent of computation. -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras.Rd deleted file mode 100644 index e6762901..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras.Rd +++ /dev/null @@ -1,23 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/processing.R -\name{clip_as_extent_ras} -\alias{clip_as_extent_ras} -\title{clip_as_extent_ras: Clip input raster.} -\usage{ -clip_as_extent_ras(pnts, buffer_r, nqsegs = 180, ras) -} -\arguments{ -\item{pnts}{sf or SpatVector object} - -\item{buffer_r}{numeric(1). buffer radius. this value will be automatically multiplied by 1.25} - -\item{nqsegs}{integer(1). the number of points per a quarter circle} - -\item{ras}{SpatRaster object to be clipped} -} -\description{ -Clip input raster by the expected maximum extent of computation. -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras2.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras2.Rd deleted file mode 100644 index 6d8c0e00..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/clip_as_extent_ras2.Rd +++ /dev/null @@ -1,23 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/processing.R -\name{clip_as_extent_ras2} -\alias{clip_as_extent_ras2} -\title{clip_as_extent_ras2: Clip input raster (version 2).} -\usage{ -clip_as_extent_ras2(points_in, buffer_r, nqsegs = 180, ras) -} -\arguments{ -\item{points_in}{sf or SpatVector object} - -\item{buffer_r}{numeric(1). buffer radius. this value will be automatically multiplied by 1.25} - -\item{nqsegs}{integer(1). the number of points per a quarter circle} - -\item{ras}{SpatRaster object to be clipped} -} -\description{ -Clip input raster by the expected maximum extent of computation. -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/distribute_process.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/distribute_process.Rd deleted file mode 100644 index ebb58e82..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/distribute_process.Rd +++ /dev/null @@ -1,26 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/interpret_computational_domain.R -\name{distribute_process} -\alias{distribute_process} -\title{Process a given function in the entire or partial computational grids (under construction)} -\usage{ -distribute_process(grids, grid_id = NULL, fun, ...) -} -\arguments{ -\item{grids}{sf/SpatVector object. Computational grids.} - -\item{grid_id}{character(1) or numeric(2). Default is NULL. If NULL, all grid_ids are used. \code{"id_from:id_to"} format or \code{c(unique(grid_id)[id_from], unique(grid_id)[id_to])}} - -\item{fun}{function supported in scomps.} - -\item{...}{Arguments passed to fun.} -} -\value{ -a data.frame object with mean value -} -\description{ -Should -} -\author{ -Insang Song \email{geoissong@gmail.com} -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/estimate_demands.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/estimate_demands.Rd deleted file mode 100644 index 787ad77f..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/estimate_demands.Rd +++ /dev/null @@ -1,23 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/estimate_demands.R -\name{estimate_demands} -\alias{estimate_demands} -\title{Estimate computational demands from inputs (to be written)} -\usage{ -estimate_demands(inputs, nx, ny, padding) -} -\arguments{ -\item{inputs}{a list of sf/Spat* objects or file paths} - -\item{nx}{integer(1).} - -\item{ny}{integer(1).} - -\item{padding}{numeric(1). Extrusion factor} -} -\description{ -Estimate computational demands from inputs (to be written) -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/extent_to_polygon.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/extent_to_polygon.Rd deleted file mode 100644 index 2874461e..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/extent_to_polygon.Rd +++ /dev/null @@ -1,21 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/check.R -\name{extent_to_polygon} -\alias{extent_to_polygon} -\title{Generate a rectangular polygon from extent} -\usage{ -extent_to_polygon(extent, output_class = "terra", crs = "EPSG:4326") -} -\arguments{ -\item{extent}{input extent. A numeric vector with xmin/xmax/ymin/ymax, sf::st_bbox() or terra::ext() outputs.} - -\item{output_class}{character(1). Class of the output polygon. One of "sf" or "terra"} - -\item{crs}{character(1). Coordinate reference system definition.} -} -\description{ -Generate a rectangular polygon from extent -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/extract_with.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/extract_with.Rd deleted file mode 100644 index 8794f571..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/extract_with.Rd +++ /dev/null @@ -1,27 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/processing.R -\name{extract_with} -\alias{extract_with} -\title{Extract raster values with point buffers or polygons} -\usage{ -extract_with(raster, vector, id, func = mean, mode = "polygon", ...) -} -\arguments{ -\item{raster}{SpatRaster object.} - -\item{vector}{SpatVector object.} - -\item{id}{character(1). Unique identifier of each point.} - -\item{func}{function taking one numeric vector argument.} - -\item{mode}{one of "polygon" (generic polygons to extract raster values with) or "buffer" (point with buffer radius)} - -\item{...}{various. Passed to extract_with_buffer. See \code{?extract_with_buffer} for details.} -} -\description{ -Extract raster values with point buffers or polygons -} -\author{ -Insang Song \email{geoissong@gmail.com} -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_buffer.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_buffer.Rd deleted file mode 100644 index f0c3943d..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_buffer.Rd +++ /dev/null @@ -1,43 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/processing.R -\name{extract_with_buffer} -\alias{extract_with_buffer} -\title{Extract summarized values from raster with points and a buffer radius (to be written)} -\usage{ -extract_with_buffer( - points, - surf, - radius, - id, - qsegs = 90, - func = mean, - kernel = NULL, - bandwidth = NULL -) -} -\arguments{ -\item{points}{SpatVector object. Coordinates where buffers will be generated} - -\item{surf}{SpatRaster object. A raster of whatnot a summary will be calculated} - -\item{radius}{numeric(1). Buffer radius. here we assume circular buffers only} - -\item{id}{character(1). Unique identifier of each point.} - -\item{qsegs}{integer(1). Number of vertices at a quarter of a circle. Default is 90.} - -\item{func}{a function taking a numeric vector argument.} - -\item{kernel}{character(1). Name of a kernel function (yet to be implemented)} - -\item{bandwidth}{numeric(1). Kernel bandwidth.} -} -\value{ -a data.frame object with mean value -} -\description{ -For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. -} -\author{ -Insang Song \email{geoissong@gmail.com} -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_polygons.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_polygons.Rd deleted file mode 100644 index adaa9c6a..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/extract_with_polygons.Rd +++ /dev/null @@ -1,28 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/processing.R -\name{extract_with_polygons} -\alias{extract_with_polygons} -\title{Extract summarized values from raster with generic polygons} -\usage{ -extract_with_polygons(polys, surf, id, func = mean, na.rm = TRUE) -} -\arguments{ -\item{polys}{sf/SpatVector object. Polygons.} - -\item{surf}{stars/SpatRaster object. A raster of whatnot a summary will be calculated} - -\item{id}{character(1). Unique identifier of each point.} - -\item{func}{a function taking one argument. For example, function(x) mean(x, na.rm = TRUE) or \(x) mode(x, na.rm = TRUE)} - -\item{na.rm}{logical(1). NA values are omitted when summary is calculated.} -} -\value{ -a data.frame object with function value -} -\description{ -For simplicity, it is assumed that the coordinate systems of the points and the raster are the same. Kernel function is not yet implemented. -} -\author{ -Insang Song \email{geoissong@gmail.com} -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/get_computational_regions.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/get_computational_regions.Rd deleted file mode 100644 index 6a864a55..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/get_computational_regions.Rd +++ /dev/null @@ -1,53 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/interpret_computational_domain.R -\name{get_computational_regions} -\alias{get_computational_regions} -\title{Get a set of computational regions} -\usage{ -get_computational_regions( - input, - mode = "grid", - nx = 10, - ny = 10, - grid_min_features = 30, - padding = NULL, - unit = NULL, - ... -) -} -\arguments{ -\item{input}{sf or Spat* object.} - -\item{mode}{character(1). Mode of region construction. One of "grid" (simple grid regardless of the number of features in each grid), "density" (clustering-based varying grids), "grid_advanced" (merging adjacent grids with smaller number of features than grid_min_features).} - -\item{nx}{integer(1). The number of grids along x-axis.} - -\item{ny}{integer(1). The number of grids along y-axis.} - -\item{grid_min_features}{integer(1). A threshold to merging adjacent grids} - -\item{padding}{numeric(1). A extrusion factor to make buffer to clip actual datasets. Depending on the length unit of the CRS of input.} - -\item{unit}{character(1). The length unit for padding (optional). units::set_units is used for padding when sf object is used. See \href{https://cran.r-project.org/web/packages/units/vignettes/measurement_units_in_R.html}{units package vignette (web)} for the list of acceptable unit forms.} - -\item{...}{arguments passed to the internal function} -} -\value{ -A set of polygons in the input class -} -\description{ -TODO. Using input points, the bounding box is split to the predefined numbers of columns and rows. Each grid will be buffered by the radius. -} -\examples{ -# data -library(sf) -ncpath = system.file("shape/nc.shp", package = "sf") -nc = read_sf(ncpath) -nc = st_transform(nc, "EPSG:5070") -# run -# nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) - -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/grid_merge.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/grid_merge.Rd deleted file mode 100644 index 0361cece..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/grid_merge.Rd +++ /dev/null @@ -1,38 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/interpret_computational_domain.R -\name{grid_merge} -\alias{grid_merge} -\title{grid_merge: Merge grid polygons with given rules} -\usage{ -grid_merge(points_in, grid_in, grid_min_features) -} -\arguments{ -\item{points_in}{sf or SpatVector object. Target points of computation.} - -\item{grid_in}{sf or SpatVector object. The grid generated by sp_index_grid} - -\item{grid_min_features}{integer(1). Threshold to merge adjacent grids.} -} -\value{ -A sf or SpatVector object of computation grids. -} -\description{ -Merge boundary-sharing (in "Rook" contiguity) grids with fewer target features than the threshold. This function strongly assumes that the input is returned from the sp_index_grid, which has 'CGRIDID' as the unique id field. -} -\examples{ -# library(sf) -# library(igraph) -# ligrary(dplyr) -# dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -# sf::st_crs(dg) = 5070 -# dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) -# dgs$CGRIDID = seq(1, nrow(dgs)) -# -# dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -# sf::st_crs(dg_sample) = sf::st_crs(dg) -# dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) -#### NOT RUN #### -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/initate_log.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/initate_log.Rd deleted file mode 100644 index 6e64c090..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/initate_log.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/logging.R -\name{initate_log} -\alias{initate_log} -\title{Turn on logging} -\usage{ -initate_log(expr, dolog = FALSE, logpath) -} -\arguments{ -\item{expr}{expression. Any function call to be logged.} - -\item{dolog}{logical(1). Will the messages be logged.} - -\item{logpath}{character(1). Log file path with the full log file name.} -} -\value{ -Nothing. It will export a log file in the specified path as logpath. -} -\description{ -Turn on logging -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/rast_short.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/rast_short.Rd deleted file mode 100644 index de4acd9f..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/rast_short.Rd +++ /dev/null @@ -1,22 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/preprocessing.R -\name{rast_short} -\alias{rast_short} -\title{Quick call for SpatRaster with a window} -\usage{ -rast_short(rasterpath, win) -} -\arguments{ -\item{rasterpath}{character(1). Path to the raster file.} - -\item{win}{Named integer vector (4) or terra::ext() results.} -} -\value{ -SpatRaster object. -} -\description{ -Quick call for SpatRaster with a window -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/set_clip_extent.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/set_clip_extent.Rd deleted file mode 100644 index 4fb91191..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/set_clip_extent.Rd +++ /dev/null @@ -1,22 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/preprocessing.R -\name{set_clip_extent} -\alias{set_clip_extent} -\title{Setting the clipping extent} -\usage{ -set_clip_extent(pnts, buffer_r) -} -\arguments{ -\item{pnts}{One of sf or vect class. Target points of computation.} - -\item{buffer_r}{numeric(1). Buffer radius. It is assumed in metres} -} -\value{ -A terra::ext or sfc_POLYGON object of the computation extent. -} -\description{ -Return clipping extent with buffer radius. It assumes the input CRS is projected and linear unit is meters. -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/sp_index_grid.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/sp_index_grid.Rd deleted file mode 100644 index bf0d4ac5..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/sp_index_grid.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/interpret_computational_domain.R -\name{sp_index_grid} -\alias{sp_index_grid} -\title{sp_index_grid: Generate grid polygons} -\usage{ -sp_index_grid(points_in, ncutsx, ncutsy) -} -\arguments{ -\item{points_in}{sf or SpatVector object. Target points of computation.} - -\item{ncutsx}{integer(1). The number of splits along x-axis.} - -\item{ncutsy}{integer(1). The number of splits along y-axis.} -} -\value{ -A sf or SpatVector object of computation grids with unique grid id (CGRIDID). -} -\description{ -Returns a sf object that includes x- and y- index by using two inputs ncutsx and ncutsy, which are x- and y-directional splits, respectively. -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/sp_indexing.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/sp_indexing.Rd deleted file mode 100644 index f4da1434..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/sp_indexing.Rd +++ /dev/null @@ -1,21 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/indexing.R -\name{sp_indexing} -\alias{sp_indexing} -\title{Create integer indices for grid} -\usage{ -sp_indexing(points_in, ncutsx, ncutsy) -} -\arguments{ -\item{points_in}{sf object.} - -\item{ncutsx}{integer(1). The number of splits along x-axis.} - -\item{ncutsy}{integer(1). The number of splits along y-axis.} -} -\description{ -Returns a tibble object that includes x- and y- index by using two inputs ncutsx and ncutsy, which are x- and y-directional splits, respectively. -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/switch_packbound.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/switch_packbound.Rd deleted file mode 100644 index 18eafb22..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/switch_packbound.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/switch_format.R -\name{switch_packbound} -\alias{switch_packbound} -\title{Switch spatial data class} -\usage{ -switch_packbound(input) -} -\arguments{ -\item{input}{Spat* in terra or sf object.} -} -\value{ -Data converted to the other package class (if sf, terra; if terra, sf) -} -\description{ -Convert stars into SpatRaster and vice versa; sf into SpatVector and vice versa. -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/man/validate_and_repair_vectors.Rd b/scomps.Rcheck/00_pkg_src/scomps/man/validate_and_repair_vectors.Rd deleted file mode 100644 index e8447ca9..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/man/validate_and_repair_vectors.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/validate.R -\name{validate_and_repair_vectors} -\alias{validate_and_repair_vectors} -\title{Validate and repair input vector data} -\usage{ -validate_and_repair_vectors(input_vector) -} -\arguments{ -\item{input_vector}{One of sf or vect class. Target points of computation.} -} -\value{ -A repaired sf or SpatVector object depending on the class of input_vector. -} -\description{ -It tries repairing input vector data. Vector validity violation usually appears in polygon data with self-crossing or hole orders. This function will pass the input_vector object to sf::st_make_valid() (if input_vector is sf) or terra::makeValid() (if input_vector is SpatVector). May take some time depending on the geometry complexity. -} -\author{ -Insang Song -} diff --git a/scomps.Rcheck/00_pkg_src/scomps/tests/testthat.R b/scomps.Rcheck/00_pkg_src/scomps/tests/testthat.R deleted file mode 100644 index b465b524..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/tests/testthat.R +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of the standard setup for testthat. -# It is recommended that you do not modify it. -# -# Where should you do additional test configuration? -# Learn more about the roles of various files in: -# * https://r-pkgs.org/testing-design.html#sec-tests-files-overview -# * https://testthat.r-lib.org/articles/special-files.html - -library(testthat) -library(scomps) - -test_check("scomps") diff --git a/scomps.Rcheck/00_pkg_src/scomps/tests/testthat/tests.R b/scomps.Rcheck/00_pkg_src/scomps/tests/testthat/tests.R deleted file mode 100644 index 6efa4142..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/tests/testthat/tests.R +++ /dev/null @@ -1,65 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand -testthat::test_that("What package does the input object belong?", -{ - withr::local_package("stars") - withr::local_package("terra") - withr::local_options(list(sf_use_s2 = FALSE)) - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) - - packbound_stars = check_packbound(bcsd_stars) - sprast_bcsd = terra::rast(bcsd_path) - packbound_terra = check_packbound(sprast_bcsd) - - testthat::expect_equal(packbound_stars, "sf") - testthat::expect_equal(packbound_terra, "terra") -}) - - -testthat::test_that("What package does the input object belong?", -{ - withr::local_package("stars") - withr::local_package("terra") - withr::local_options(list(sf_use_s2 = FALSE)) - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) - - nc = system.file(package = "sf", "shape/nc.shp") - nc = sf::read_sf(nc) - - datatype_stars = check_datatype(bcsd_stars) - datatype_sf = check_datatype(nc) - - testthat::expect_equal(datatype_stars, "raster") - testthat::expect_equal(datatype_sf, "vector") -}) - - -testthat::test_that("Format is well converted", -{ - withr::local_package("stars") - withr::local_package("terra") - withr::local_options(list(sf_use_s2 = FALSE)) - - # starts from sf/stars - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) - nc = system.file(package = "sf", "shape/nc.shp") - nc = sf::read_sf(nc) - - stars_bcsd_tr = switch_packbound(bcsd_stars) - sf_nc_tr = switch_packbound(nc) - - testthat::expect_equal(check_packbound(stars_bcsd_tr), "terra") - testthat::expect_equal(check_packbound(sf_nc_tr), "terra") - - stars_bcsd_trb = switch_packbound(stars_bcsd_tr) - sf_nc_trb = switch_packbound(sf_nc_tr) - - testthat::expect_equal(check_packbound(stars_bcsd_trb), "sf") - testthat::expect_equal(check_packbound(sf_nc_trb), "sf") - -}) - - - diff --git a/scomps.Rcheck/00_pkg_src/scomps/vignettes/v00_good_practice_parallelization.Rmd b/scomps.Rcheck/00_pkg_src/scomps/vignettes/v00_good_practice_parallelization.Rmd deleted file mode 100644 index 8966a59d..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/vignettes/v00_good_practice_parallelization.Rmd +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "Good practice of scomps with HPC" -date: "`r Sys.Date()`" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{good_practice_hpc} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - - -```{r} -knitr::opts_chunk$set(warning = FALSE, message = FALSE) - -``` - -## Assumptions -- Users have an accessible HPC at your work -- Data are stored in distributed file systems (usually incorporated into the HPC system) - - -## Basic workflow - -### Practice for minimizing errors -- Consider using `try()` or `tryCatch()` not to a tiny error will halt all the work without any results - - Especially with the higher-level functions -- "IPDE -- Inspect, Predict, Decide, Execute" all the time - -### Raster-Vector overlay -- Make `sp_index_grid()` to get padded grid objects -- Convert sf/SpatVector objects into `terra::ext()` compatible named numeric vector - - For example: `c(xmin=0, ymin=0, xmax=10, ymax=10)` -- Make list objects with: - - An extent vector in each element - - Preprocessed vector objects with respect to each extent vector in the first list - - Preferably all lists are named -- Write a `future.apply` script running through the extent list object -- Run a small amount of data to estimate the total computational demand -- Submit a job with a proper amount of computational assets diff --git a/scomps.Rcheck/00_pkg_src/scomps/vignettes/v01_generate_computational_grid.Rmd b/scomps.Rcheck/00_pkg_src/scomps/vignettes/v01_generate_computational_grid.Rmd deleted file mode 100644 index 4bc1aaf2..00000000 --- a/scomps.Rcheck/00_pkg_src/scomps/vignettes/v01_generate_computational_grid.Rmd +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "Generate computational grids" -date: "`r Sys.Date()`" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{computational_grids} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - - -```{r} -knitr::opts_chunk$set(warning = FALSE, message = FALSE) - -``` - - -## Prepare input data -```{r} -library(scomps) -library(sf) -library(terra) -library(stars) -library(dplyr) - -``` - -## Computational grids -```{r} -# your_grid = scomps::sp_index_grid() - -``` - - -## Visualize computational grids -```{r} -# library(mapsf) -# mf_map(your_grid$geometry) - - -``` - - - -## Notes -- Computational grids are the exhaustive split of the entire study region. You should take a square buffer of each grid to clip the target raster or vector. diff --git a/scomps.Rcheck/00check.log b/scomps.Rcheck/00check.log deleted file mode 100644 index 2fc32c95..00000000 --- a/scomps.Rcheck/00check.log +++ /dev/null @@ -1,79 +0,0 @@ -* using log directory ‘/Users/songi2/Documents/GitHub/Scalable_GIS/scomps.Rcheck’ -* using R version 4.3.1 (2023-06-16) -* using platform: aarch64-apple-darwin20 (64-bit) -* R was compiled by - Apple clang version 14.0.0 (clang-1400.0.29.202) - GNU Fortran (GCC) 12.2.0 -* running under: macOS Ventura 13.6 -* using session charset: UTF-8 -* checking for file ‘scomps/DESCRIPTION’ ... OK -* this is package ‘scomps’ version ‘0.0.3.10042023’ -* package encoding: UTF-8 -* checking package namespace information ... OK -* checking package dependencies ... OK -* checking if this is a source package ... OK -* checking if there is a namespace ... OK -* checking for executable files ... OK -* checking for hidden files and directories ... OK -* checking for portable file names ... OK -* checking for sufficient/correct file permissions ... OK -* checking whether package ‘scomps’ can be installed ... OK -* checking installed package size ... OK -* checking package directory ... OK -* checking DESCRIPTION meta-information ... NOTE -Malformed Description field: should contain one or more complete sentences. -* checking top-level files ... OK -* checking for left-over files ... OK -* checking index information ... OK -* checking package subdirectories ... OK -* checking R files for non-ASCII characters ... OK -* checking R files for syntax errors ... OK -* checking whether the package can be loaded ... OK -* checking whether the package can be loaded with stated dependencies ... OK -* checking whether the package can be unloaded cleanly ... OK -* checking whether the namespace can be loaded with stated dependencies ... OK -* checking whether the namespace can be unloaded cleanly ... OK -* checking loading without being on the library search path ... OK -* checking dependencies in R code ... NOTE -Namespaces in Imports field not imported from: - ‘covr’ ‘future’ ‘testthat’ ‘units’ - All declared Imports should be used. -* checking S3 generic/method consistency ... OK -* checking replacement functions ... OK -* checking foreign function calls ... OK -* checking R code for possible problems ... NOTE -calculate_sedc: no visible binding for global variable ‘dist’ -check_within_reference: no visible binding for global variable ‘x’ -extract_with_buffer.flat: no visible binding for global variable ‘ID’ -extract_with_buffer.kernel: no visible binding for global variable ‘ID’ -get_computational_regions: no visible binding for global variable ‘y’ -sp_indexing: no visible binding for global variable ‘x’ -sp_indexing: no visible binding for global variable ‘y’ -Undefined global functions or variables: - ID dist x y -Consider adding - importFrom("stats", "dist") -to your NAMESPACE file. -* checking Rd files ... OK -* checking Rd metadata ... OK -* checking Rd cross-references ... OK -* checking for missing documentation entries ... OK -* checking for code/documentation mismatches ... OK -* checking Rd \usage sections ... OK -* checking Rd contents ... OK -* checking for unstated dependencies in examples ... OK -* checking installed files from ‘inst/doc’ ... OK -* checking files in ‘vignettes’ ... OK -* checking examples ... OK -* checking for unstated dependencies in ‘tests’ ... OK -* checking tests ... OK - Running ‘testthat.R’ -* checking for unstated dependencies in vignettes ... OK -* checking package vignettes in ‘inst/doc’ ... OK -* checking running R code from vignettes ... NONE - ‘v00_good_practice_parallelization.Rmd’ using ‘UTF-8’... OK - ‘v01_generate_computational_grid.Rmd’ using ‘UTF-8’... OK -* checking re-building of vignette outputs ... OK -* checking PDF version of manual ... OK -* DONE -Status: 3 NOTEs diff --git a/scomps.Rcheck/00install.out b/scomps.Rcheck/00install.out deleted file mode 100644 index 1c871a2e..00000000 --- a/scomps.Rcheck/00install.out +++ /dev/null @@ -1,13 +0,0 @@ -* installing *source* package ‘scomps’ ... -** using staged installation -** R -** inst -** byte-compile and prepare package for lazy loading -** help -*** installing help indices -** building package indices -** installing vignettes -** testing if installed package can be loaded from temporary location -** testing if installed package can be loaded from final location -** testing if installed package keeps a record of temporary installation path -* DONE (scomps) diff --git a/scomps.Rcheck/Rdlatex.log b/scomps.Rcheck/Rdlatex.log deleted file mode 100644 index bb0bdaa0..00000000 --- a/scomps.Rcheck/Rdlatex.log +++ /dev/null @@ -1,564 +0,0 @@ -Hmm ... looks like a package -Converting parsed Rd's to LaTeX .. -Creating pdf output from LaTeX ... - -This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Homebrew) (preloaded format=pdflatex) - restricted \write18 enabled. -entering extended mode -LaTeX2e <2022-11-01> patch level 1 -L3 programming layer <2023-02-22> (./Rd2.tex - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/book.c -ls -Document Class: book 2022/07/02 v1.4n Standard LaTeX document class - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/bk10.c -lo)) (/Library/Frameworks/R.framework/Resources/share/texmf/tex/latex/Rd.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/ifthen -.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/longt -able.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/bm.st -y) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/alltt. -sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/verba -tim.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/url/url.sty -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/textco -mp.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -math.sty -For additional information on amsmath, use the `?' option. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -text.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -gen.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -bsy.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -opn.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am -sfonts.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am -ssymb.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ma -thrsfs.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/iftex/ift -ex.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/fonten -c.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/time -s.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/zi4.sty -`inconsolata-zi4' v1.12, 2019/05/17 Text macros for Inconsolata (msharpe) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/xkeyval/xke -yval.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x -keyval.tex -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x -kvutils.tex -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/k -eyval.tex))))) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/co -lor.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-cf -g/color.cfg) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-de -f/pdftex.def) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/ma -thcolor.ltx)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hy -perref.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/ltxcmds/l -txcmds.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdftexcmd -s/pdftexcmds.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/infwarerr -/infwarerr.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvsetkeys/k -vsetkeys.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/kvdefinek -eys/kvdefinekeys.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdfescape -/pdfescape.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hycolor/hyc -olor.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/letltxmacro -/letltxmacro.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/auxhook/aux -hook.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/na -meref.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/refcount/re -fcount.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/gettitles -tring/gettitlestring.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvoptions/k -voptions.sty))) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pd -1enc.def) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/intcalc/i -ntcalc.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/etexcmds/ -etexcmds.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pu -enc.def) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bitset/bi -tset.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bigintcal -c/bigintcalc.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atbegs -hi-ltx.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hp -dftex.def -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atvery -end-ltx.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/rerunfilech -eck/rerunfilecheck.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/uniquecou -nter/uniquecounter.sty)))) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/makeid -x.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/inpute -nc.sty) -Writing index file Rd2.idx - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1pt -m.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/l3backend/l -3backend-pdftex.def) -No file Rd2.aux. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/context/base/mkii -/supp-pdf.mkii -[Loading MPS to PDF converter (version 2006.09.02).] -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/t1zi4.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um -sa.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um -sb.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ur -sfs.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1ph -v.fd) -No file Rd2.toc. -[1{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/map/pdftex/up -dmap/pdftex.map}{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts -/enc/dvips/base/8r.enc}{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dis -t/fonts/enc/dvips/inconsolata/i4-t1-0.enc}] -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/ts1zi4.fd) [2{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/e -nc/dvips/inconsolata/i4-ts1.enc}] -Overfull \hbox (6.7171pt too wide) in paragraph at lines 143--144 -[]\T1/ptm/m/n/10 sf*/stars/SpatVector/SpatRaster ob-ject or a named nu-meric ve -c-tor with four names -[3] [4] [5] [6] -Overfull \hbox (50.24054pt too wide) in paragraph at lines 376--377 -[]\T1/zi4/m/n/10 "id_from:id_to" []\T1/ptm/m/n/10 for-mat or []\T1/zi4/m/n/10 c -(unique(grid_id)[id_from], unique(grid_id)[id_to]) -[7] [8] [9] [10] [11] [12] [13] [14] [15] -No file Rd2.ind. -[16] -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.aux) - -Package rerunfilecheck Warning: File `Rd2.out' has changed. -(rerunfilecheck) Rerun to get outlines right -(rerunfilecheck) or use package `bookmark'. - - ) -(see the transcript file for additional information) -Output written on Rd2.pdf (16 pages, 110666 bytes). -Transcript written on Rd2.log. -This is makeindex, version 2.17 [TeX Live 2023] (kpathsea + Thai support). -Scanning input file Rd2.idx....done (25 entries accepted, 0 rejected). -Sorting entries....done (101 comparisons). -Generating output file Rd2.ind....done (53 lines written, 0 warnings). -Output written in Rd2.ind. -Transcript written in Rd2.ilg. -This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Homebrew) (preloaded format=pdflatex) - restricted \write18 enabled. -entering extended mode -LaTeX2e <2022-11-01> patch level 1 -L3 programming layer <2023-02-22> (./Rd2.tex - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/book.c -ls -Document Class: book 2022/07/02 v1.4n Standard LaTeX document class - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/bk10.c -lo)) (/Library/Frameworks/R.framework/Resources/share/texmf/tex/latex/Rd.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/ifthen -.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/longt -able.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/bm.st -y) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/alltt. -sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/verba -tim.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/url/url.sty -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/textco -mp.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -math.sty -For additional information on amsmath, use the `?' option. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -text.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -gen.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -bsy.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -opn.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am -sfonts.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am -ssymb.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ma -thrsfs.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/iftex/ift -ex.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/fonten -c.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/time -s.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/zi4.sty -`inconsolata-zi4' v1.12, 2019/05/17 Text macros for Inconsolata (msharpe) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/xkeyval/xke -yval.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x -keyval.tex -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x -kvutils.tex -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/k -eyval.tex))))) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/co -lor.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-cf -g/color.cfg) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-de -f/pdftex.def) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/ma -thcolor.ltx)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hy -perref.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/ltxcmds/l -txcmds.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdftexcmd -s/pdftexcmds.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/infwarerr -/infwarerr.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvsetkeys/k -vsetkeys.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/kvdefinek -eys/kvdefinekeys.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdfescape -/pdfescape.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hycolor/hyc -olor.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/letltxmacro -/letltxmacro.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/auxhook/aux -hook.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/na -meref.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/refcount/re -fcount.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/gettitles -tring/gettitlestring.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvoptions/k -voptions.sty))) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pd -1enc.def) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/intcalc/i -ntcalc.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/etexcmds/ -etexcmds.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pu -enc.def) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bitset/bi -tset.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bigintcal -c/bigintcalc.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atbegs -hi-ltx.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hp -dftex.def -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atvery -end-ltx.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/rerunfilech -eck/rerunfilecheck.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/uniquecou -nter/uniquecounter.sty)))) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/makeid -x.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/inpute -nc.sty) -Writing index file Rd2.idx - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1pt -m.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/l3backend/l -3backend-pdftex.def) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.aux) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/context/base/mkii -/supp-pdf.mkii -[Loading MPS to PDF converter (version 2006.09.02).] -) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.out) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.out) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/t1zi4.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um -sa.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um -sb.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ur -sfs.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1ph -v.fd) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.toc [1{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fo -nts/map/pdftex/updmap/pdftex.map}{/opt/homebrew/Cellar/texlive/20230313_2/share -/texmf-dist/fonts/enc/dvips/base/8r.enc}{/opt/homebrew/Cellar/texlive/20230313_ -2/share/texmf-dist/fonts/enc/dvips/inconsolata/i4-t1-0.enc}]) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/ts1zi4.fd) [2{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/e -nc/dvips/inconsolata/i4-ts1.enc}] -Overfull \hbox (6.7171pt too wide) in paragraph at lines 143--144 -[]\T1/ptm/m/n/10 sf*/stars/SpatVector/SpatRaster ob-ject or a named nu-meric ve -c-tor with four names -[3] [4] [5] [6] [7] -Overfull \hbox (50.24054pt too wide) in paragraph at lines 376--377 -[]\T1/zi4/m/n/10 "id_from:id_to" []\T1/ptm/m/n/10 for-mat or []\T1/zi4/m/n/10 c -(unique(grid_id)[id_from], unique(grid_id)[id_to]) -[8] [9] [10] [11] [12] [13] [14] [15] -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.ind [16] [17]) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.aux) - -Package rerunfilecheck Warning: File `Rd2.out' has changed. -(rerunfilecheck) Rerun to get outlines right -(rerunfilecheck) or use package `bookmark'. - - ) -(see the transcript file for additional information) -Output written on Rd2.pdf (17 pages, 115771 bytes). -Transcript written on Rd2.log. -This is makeindex, version 2.17 [TeX Live 2023] (kpathsea + Thai support). -Scanning input file Rd2.idx....done (25 entries accepted, 0 rejected). -Sorting entries....done (101 comparisons). -Generating output file Rd2.ind....done (53 lines written, 0 warnings). -Output written in Rd2.ind. -Transcript written in Rd2.ilg. -This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Homebrew) (preloaded format=pdflatex) - restricted \write18 enabled. -entering extended mode -LaTeX2e <2022-11-01> patch level 1 -L3 programming layer <2023-02-22> (./Rd2.tex - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/book.c -ls -Document Class: book 2022/07/02 v1.4n Standard LaTeX document class - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/bk10.c -lo)) (/Library/Frameworks/R.framework/Resources/share/texmf/tex/latex/Rd.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/ifthen -.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/longt -able.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/bm.st -y) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/alltt. -sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/verba -tim.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/url/url.sty -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/textco -mp.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -math.sty -For additional information on amsmath, use the `?' option. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -text.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -gen.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -bsy.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -opn.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am -sfonts.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am -ssymb.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ma -thrsfs.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/iftex/ift -ex.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/fonten -c.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/time -s.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/zi4.sty -`inconsolata-zi4' v1.12, 2019/05/17 Text macros for Inconsolata (msharpe) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/xkeyval/xke -yval.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x -keyval.tex -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x -kvutils.tex -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/k -eyval.tex))))) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/co -lor.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-cf -g/color.cfg) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-de -f/pdftex.def) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/ma -thcolor.ltx)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hy -perref.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/ltxcmds/l -txcmds.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdftexcmd -s/pdftexcmds.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/infwarerr -/infwarerr.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvsetkeys/k -vsetkeys.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/kvdefinek -eys/kvdefinekeys.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdfescape -/pdfescape.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hycolor/hyc -olor.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/letltxmacro -/letltxmacro.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/auxhook/aux -hook.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/na -meref.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/refcount/re -fcount.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/gettitles -tring/gettitlestring.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvoptions/k -voptions.sty))) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pd -1enc.def) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/intcalc/i -ntcalc.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/etexcmds/ -etexcmds.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pu -enc.def) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bitset/bi -tset.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bigintcal -c/bigintcalc.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atbegs -hi-ltx.sty)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hp -dftex.def -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atvery -end-ltx.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/rerunfilech -eck/rerunfilecheck.sty -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/uniquecou -nter/uniquecounter.sty)))) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/makeid -x.sty) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/inpute -nc.sty) -Writing index file Rd2.idx - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1pt -m.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/l3backend/l -3backend-pdftex.def) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.aux) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/context/base/mkii -/supp-pdf.mkii -[Loading MPS to PDF converter (version 2006.09.02).] -) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.out) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.out) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/t1zi4.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um -sa.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um -sb.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ur -sfs.fd) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1ph -v.fd) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.toc [1{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fo -nts/map/pdftex/updmap/pdftex.map}{/opt/homebrew/Cellar/texlive/20230313_2/share -/texmf-dist/fonts/enc/dvips/base/8r.enc}{/opt/homebrew/Cellar/texlive/20230313_ -2/share/texmf-dist/fonts/enc/dvips/inconsolata/i4-t1-0.enc}]) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/ts1zi4.fd) [2{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/e -nc/dvips/inconsolata/i4-ts1.enc}] [3] -Overfull \hbox (6.7171pt too wide) in paragraph at lines 143--144 -[]\T1/ptm/m/n/10 sf*/stars/SpatVector/SpatRaster ob-ject or a named nu-meric ve -c-tor with four names -[4] [5] [6] [7] -Overfull \hbox (50.24054pt too wide) in paragraph at lines 376--377 -[]\T1/zi4/m/n/10 "id_from:id_to" []\T1/ptm/m/n/10 for-mat or []\T1/zi4/m/n/10 c -(unique(grid_id)[id_from], unique(grid_id)[id_to]) -[8] [9] [10] [11] [12] [13] [14] [15] -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.ind [16] [17]) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.aux) ) -(see the transcript file for additional information) -Output written on Rd2.pdf (17 pages, 116155 bytes). -Transcript written on Rd2.log. -Saving output to ‘scomps-manual.pdf’ ... -Done -You may want to clean up by 'rm -Rf /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpOaxUwq/Rd2pdff3c856e679a5' diff --git a/scomps.Rcheck/scomps-Ex.R b/scomps.Rcheck/scomps-Ex.R deleted file mode 100644 index 4c502e90..00000000 --- a/scomps.Rcheck/scomps-Ex.R +++ /dev/null @@ -1,121 +0,0 @@ -pkgname <- "scomps" -source(file.path(R.home("share"), "R", "examples-header.R")) -options(warn = 1) -library('scomps') - -base::assign(".oldSearch", base::search(), pos = 'CheckExEnv') -base::assign(".old_wd", base::getwd(), pos = 'CheckExEnv') -cleanEx() -nameEx("aw_covariates") -### * aw_covariates - -flush(stderr()); flush(stdout()) - -### Name: aw_covariates -### Title: Computing area weighted covariates using two polygon sf or -### SpatVector objects -### Aliases: aw_covariates - -### ** Examples - -# package -library(sf) - -# run -nc = sf::st_read(system.file("shape/nc.shp", package="sf")) -nc = sf::st_transform(nc, 5070) -pp = sf::st_sample(nc, size = 300) -pp = sf::st_as_sf(pp) -pp[["id"]] = seq(1, nrow(pp)) -sf::st_crs(pp) = "EPSG:5070" -ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) - -system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) -summary(ppb_nc_aw) -#### Example of aw_covariates ends #### - - - -cleanEx() -nameEx("check_crs") -### * check_crs - -flush(stderr()); flush(stdout()) - -### Name: check_crs -### Title: Check Coordinate Reference System -### Aliases: check_crs - -### ** Examples - -# data -library(sf) -ncpath = system.file("shape/nc.shp", package = "sf") -nc = read_sf(ncpath) -check_crs(nc) - - - - -cleanEx() -nameEx("get_computational_regions") -### * get_computational_regions - -flush(stderr()); flush(stdout()) - -### Name: get_computational_regions -### Title: Get a set of computational regions -### Aliases: get_computational_regions - -### ** Examples - -# data -library(sf) -ncpath = system.file("shape/nc.shp", package = "sf") -nc = read_sf(ncpath) -nc = st_transform(nc, "EPSG:5070") -# run -# nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) - - - - -cleanEx() -nameEx("grid_merge") -### * grid_merge - -flush(stderr()); flush(stdout()) - -### Name: grid_merge -### Title: grid_merge: Merge grid polygons with given rules -### Aliases: grid_merge - -### ** Examples - -# library(sf) -# library(igraph) -# ligrary(dplyr) -# dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -# sf::st_crs(dg) = 5070 -# dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) -# dgs$CGRIDID = seq(1, nrow(dgs)) -# -# dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -# sf::st_crs(dg_sample) = sf::st_crs(dg) -# dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) -#### NOT RUN #### - - - -### *
-### -cleanEx() -options(digits = 7L) -base::cat("Time elapsed: ", proc.time() - base::get("ptime", pos = 'CheckExEnv'),"\n") -grDevices::dev.off() -### -### Local variables: *** -### mode: outline-minor *** -### outline-regexp: "\\(> \\)?### [*]+" *** -### End: *** -quit('no') diff --git a/scomps.Rcheck/scomps-Ex.Rout b/scomps.Rcheck/scomps-Ex.Rout deleted file mode 100644 index 68d31f33..00000000 --- a/scomps.Rcheck/scomps-Ex.Rout +++ /dev/null @@ -1,212 +0,0 @@ - -R version 4.3.1 (2023-06-16) -- "Beagle Scouts" -Copyright (C) 2023 The R Foundation for Statistical Computing -Platform: aarch64-apple-darwin20 (64-bit) - -R is free software and comes with ABSOLUTELY NO WARRANTY. -You are welcome to redistribute it under certain conditions. -Type 'license()' or 'licence()' for distribution details. - - Natural language support but running in an English locale - -R is a collaborative project with many contributors. -Type 'contributors()' for more information and -'citation()' on how to cite R or R packages in publications. - -Type 'demo()' for some demos, 'help()' for on-line help, or -'help.start()' for an HTML browser interface to help. -Type 'q()' to quit R. - -> pkgname <- "scomps" -> source(file.path(R.home("share"), "R", "examples-header.R")) -> options(warn = 1) -> library('scomps') -> -> base::assign(".oldSearch", base::search(), pos = 'CheckExEnv') -> base::assign(".old_wd", base::getwd(), pos = 'CheckExEnv') -> cleanEx() -> nameEx("aw_covariates") -> ### * aw_covariates -> -> flush(stderr()); flush(stdout()) -> -> ### Name: aw_covariates -> ### Title: Computing area weighted covariates using two polygon sf or -> ### SpatVector objects -> ### Aliases: aw_covariates -> -> ### ** Examples -> -> # package -> library(sf) -Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE -> -> # run -> nc = sf::st_read(system.file("shape/nc.shp", package="sf")) -Reading layer `nc' from data source - `/Users/songi2/Library/R/arm64/4.3/library/sf/shape/nc.shp' - using driver `ESRI Shapefile' -Simple feature collection with 100 features and 14 fields -Geometry type: MULTIPOLYGON -Dimension: XY -Bounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965 -Geodetic CRS: NAD27 -> nc = sf::st_transform(nc, 5070) -> pp = sf::st_sample(nc, size = 300) -> pp = sf::st_as_sf(pp) -> pp[["id"]] = seq(1, nrow(pp)) -> sf::st_crs(pp) = "EPSG:5070" -> ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) -> -> system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) -Warning in st_interpolate_aw.sf(poly_weight[, index_numeric], poly_in, extensive = FALSE) : - st_interpolate_aw assumes attributes are constant or uniform over areas of x - user system elapsed - 0.180 0.003 0.183 -> summary(ppb_nc_aw) - AREA PERIMETER CNTY_ CNTY_ID - Min. :0.06133 Min. :1.114 Min. :1825 Min. :1825 - 1st Qu.:0.12008 1st Qu.:1.549 1st Qu.:1917 1st Qu.:1917 - Median :0.13834 Median :1.685 Median :2000 Median :2000 - Mean :0.14702 Mean :1.777 Mean :2004 Mean :2004 - 3rd Qu.:0.17292 3rd Qu.:1.978 3rd Qu.:2078 3rd Qu.:2078 - Max. :0.24000 Max. :3.588 Max. :2241 Max. :2241 - FIPSNO CRESS_ID BIR74 SID74 - Min. :37009 Min. : 5.042 Min. : 315.1 Min. : 0.000 - 1st Qu.:37075 1st Qu.:38.024 1st Qu.: 1955.4 1st Qu.: 4.015 - Median :37104 Median :52.610 Median : 3124.2 Median : 6.867 - Mean :37103 Mean :51.798 Mean : 3977.7 Mean : 8.529 - 3rd Qu.:37131 3rd Qu.:65.974 3rd Qu.: 4639.0 3rd Qu.:10.591 - Max. :37191 Max. :95.910 Max. :18561.5 Max. :36.075 - NWBIR74 BIR79 SID79 NWBIR79 - Min. : 6.222 Min. : 403.3 Min. : 0.000 Min. : 4.222 - 1st Qu.: 458.022 1st Qu.: 2393.5 1st Qu.: 4.990 1st Qu.: 589.223 - Median : 955.882 Median : 3903.2 Median : 8.036 Median :1189.908 - Mean :1285.378 Mean : 5092.6 Mean :10.052 Mean :1655.747 - 3rd Qu.:1669.800 3rd Qu.: 5904.1 3rd Qu.:13.890 3rd Qu.:2127.972 - Max. :6467.572 Max. :26115.7 Max. :34.448 Max. :9367.957 - geometry - POLYGON :300 - epsg:5070 : 0 - +proj=aea ...: 0 - - - -> #### Example of aw_covariates ends #### -> -> -> -> cleanEx() - -detaching ‘package:sf’ - -> nameEx("check_crs") -> ### * check_crs -> -> flush(stderr()); flush(stdout()) -> -> ### Name: check_crs -> ### Title: Check Coordinate Reference System -> ### Aliases: check_crs -> -> ### ** Examples -> -> # data -> library(sf) -Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE -> ncpath = system.file("shape/nc.shp", package = "sf") -> nc = read_sf(ncpath) -> check_crs(nc) -Coordinate Reference System: - User input: NAD27 - wkt: -GEOGCRS["NAD27", - DATUM["North American Datum 1927", - ELLIPSOID["Clarke 1866",6378206.4,294.978698213898, - LENGTHUNIT["metre",1]]], - PRIMEM["Greenwich",0, - ANGLEUNIT["degree",0.0174532925199433]], - CS[ellipsoidal,2], - AXIS["latitude",north, - ORDER[1], - ANGLEUNIT["degree",0.0174532925199433]], - AXIS["longitude",east, - ORDER[2], - ANGLEUNIT["degree",0.0174532925199433]], - ID["EPSG",4267]] -> -> -> -> -> cleanEx() - -detaching ‘package:sf’ - -> nameEx("get_computational_regions") -> ### * get_computational_regions -> -> flush(stderr()); flush(stdout()) -> -> ### Name: get_computational_regions -> ### Title: Get a set of computational regions -> ### Aliases: get_computational_regions -> -> ### ** Examples -> -> # data -> library(sf) -Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE -> ncpath = system.file("shape/nc.shp", package = "sf") -> nc = read_sf(ncpath) -> nc = st_transform(nc, "EPSG:5070") -> # run -> # nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) -> -> -> -> -> cleanEx() - -detaching ‘package:sf’ - -> nameEx("grid_merge") -> ### * grid_merge -> -> flush(stderr()); flush(stdout()) -> -> ### Name: grid_merge -> ### Title: grid_merge: Merge grid polygons with given rules -> ### Aliases: grid_merge -> -> ### ** Examples -> -> # library(sf) -> # library(igraph) -> # ligrary(dplyr) -> # dg = sf::st_as_sfc(st_bbox(c(xmin = 0, ymin = 0, xmax = 8e5, ymax = 6e5))) -> # sf::st_crs(dg) = 5070 -> # dgs = sf::st_as_sf(st_make_grid(dg, n = c(20, 15))) -> # dgs$CGRIDID = seq(1, nrow(dgs)) -> # -> # dg_sample = st_sample(dg, kappa = 5e-9, mu = 15, scale = 20000, type = "Thomas") -> # sf::st_crs(dg_sample) = sf::st_crs(dg) -> # dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) -> #### NOT RUN #### -> -> -> -> ### *
-> ### -> cleanEx() -> options(digits = 7L) -> base::cat("Time elapsed: ", proc.time() - base::get("ptime", pos = 'CheckExEnv'),"\n") -Time elapsed: 0.684 0.035 0.72 0 0 -> grDevices::dev.off() -null device - 1 -> ### -> ### Local variables: *** -> ### mode: outline-minor *** -> ### outline-regexp: "\\(> \\)?### [*]+" *** -> ### End: *** -> quit('no') diff --git a/scomps.Rcheck/scomps-Ex.pdf b/scomps.Rcheck/scomps-Ex.pdf deleted file mode 100644 index ec1c6fe30269924782ad2fae006daca8aea4de34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3611 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 Ykwh3Ufe!yTo3^&D4nkSk+};B5Ul$NA%K!iX diff --git a/scomps.Rcheck/scomps-manual.log b/scomps.Rcheck/scomps-manual.log deleted file mode 100644 index a85a6b5f..00000000 --- a/scomps.Rcheck/scomps-manual.log +++ /dev/null @@ -1,570 +0,0 @@ -This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Homebrew) (preloaded format=pdflatex 2023.6.22) 4 OCT 2023 11:41 -entering extended mode - restricted \write18 enabled. - %&-line parsing enabled. -**\input ./Rd2.tex \input ./Rd2.tex \input ./Rd2.tex - (./Rd2.tex - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/book.c -ls -Document Class: book 2022/07/02 v1.4n Standard LaTeX document class - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/bk10.c -lo -File: bk10.clo 2022/07/02 v1.4n Standard LaTeX file (size option) -) -\c@part=\count185 -\c@chapter=\count186 -\c@section=\count187 -\c@subsection=\count188 -\c@subsubsection=\count189 -\c@paragraph=\count190 -\c@subparagraph=\count191 -\c@figure=\count192 -\c@table=\count193 -\abovecaptionskip=\skip48 -\belowcaptionskip=\skip49 -\bibindent=\dimen140 -) (/Library/Frameworks/R.framework/Resources/share/texmf/tex/latex/Rd.sty -Package: Rd - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/ifthen -.sty -Package: ifthen 2022/04/13 v1.1d Standard LaTeX ifthen package (DPC) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/longt -able.sty -Package: longtable 2021-09-01 v4.17 Multi-page Table package (DPC) -\LTleft=\skip50 -\LTright=\skip51 -\LTpre=\skip52 -\LTpost=\skip53 -\LTchunksize=\count194 -\LTcapwidth=\dimen141 -\LT@head=\box51 -\LT@firsthead=\box52 -\LT@foot=\box53 -\LT@lastfoot=\box54 -\LT@gbox=\box55 -\LT@cols=\count195 -\LT@rows=\count196 -\c@LT@tables=\count197 -\c@LT@chunks=\count198 -\LT@p@ftn=\toks16 -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/bm.st -y -Package: bm 2022/01/05 v1.2f Bold Symbol Support (DPC/FMi) -\symboldoperators=\mathgroup4 -\symboldletters=\mathgroup5 -\symboldsymbols=\mathgroup6 -Package bm Info: No bold for \OMX/cmex/m/n, using \pmb. -LaTeX Font Info: Redeclaring math alphabet \mathbf on input line 149. -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/alltt. -sty -Package: alltt 2021/01/29 v2.0g defines alltt environment -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/tools/verba -tim.sty -Package: verbatim 2022-07-02 v1.5u LaTeX2e package for verbatim enhancements -\every@verbatim=\toks17 -\verbatim@line=\toks18 -\verbatim@in@stream=\read2 -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/url/url.sty -\Urlmuskip=\muskip16 -Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/textco -mp.sty -Package: textcomp 2020/02/02 v2.0n Standard LaTeX package -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -math.sty -Package: amsmath 2022/04/08 v2.17n AMS math features -\@mathmargin=\skip54 - -For additional information on amsmath, use the `?' option. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -text.sty -Package: amstext 2021/08/26 v2.01 AMS text - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -gen.sty -File: amsgen.sty 1999/11/30 v2.0 generic functions -\@emptytoks=\toks19 -\ex@=\dimen142 -)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -bsy.sty -Package: amsbsy 1999/11/29 v1.2d Bold Symbols -LaTeX Info: Redefining \boldsymbol on input line 28. -\pmbraise@=\dimen143 -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsmath/ams -opn.sty -Package: amsopn 2022/04/08 v2.04 operator names -) -\inf@bad=\count199 -LaTeX Info: Redefining \frac on input line 234. -\uproot@=\count266 -\leftroot@=\count267 -LaTeX Info: Redefining \overline on input line 399. -LaTeX Info: Redefining \colon on input line 410. -\classnum@=\count268 -\DOTSCASE@=\count269 -LaTeX Info: Redefining \ldots on input line 496. -LaTeX Info: Redefining \dots on input line 499. -LaTeX Info: Redefining \cdots on input line 620. -\Mathstrutbox@=\box56 -\strutbox@=\box57 -LaTeX Info: Redefining \big on input line 722. -LaTeX Info: Redefining \Big on input line 723. -LaTeX Info: Redefining \bigg on input line 724. -LaTeX Info: Redefining \Bigg on input line 725. -\big@size=\dimen144 -LaTeX Font Info: Redeclaring font encoding OML on input line 743. -LaTeX Font Info: Redeclaring font encoding OMS on input line 744. -\macc@depth=\count270 -LaTeX Info: Redefining \bmod on input line 905. -LaTeX Info: Redefining \pmod on input line 910. -LaTeX Info: Redefining \smash on input line 940. -LaTeX Info: Redefining \relbar on input line 970. -LaTeX Info: Redefining \Relbar on input line 971. -\c@MaxMatrixCols=\count271 -\dotsspace@=\muskip17 -\c@parentequation=\count272 -\dspbrk@lvl=\count273 -\tag@help=\toks20 -\row@=\count274 -\column@=\count275 -\maxfields@=\count276 -\andhelp@=\toks21 -\eqnshift@=\dimen145 -\alignsep@=\dimen146 -\tagshift@=\dimen147 -\tagwidth@=\dimen148 -\totwidth@=\dimen149 -\lineht@=\dimen150 -\@envbody=\toks22 -\multlinegap=\skip55 -\multlinetaggap=\skip56 -\mathdisplay@stack=\toks23 -LaTeX Info: Redefining \[ on input line 2953. -LaTeX Info: Redefining \] on input line 2954. -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am -sfonts.sty -Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support -\symAMSa=\mathgroup7 -\symAMSb=\mathgroup8 -LaTeX Font Info: Redeclaring math symbol \hbar on input line 98. -LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' -(Font) U/euf/m/n --> U/euf/b/n on input line 106. -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/am -ssymb.sty -Package: amssymb 2013/01/14 v3.01 AMS font symbols -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ma -thrsfs.sty -Package: mathrsfs 1996/01/01 Math RSFS package v1.0 (jk) -\symrsfs=\mathgroup9 -) -\ldescriptionwidth=\skip57 - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/iftex/ift -ex.sty -Package: iftex 2022/02/03 v1.0f TeX engine tests -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/fonten -c.sty -Package: fontenc 2021/04/29 v2.0v Standard LaTeX package -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/time -s.sty -Package: times 2020/03/25 PSNFSS-v9.3 (SPQR) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/zi4.sty -Package: zi4 2019/05/17 v1.12 - -`inconsolata-zi4' v1.12, 2019/05/17 Text macros for Inconsolata (msharpe) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/xkeyval/xke -yval.sty -Package: xkeyval 2022/06/16 v2.9 package option processing (HA) - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x -keyval.tex -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/x -kvutils.tex -\XKV@toks=\toks24 -\XKV@tempa@toks=\toks25 - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/xkeyval/k -eyval.tex)) -\XKV@depth=\count277 -File: xkeyval.tex 2014/12/03 v2.7a key=value parser (HA) -)) -\zifour@ocount=\count278 -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/co -lor.sty -Package: color 2022/01/06 v1.3d Standard LaTeX Color (DPC) - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-cf -g/color.cfg -File: color.cfg 2016/01/02 v1.6 sample color configuration -) -Package color Info: Driver file: pdftex.def on input line 149. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics-de -f/pdftex.def -File: pdftex.def 2022/09/22 v1.2b Graphics/color driver for pdftex -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/graphics/ma -thcolor.ltx)) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hy -perref.sty -Package: hyperref 2023-02-07 v7.00v Hypertext links for LaTeX - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/ltxcmds/l -txcmds.sty -Package: ltxcmds 2020-05-10 v1.25 LaTeX kernel commands for general use (HO) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdftexcmd -s/pdftexcmds.sty -Package: pdftexcmds 2020-06-27 v0.33 Utility functions of pdfTeX for LuaTeX (HO -) - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/infwarerr -/infwarerr.sty -Package: infwarerr 2019/12/03 v1.5 Providing info/warning/error messages (HO) -) -Package pdftexcmds Info: \pdf@primitive is available. -Package pdftexcmds Info: \pdf@ifprimitive is available. -Package pdftexcmds Info: \pdfdraftmode found. -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvsetkeys/k -vsetkeys.sty -Package: kvsetkeys 2022-10-05 v1.19 Key value parser (HO) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/kvdefinek -eys/kvdefinekeys.sty -Package: kvdefinekeys 2019-12-19 v1.6 Define keys (HO) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/pdfescape -/pdfescape.sty -Package: pdfescape 2019/12/09 v1.15 Implements pdfTeX's escape features (HO) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hycolor/hyc -olor.sty -Package: hycolor 2020-01-27 v1.10 Color options for hyperref/bookmark (HO) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/letltxmacro -/letltxmacro.sty -Package: letltxmacro 2019/12/03 v1.6 Let assignment for LaTeX macros (HO) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/auxhook/aux -hook.sty -Package: auxhook 2019-12-17 v1.6 Hooks for auxiliary files (HO) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/na -meref.sty -Package: nameref 2022-05-17 v2.50 Cross-referencing by name of section - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/refcount/re -fcount.sty -Package: refcount 2019/12/15 v3.6 Data extraction from label references (HO) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/gettitles -tring/gettitlestring.sty -Package: gettitlestring 2019/12/15 v1.6 Cleanup title references (HO) - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/kvoptions/k -voptions.sty -Package: kvoptions 2022-06-15 v3.15 Key value format for package options (HO) -)) -\c@section@level=\count279 -) -\@linkdim=\dimen151 -\Hy@linkcounter=\count280 -\Hy@pagecounter=\count281 - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pd -1enc.def -File: pd1enc.def 2023-02-07 v7.00v Hyperref: PDFDocEncoding definition (HO) -Now handling font encoding PD1 ... -... no UTF-8 mapping file for font encoding PD1 -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/intcalc/i -ntcalc.sty -Package: intcalc 2019/12/15 v1.3 Expandable calculations with integers (HO) -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/etexcmds/ -etexcmds.sty -Package: etexcmds 2019/12/15 v1.7 Avoid name clashes with e-TeX commands (HO) -) -\Hy@SavedSpaceFactor=\count282 - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/pu -enc.def -File: puenc.def 2023-02-07 v7.00v Hyperref: PDF Unicode definition (HO) -Now handling font encoding PU ... -... no UTF-8 mapping file for font encoding PU -) -Package hyperref Info: Hyper figures OFF on input line 4177. -Package hyperref Info: Link nesting OFF on input line 4182. -Package hyperref Info: Hyper index ON on input line 4185. -Package hyperref Info: Plain pages OFF on input line 4192. -Package hyperref Info: Backreferencing OFF on input line 4197. -Package hyperref Info: Implicit mode ON; LaTeX internals redefined. -Package hyperref Info: Bookmarks ON on input line 4425. -\c@Hy@tempcnt=\count283 -LaTeX Info: Redefining \url on input line 4763. -\XeTeXLinkMargin=\dimen152 - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bitset/bi -tset.sty -Package: bitset 2019/12/09 v1.3 Handle bit-vector datatype (HO) - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/bigintcal -c/bigintcalc.sty -Package: bigintcalc 2019/12/15 v1.5 Expandable calculations on big integers (HO -) -)) -\Fld@menulength=\count284 -\Field@Width=\dimen153 -\Fld@charsize=\dimen154 -Package hyperref Info: Hyper figures OFF on input line 6042. -Package hyperref Info: Link nesting OFF on input line 6047. -Package hyperref Info: Hyper index ON on input line 6050. -Package hyperref Info: backreferencing OFF on input line 6057. -Package hyperref Info: Link coloring OFF on input line 6062. -Package hyperref Info: Link coloring with OCG OFF on input line 6067. -Package hyperref Info: PDF/A mode OFF on input line 6072. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atbegs -hi-ltx.sty -Package: atbegshi-ltx 2021/01/10 v1.0c Emulation of the original atbegshi -package with kernel methods -) -\Hy@abspage=\count285 -\c@Item=\count286 -\c@Hfootnote=\count287 -) -Package hyperref Info: Driver (autodetected): hpdftex. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/hyperref/hp -dftex.def -File: hpdftex.def 2023-02-07 v7.00v Hyperref driver for pdfTeX - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/atvery -end-ltx.sty -Package: atveryend-ltx 2020/08/19 v1.0a Emulation of the original atveryend pac -kage -with kernel methods -) -\Fld@listcount=\count288 -\c@bookmark@seq@number=\count289 - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/rerunfilech -eck/rerunfilecheck.sty -Package: rerunfilecheck 2022-07-10 v1.10 Rerun checks for auxiliary files (HO) - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/generic/uniquecou -nter/uniquecounter.sty -Package: uniquecounter 2019/12/15 v1.4 Provide unlimited unique counter (HO) -) -Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2 -85. -) -\Hy@SectionHShift=\skip58 -) -Package hyperref Info: Option `colorlinks' set `true' on input line 390. -Package hyperref Info: Option `linktocpage' set `true' on input line 390. -Package hyperref Info: Option `plainpages' set `false' on input line 390. -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/makeid -x.sty -Package: makeidx 2021/10/04 v1.0m Standard LaTeX package -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/base/inpute -nc.sty -Package: inputenc 2021/02/14 v1.3d Input encoding file -\inpenc@prehook=\toks26 -\inpenc@posthook=\toks27 -) -\@indexfile=\write3 -\openout3 = `Rd2.idx'. - - -Writing index file Rd2.idx -LaTeX Font Info: Trying to load font information for T1+ptm on input line 8. - - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1pt -m.fd -File: t1ptm.fd 2001/06/04 font definitions for T1/ptm. -) -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/l3backend/l -3backend-pdftex.def -File: l3backend-pdftex.def 2023-01-16 L3 backend support: PDF output (pdfTeX) -\l__color_backend_stack_int=\count290 -\l__pdf_internal_box=\box58 -) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.aux) -\openout1 = `Rd2.aux'. - -LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 8. -LaTeX Font Info: ... okay on input line 8. -LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 8. -LaTeX Font Info: ... okay on input line 8. -LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 8. -LaTeX Font Info: ... okay on input line 8. -LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 8. -LaTeX Font Info: ... okay on input line 8. -LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 8. -LaTeX Font Info: ... okay on input line 8. -LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 8. -LaTeX Font Info: ... okay on input line 8. -LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 8. -LaTeX Font Info: ... okay on input line 8. -LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 8. -LaTeX Font Info: ... okay on input line 8. -LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 8. -LaTeX Font Info: ... okay on input line 8. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/context/base/mkii -/supp-pdf.mkii -[Loading MPS to PDF converter (version 2006.09.02).] -\scratchcounter=\count291 -\scratchdimen=\dimen155 -\scratchbox=\box59 -\nofMPsegments=\count292 -\nofMParguments=\count293 -\everyMPshowfont=\toks28 -\MPscratchCnt=\count294 -\MPscratchDim=\dimen156 -\MPnumerator=\count295 -\makeMPintoPDFobject=\count296 -\everyMPtoPDFconversion=\toks29 -) -Package hyperref Info: Link coloring ON on input line 8. - -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.out) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.out) -\@outlinefile=\write4 -\openout4 = `Rd2.out'. - -LaTeX Font Info: Trying to load font information for T1+zi4 on input line 33 -. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/t1zi4.fd -File: t1zi4.fd 2018/01/14 T1/zi4 (Inconsolata) -) -LaTeX Font Info: Font shape `T1/zi4/m/n' will be -(Font) scaled to size 10.0pt on input line 33. -LaTeX Font Info: Trying to load font information for U+msa on input line 33. - - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um -sa.fd -File: umsa.fd 2013/01/14 v3.01 AMS symbols A -) -LaTeX Font Info: Trying to load font information for U+msb on input line 33. - - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/amsfonts/um -sb.fd -File: umsb.fd 2013/01/14 v3.01 AMS symbols B -) -LaTeX Font Info: Trying to load font information for U+rsfs on input line 33 -. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/jknapltx/ur -sfs.fd -File: ursfs.fd 1998/03/24 rsfs font definition file (jk) -) -LaTeX Font Info: Trying to load font information for T1+phv on input line 36 -. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/psnfss/t1ph -v.fd -File: t1phv.fd 2020/03/25 scalable font definitions for T1/phv. -) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.toc [1 - - -{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/map/pdftex/updm -ap/pdftex.map}{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/e -nc/dvips/base/8r.enc}{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/ -fonts/enc/dvips/inconsolata/i4-t1-0.enc}]) -\tf@toc=\write5 -\openout5 = `Rd2.toc'. - -LaTeX Font Info: Font shape `T1/zi4/m/n' will be -(Font) scaled to size 9.0pt on input line 69. -LaTeX Font Info: Trying to load font information for TS1+zi4 on input line 8 -0. - -(/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/tex/latex/inconsolata -/ts1zi4.fd -File: ts1zi4.fd 2018/01/14 TS1/zi4 (Inconsolata) -) -LaTeX Font Info: Font shape `TS1/zi4/m/n' will be -(Font) scaled to size 9.0pt on input line 80. - [2{/opt/homebrew/Cellar/texlive/20230313_2/share/texmf-dist/fonts/enc/dvips/in -consolata/i4-ts1.enc}] [3] -Overfull \hbox (6.7171pt too wide) in paragraph at lines 143--144 -[]\T1/ptm/m/n/10 sf*/stars/SpatVector/SpatRaster ob-ject or a named nu-meric ve -c-tor with four names - [] - -[4] [5] [6] [7] -Overfull \hbox (50.24054pt too wide) in paragraph at lines 376--377 -[]\T1/zi4/m/n/10 "id_from:id_to" []\T1/ptm/m/n/10 for-mat or []\T1/zi4/m/n/10 c -(unique(grid_id)[id_from], unique(grid_id)[id_to]) - [] - -[8] [9] [10] [11] [12] [13] [14] [15] -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.ind [16] [17 - - -]) -(/private/var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T/RtmpOaxUwq/Rd2pdff3c8 -56e679a5/Rd2.aux) -Package rerunfilecheck Info: File `Rd2.out' has not changed. -(rerunfilecheck) Checksum: C70573B6B3562A9A0AAA03892470A1FF;3666. - ) -Here is how much of TeX's memory you used: - 10599 strings out of 476025 - 168736 string characters out of 5779036 - 1866388 words of memory out of 5000000 - 30666 multiletter control sequences out of 15000+600000 - 549019 words of font info for 77 fonts, out of 8000000 for 9000 - 1141 hyphenation exceptions out of 8191 - 92i,6n,92p,475b,729s stack positions out of 10000i,1000n,20000p,200000b,200000s - -Output written on Rd2.pdf (17 pages, 116155 bytes). -PDF statistics: - 465 PDF objects out of 1000 (max. 8388607) - 428 compressed objects within 5 object streams - 192 named destinations out of 1000 (max. 500000) - 209 words of extra memory for PDF output out of 10000 (max. 10000000) - diff --git a/scomps.Rcheck/scomps-manual.pdf b/scomps.Rcheck/scomps-manual.pdf deleted file mode 100644 index 400991eee523a64e71fe737ff6f44ea083d436c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116155 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

2p0&Ndnn;8doG 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 diff --git a/scomps.Rcheck/scomps/DESCRIPTION b/scomps.Rcheck/scomps/DESCRIPTION deleted file mode 100644 index 737d2c62..00000000 --- a/scomps.Rcheck/scomps/DESCRIPTION +++ /dev/null @@ -1,22 +0,0 @@ -Package: scomps -Title: Scalable R geospatial computation -Version: 0.0.3.10042023 -Authors@R: - person("Insang", "Song", , "geoissong@gmail.com", role = c("aut", "cre"), - comment = c(ORCID = "0000-0001-8732-3256")) -Description: A package for scalable geospatial computation for - environmental health research -License: MIT + file LICENSE -Encoding: UTF-8 -Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.3 -Imports: covr, dplyr, future, future.apply, methods, rlang, sf, stars, - terra, testthat, units -Suggests: future.batchtools, igraph, knitr, logr, rmarkdown, withr -VignetteBuilder: knitr -Config/testthat/edition: 3 -NeedsCompilation: no -Packaged: 2023-10-04 15:41:03 UTC; songi2 -Author: Insang Song [aut, cre] () -Maintainer: Insang Song -Built: R 4.3.1; ; 2023-10-04 15:41:20 UTC; unix diff --git a/scomps.Rcheck/scomps/INDEX b/scomps.Rcheck/scomps/INDEX deleted file mode 100644 index 80dc13d3..00000000 --- a/scomps.Rcheck/scomps/INDEX +++ /dev/null @@ -1,39 +0,0 @@ -aw_covariates Computing area weighted covariates using two - polygon sf or SpatVector objects -calculate_sedc Calculate SEDC covariates -check_bbox Check if the data extent is inside the - reference bounding box -check_crs Check Coordinate Reference System -check_crs2 check_crs2: Coordinate system checker -check_packbound Return the package the input object is based on -check_within_reference - Check if the boundary of the vector/raster - object is inside the reference -clip_as_extent Extent clipping -clip_as_extent_ras clip_as_extent_ras: Clip input raster. -clip_as_extent_ras2 clip_as_extent_ras2: Clip input raster (version - 2). -distribute_process Process a given function in the entire or - partial computational grids (under - construction) -estimate_demands Estimate computational demands from inputs (to - be written) -extent_to_polygon Generate a rectangular polygon from extent -extract_with Extract raster values with point buffers or - polygons -extract_with_buffer Extract summarized values from raster with - points and a buffer radius (to be written) -extract_with_polygons Extract summarized values from raster with - generic polygons -get_computational_regions - Get a set of computational regions -grid_merge grid_merge: Merge grid polygons with given - rules -initate_log Turn on logging -rast_short Quick call for SpatRaster with a window -set_clip_extent Setting the clipping extent -sp_index_grid sp_index_grid: Generate grid polygons -sp_indexing Create integer indices for grid -switch_packbound Switch spatial data class -validate_and_repair_vectors - Validate and repair input vector data diff --git a/scomps.Rcheck/scomps/LICENSE b/scomps.Rcheck/scomps/LICENSE deleted file mode 100644 index 74e6421f..00000000 --- a/scomps.Rcheck/scomps/LICENSE +++ /dev/null @@ -1,2 +0,0 @@ -YEAR: 2023 -COPYRIGHT HOLDER: I. Song diff --git a/scomps.Rcheck/scomps/Meta/Rd.rds b/scomps.Rcheck/scomps/Meta/Rd.rds deleted file mode 100644 index ac6f584a8d8d331ce9a42e195e4c615f4c00703c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1232 zcmV;>1TXs^iwFP!000001Kn2LZyYrc-!_T36hccw5fKOsQlLd@iV6=XhzE3}6+%Uj zq!r?2<@5UX-0rPcw)ZZ_6aOv$1!4TPYkN0EJd%gK-J2QD=WoXI+pR3iwzBQ58`;(l zd}ce(&!0T}259^6X9CY1cn-4dY*&Bdbx!yS3x*YyN2i6Oze8|E+6sudqy_02dt^b$ zt9&-&7d`PUOC&-L1cCOrC*HNh29sAa-quCWIk22HQwvt-g3hU+HKCzL6>D-Vb9$j@ zt$N12n2`${c=6tl8Mt$=U{VP-Yaz@=a6)Bpbe~GamO29kUE;b3SnoP*isuclHYKln z-fiFsOq2;Fa3mz>vvv*v_T2X)uG1M9{IH}7>a=WHg%#s9t{_Dvi)8jn!HRrIMHyu6 zZB{d-W2kr;h(a1vE*D$`dAuvN4V|tu!*^tpv$~)cxi%3f_jFbV%J(G%K^9|0{%D0O zR%mx1pAbQVnaEd^C~lDxV{%z9qe$%RM}X>Z zJ%E|d#s~oYp&|Nw!c*w^9vI-xH(-dL4!=XhdEAe}&3EFJSo4|ef#xW01}O7FJ;Z#v z6MXq9N8s`b17vj|Okm~cAG`)r381q7{X355+0;}Ca)hv;7_BKQ7m60B?;6xf%~orU zT$z!aBQDTcgVhU@CB$bh;iD`6)HfJ9JNaRX1|9g_RQCsBbEFm&LFO^C1w~9ER!de; z!|6H)nR012`u6<9Dw%RFfTN9_cH(Cnsp!%P9`I`v zLTkW~KcaA50_sEuQ==i86kng%spSKQ#%}@PdWOL%2Klx_PMWylq4wOLmF;o~c>V+G z@6H=TPGzqPa#t7NnpFw>g0)wL^6h_6Uh1eBN&WluDOF$%Mx=&aoYQ#ve%VjoWAseF zOtm_N&WtI$XsfPmZ=dVVfW*R#E_+OV{%gws`*5pPXzu31Y2YtR6&S>P?WgS-Rc7F5 z6nS{ZWjc%o`Z4P29J%R)Kc2$iQo2JGEx{%nWJKo;TnX-jgEKSykp%BFTFulU74B}# z!x!!rFlDp1fNK-mzvjp_ybtzGJT|TyUJPKeCv`0`Y>DcsRDG#UfWMY_ZU57Pq8g!2%a^ zqD3w_6fAT}nbXBCL1Vn&B?iMqFUk2};fwkIviOCKkzIrLHH&BaX4aQ-r^d@}P)!_h z`w6T3Lbd%f2>9>wP2<0J&Y9|jCMPxFMSr!u@qNW$(eqctWXfT>G~J>*`H61Uuusa= u8GElJ=-1cB(OhUZV)0$U*GJy}J$P>Z2|t&Ymw&|6BxbZU%D5?rF*=c!no}R-ydxpz_-3Qu%b^-vSwlGux diff --git a/scomps.Rcheck/scomps/Meta/hsearch.rds b/scomps.Rcheck/scomps/Meta/hsearch.rds deleted file mode 100644 index c7ab64314d561e959ca8a595fa4cbef8e7bf792a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1124 zcmV-q1e^OGiwFP!000001MOH_ZyYrgp6sTi4U~jdMXGqfAO%_^XtPP%5X1x8E>%^E zLN=`sFC&k~JL`7F9@(DVgg?bUq#R#oCs`1nRzhVTqB%ac&v&lh?BwUoBuVro~!zIfNI3x-@tud47j1nzk>7Nd5G++y1NimvJR!lX`QQKXp zQD$4u1@h@YYJ!AB;~MMd)*2Go3lL(OhM^JBc=T|HE_CX*L(@lyO^}{a1Ri4K0!K_C z#udw{-H9EBY*@yPwv9h=MutL2*fC(o@%Z>mXQ3c?k!7KVmKeE&n69YXQh#=F zW*{cec?TWDSN`tt+GYoRky`y)5qA#fOw20Gl#I^1HAZ$}2o#?>AEXW_1DstWq~ zSE#?gZ-KnY))wTB=ir(%3Hv!~{w$Pl{(|0+$tSPk#PW!=U%!?Ng$O=Y``1e}Pqiu*5vD(wJ&X zIHrq2dw0vU(;>b?6zkk^(;xnL2*jn$glbvyQ%1 zH_Og*&z81qjxGI|xcRkLRxjYy3;1=ufc@9cYVq$D$$HQHZuiQ5&MH$j^IO?;3;b=I zJ8~J0a9qL6x(`mX_q!>fJ?qYF9Jv>NSpLAWBOH6T_xPcg)_(*;!JiYR%XT4Z7Uuu* zh!bIcyEr8KdHZBVBP$wtoiy^l`vU$i{Tt%M4 qBqN!&?3XM-N&Y6v#uIurhflaSjx!X%h_(JpoIe0s$v=tA6aWCQOd$XO diff --git a/scomps.Rcheck/scomps/Meta/links.rds b/scomps.Rcheck/scomps/Meta/links.rds deleted file mode 100644 index 903ef384997310223c74f8ba82c0030c06122b57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 517 zcmV+g0{Z*0h%rBBU)Tv{kXV9=GF2eNU;jsHHvRh#?A$^> H5eEPO{$~Oh diff --git a/scomps.Rcheck/scomps/Meta/nsInfo.rds b/scomps.Rcheck/scomps/Meta/nsInfo.rds deleted file mode 100644 index 41a1f926f35ac5ec8ff3bf293a7cc436b1631f10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 453 zcmV;$0XqI4iwFP!000001AUT9Yuqpp$CZ7s>~1#MW@#bxGvtz7dN1@=D1AV0LY5}> z5L+_Rc(eKPrK4DK?G4l*%lge|9)Hj8jSylk7V`@+U-G9|{`&dl?voI+10S}$;vSzp zuUoMYYuR+)L}7hLA7q zArLmPM+1$rCi8bG2szoh`lWO>87|r2m8RFKbLKIVMfb>!B-8teDTT^OZc8B6y=gmA zgwCp(MJVx~!>06TWCOm;qHNJ3#d2#`W+!fxWT>3a8eNANH>xp_ZWmgK*1$=|usL9c zXmh}Q;9_<4=68KOsv1p9&O&jetwJx4pvm#C?*~eZ25dZN|J#$_ES(oKeqE%LbAwH+ zJld1{g4drjx207L4&`a7R%6#|^WuRxU>24vUY vKlAM2)blX%JWIDSFSf>FsLApe9O1j`2<;Gb{o|oY0lD+P(QDDQ;R65wc0%9Y diff --git a/scomps.Rcheck/scomps/Meta/package.rds b/scomps.Rcheck/scomps/Meta/package.rds deleted file mode 100644 index b905bea94dbf4e1c78c7c101742d0ff0b9771045..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 994 zcmV<810DPyiwFP!000001D#e|Z`(E$mL12JWLvuiMIXod$-(4%+6GBiq;ovLK$;Y? zQw$h}f|Y2Qh(rn`oi;yUe|y`JL@JizV3-6*yd9qNox6VDvn*@Js_j&)on4q(yVr}~ zy2r400E?z&RiDE6%&J)}80*sIVI=kH<=n*q{t^)6AfIp_i8tdJ^_7FS~5t6e`d&VSYe%nUvIZsBI0aGgB)Iak>OoJY9h6BMt;xEYU zwDDTS7hFNwhjzkEKR_4~rV^?vXEHm7S$hCa7v5p__|16K9gkkUZXX_MF!T2)!tM?B z30iW2q|t1t`Qk3-mKuQeby6n@lg~Q+=Xs zoi3gSRH{yh#f`_mG61}AuBQgx?wj7IXAHM+`K_>#7X^1PEZ1r+h#7l0f^8dxM6I|d z!CC>B)kbm&ufjswdx{8wZKQ})YK4`J){H9S(__u%3s&w*aUK8*>I)pLY;*&3ATZ!Q ze1$=3qpwu0gaMim=|#mLt}?D?Kg9vi9fBi{(D2pC(ePw2M%RnUDT@6}N1E&`4F?p* z0{R2|Y$NdUpQ!V8rBozO`h6~3>h-wr`&<0_&e-kcCZD%k;_00x>^SHs4$)I|iXK25 z4N{0;sBe~4tH!DseHjjkgvn-_G(M)GWM~#t1!mFs1Ob1a8m;$haFmc|j^5ZmC(;!( z+DMm-q*`Zt}>akFybQfadW=*eek|nKlwy`MwBAI zu4&*APG&DKAJmi3Tsp^@?F00AG#T9e$7~k&hO#Or9i?oXq$-!Z{oQ8wD#@dvdtO=XlTKOka#b$NicPw5 z*~>{UFL}9X3VT`M>3_rj%aHwCoaW*#A4l8bqTuJ8-|qd8vun;yMZNQSY}VEs=4RHK zr}K$3`?#20UFMsYX6$$*A}mAJGHdf!(>Twa7yEFbO}8#6yMZ>p;3=MJ(Z&b5pKbgx QjAAwZ1$uHj1k?)v0N9r6Y5)KL diff --git a/scomps.Rcheck/scomps/Meta/vignette.rds b/scomps.Rcheck/scomps/Meta/vignette.rds deleted file mode 100644 index a7b7d0778fa83642cc773c17104480218a865adf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 277 zcmV+w0qXuAiwFP!000001C3C@PQx$^O=-KaNl2i50UB_lDmOl0>V*qJo5U@$TGK^J zng1&=9C^M?A9#s18nDQ7Rq1!zaX|9Yh@zwR`(O2Y zuXXM|W`D~!N40mu-qyB~j(sy^uH*I<<|j<=sMmwDw?lQk4;t*(`wt$qSl|TW8Y=WF z7&$P?ghWqR3j33U&x_23fwwqbpvIckcu3Em@MEV;yVjo2#Hd~3#V%TBUvxE1vp;r} bOW1fv9-J0nA$c=YPucz(YSVVYZUO)R^UQ>w diff --git a/scomps.Rcheck/scomps/NAMESPACE b/scomps.Rcheck/scomps/NAMESPACE deleted file mode 100644 index b8f3fc6a..00000000 --- a/scomps.Rcheck/scomps/NAMESPACE +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by roxygen2: do not edit by hand - -export(aw_covariates) -export(calculate_sedc) -export(check_bbox) -export(check_crs) -export(check_crs2) -export(check_packbound) -export(check_within_reference) -export(clip_as_extent) -export(clip_as_extent_ras) -export(clip_as_extent_ras2) -export(distribute_process) -export(estimate_demands) -export(extent_to_polygon) -export(extract_with) -export(extract_with_buffer) -export(extract_with_polygons) -export(get_computational_regions) -export(grid_merge) -export(initate_log) -export(rast_short) -export(set_clip_extent) -export(sp_index_grid) -export(sp_indexing) -export(switch_packbound) -export(validate_and_repair_vectors) diff --git a/scomps.Rcheck/scomps/R/scomps b/scomps.Rcheck/scomps/R/scomps deleted file mode 100644 index 66861563..00000000 --- a/scomps.Rcheck/scomps/R/scomps +++ /dev/null @@ -1,27 +0,0 @@ -# File share/R/nspackloader.R -# Part of the R package, https://www.R-project.org -# -# Copyright (C) 1995-2012 The R Core Team -# -# This program 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 2 of the License, or -# (at your option) any later version. -# -# This program 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. -# -# A copy of the GNU General Public License is available at -# https://www.r-project.org/Licenses/ - -local({ - info <- loadingNamespaceInfo() - pkg <- info$pkgname - ns <- .getNamespace(as.name(pkg)) - if (is.null(ns)) - stop("cannot find namespace environment for ", pkg, domain = NA); - dbbase <- file.path(info$libname, pkg, "R", pkg) - lazyLoad(dbbase, ns, filter = function(n) n != ".__NAMESPACE__.") -}) diff --git a/scomps.Rcheck/scomps/R/scomps.rdb b/scomps.Rcheck/scomps/R/scomps.rdb deleted file mode 100644 index f527b32d064d5e9f91cc313397ffd5e7bd68b064..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35289 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 Ang9R* diff --git a/scomps.Rcheck/scomps/R/scomps.rdx b/scomps.Rcheck/scomps/R/scomps.rdx deleted file mode 100644 index d01a9901054e564b923e191e1b706cd798babb14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 729 zcmV;~0w(<*iwFP!0000018tN`Zxb;P$DM8hG^HdoJX#(Cao}-iB$^6nB_35(gb=Mj zZ6%OE#__rvtDD`$>!hg=96$&z+_)eiq~5r2feSY{Ax?1N1Heb%fJ6^GW*^REX`@*7 z??3igc`HY(0t`uEapB_V8AAFhu_5UXK^uhD2mc$;k0V>9|9BeuS`W7g z*>)Fs;0N$leDsiyZP% zLB0j~vd$vkeoILCJMtaaJNFeiYykJ?>F#iSjEf*9T3Y({Dkv9ZiruDktNtOOY;VR5d0b#7` zDpqW!nO+UduBAkc!m0Z$&ran%iM%3pLwZz+C831JMc0)p1Ij`wI$C%-Rfn=FRm=oa z*=R9Q4cRi(O4eI&!a(_4gl17$gjzPEliQ-nJlp6yQzzP|f$y$5zGspO2F19Jqc%JD zYP8;3f`g={;Z01{B}jE@-?y24Stw7q>5Sc(8EG&k%n?UuxX)(Lf_zKgV=ko8kvO5~ zC~4ECP>xCKfb^t}4($4lnFOiQG;H|FgjEV7zfnFj$sY^@Dm`0tXyn#7G@|s3!*U40 z^2UY>-`{4gw4==-)evdGq@r!XwXdT0{wMta=CMF>hoMa%$G- - -R: Vignettes and other documentation - - - -

diff --git a/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.R b/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.R deleted file mode 100644 index c639e81d..00000000 --- a/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.R +++ /dev/null @@ -1,4 +0,0 @@ -## ----------------------------------------------------------------------------- -knitr::opts_chunk$set(warning = FALSE, message = FALSE) - - diff --git a/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.Rmd b/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.Rmd deleted file mode 100644 index 8966a59d..00000000 --- a/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.Rmd +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "Good practice of scomps with HPC" -date: "`r Sys.Date()`" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{good_practice_hpc} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - - -```{r} -knitr::opts_chunk$set(warning = FALSE, message = FALSE) - -``` - -## Assumptions -- Users have an accessible HPC at your work -- Data are stored in distributed file systems (usually incorporated into the HPC system) - - -## Basic workflow - -### Practice for minimizing errors -- Consider using `try()` or `tryCatch()` not to a tiny error will halt all the work without any results - - Especially with the higher-level functions -- "IPDE -- Inspect, Predict, Decide, Execute" all the time - -### Raster-Vector overlay -- Make `sp_index_grid()` to get padded grid objects -- Convert sf/SpatVector objects into `terra::ext()` compatible named numeric vector - - For example: `c(xmin=0, ymin=0, xmax=10, ymax=10)` -- Make list objects with: - - An extent vector in each element - - Preprocessed vector objects with respect to each extent vector in the first list - - Preferably all lists are named -- Write a `future.apply` script running through the extent list object -- Run a small amount of data to estimate the total computational demand -- Submit a job with a proper amount of computational assets diff --git a/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.html b/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.html deleted file mode 100644 index da4506f4..00000000 --- a/scomps.Rcheck/scomps/doc/v00_good_practice_parallelization.html +++ /dev/null @@ -1,408 +0,0 @@ - - - - - - - - - - - - - - - -Good practice of scomps with HPC - - - - - - - - - - - - - - - - - - - - - - - - - - -

Good practice of scomps with HPC

-

2023-10-04

- - - -
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
-
-

Assumptions

-
    -
  • Users have an accessible HPC at your work
  • -
  • Data are stored in distributed file systems (usually incorporated -into the HPC system)
  • -
-
-
-

Basic workflow

-
-

Practice for minimizing errors

-
    -
  • Consider using try() or tryCatch() not to -a tiny error will halt all the work without any results -
      -
    • Especially with the higher-level functions
    • -
  • -
  • “IPDE – Inspect, Predict, Decide, Execute” all the time
  • -
-
-
-

Raster-Vector overlay

-
    -
  • Make sp_index_grid() to get padded grid objects
  • -
  • Convert sf/SpatVector objects into terra::ext() -compatible named numeric vector -
      -
    • For example: c(xmin=0, ymin=0, xmax=10, ymax=10)
    • -
  • -
  • Make list objects with: -
      -
    • An extent vector in each element
    • -
    • Preprocessed vector objects with respect to each extent vector in -the first list
    • -
    • Preferably all lists are named
    • -
  • -
  • Write a future.apply script running through the extent -list object
  • -
  • Run a small amount of data to estimate the total computational -demand
  • -
  • Submit a job with a proper amount of computational assets
  • -
-
-
- - - - - - - - - - - diff --git a/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.R b/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.R deleted file mode 100644 index aa3d29fc..00000000 --- a/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.R +++ /dev/null @@ -1,22 +0,0 @@ -## ----------------------------------------------------------------------------- -knitr::opts_chunk$set(warning = FALSE, message = FALSE) - - -## ----------------------------------------------------------------------------- -library(scomps) -library(sf) -library(terra) -library(stars) -library(dplyr) - - -## ----------------------------------------------------------------------------- -# your_grid = scomps::sp_index_grid() - - -## ----------------------------------------------------------------------------- -# library(mapsf) -# mf_map(your_grid$geometry) - - - diff --git a/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.Rmd b/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.Rmd deleted file mode 100644 index 4bc1aaf2..00000000 --- a/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.Rmd +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "Generate computational grids" -date: "`r Sys.Date()`" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{computational_grids} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - - -```{r} -knitr::opts_chunk$set(warning = FALSE, message = FALSE) - -``` - - -## Prepare input data -```{r} -library(scomps) -library(sf) -library(terra) -library(stars) -library(dplyr) - -``` - -## Computational grids -```{r} -# your_grid = scomps::sp_index_grid() - -``` - - -## Visualize computational grids -```{r} -# library(mapsf) -# mf_map(your_grid$geometry) - - -``` - - - -## Notes -- Computational grids are the exhaustive split of the entire study region. You should take a square buffer of each grid to clip the target raster or vector. diff --git a/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.html b/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.html deleted file mode 100644 index c2d963b8..00000000 --- a/scomps.Rcheck/scomps/doc/v01_generate_computational_grid.html +++ /dev/null @@ -1,388 +0,0 @@ - - - - - - - - - - - - - - - -Generate computational grids - - - - - - - - - - - - - - - - - - - - - - - - - - -

Generate computational grids

-

2023-10-04

- - - -
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
-
-

Prepare input data

-
library(scomps)
-library(sf)
-library(terra)
-library(stars)
-library(dplyr)
-
-
-

Computational grids

-
# your_grid = scomps::sp_index_grid()
-
-
-

Visualize computational grids

-
# library(mapsf)
-# mf_map(your_grid$geometry)
-
-
-

Notes

-
    -
  • Computational grids are the exhaustive split of the entire study -region. You should take a square buffer of each grid to clip the target -raster or vector.
  • -
-
- - - - - - - - - - - diff --git a/scomps.Rcheck/scomps/help/AnIndex b/scomps.Rcheck/scomps/help/AnIndex deleted file mode 100644 index a7b8aefb..00000000 --- a/scomps.Rcheck/scomps/help/AnIndex +++ /dev/null @@ -1,25 +0,0 @@ -aw_covariates aw_covariates -calculate_sedc calculate_sedc -check_bbox check_bbox -check_crs check_crs -check_crs2 check_crs2 -check_packbound check_packbound -check_within_reference check_within_reference -clip_as_extent clip_as_extent -clip_as_extent_ras clip_as_extent_ras -clip_as_extent_ras2 clip_as_extent_ras2 -distribute_process distribute_process -estimate_demands estimate_demands -extent_to_polygon extent_to_polygon -extract_with extract_with -extract_with_buffer extract_with_buffer -extract_with_polygons extract_with_polygons -get_computational_regions get_computational_regions -grid_merge grid_merge -initate_log initate_log -rast_short rast_short -set_clip_extent set_clip_extent -sp_indexing sp_indexing -sp_index_grid sp_index_grid -switch_packbound switch_packbound -validate_and_repair_vectors validate_and_repair_vectors diff --git a/scomps.Rcheck/scomps/help/aliases.rds b/scomps.Rcheck/scomps/help/aliases.rds deleted file mode 100644 index 35dd2b9ebc768c1c42366370307d274bee18e960..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 350 zcmV-k0ipgMiwFP!000001MQN}PQx$^#^RChCKtikHcZ&H!y zWaG?7>1+yIalnI$-(6?rzf2bGmIq0pyIv@j$|9Q*Bl})AZG=e9f?*R%`c0UXp0upd zm)Vp#S&Ch|#+5mV2aPgR&S#I7p{v`u(X(zI8c9~;k!-%Z$Vhfd*^|J{s_N{y9`;~J wcj9amciI4XxknWpKfM?aIc1PiCl+d6B(8PYvdfnJ{(~D zjvaZN?eg-7NxM~2#L+%Pu@ftw9FPCx`-M_!rPix6wc1EiZSKE)djCp#i8jQv~4`j$d5XRNnCv*Vr*xmt%D5O z?Atg7J4;kYdZgS@fP_0t7!1~|I8Os;20UhY&J1B)2$Eh@#jZZKtvEGHoD;R9Y}+A4 zgS?oUDUBg#>ZgRTC|$dtY;o%O?d1qV^uJvUvjr8bq)mP*{fdRLWS|{)vcYDptE!#e z;bOsjY0qJXsW)bwDF*E&LL9v^iwCevWTD687Af_sG(v&$RP#Q%ic^u8$iQ7px#G8k zr!|`5>EFaH{?oz(P_TG}X^AQ>&Wl6ARm?q>O=PYzQ@soW%AWd{wK5**Ov k`1~iM*5{(0o%GF)5@%_=eY&XBS2_Ot1t=ar)Tjyo0P33CssI20 diff --git a/scomps.Rcheck/scomps/help/scomps.rdb b/scomps.Rcheck/scomps/help/scomps.rdb deleted file mode 100644 index 6ddc3f1a5122e9bc3272d87f20f248371dac4ee5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35998 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 diff --git a/scomps.Rcheck/scomps/help/scomps.rdx b/scomps.Rcheck/scomps/help/scomps.rdx deleted file mode 100644 index 57f62f66e7ab44a13d877be5cf2a40ec4261c111..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 769 zcmV+c1OEIUiwFP!0000017*}bY|}s#0N`_z{sq#OmR1x*5g_r~LgW6W6$lkXk)YjL z3BhnU_BA=xv0eL;rbPlFK(HXeg2V^|6B2vHP>>iH7#Kh-Y)G&(uu-04yRR>eWX0cm zmv=vo-}MY*EXC3(jis95mNhTT&kW@mYwD>dqVImVvT!vqrk!D|r3c;S!f)o#9lyYb z(Y-k+^8vm8Aow@>kPgnGj|Sjn^oef9(wERf55a9{eFNNw&Zohj(dRdz-ZS*Y_uvim zmA5ed6MF6q?C%A7VGZ_k9DVaE?3ts*Ey#aI+ZNPcM=xIm&!Q_I!LQJ3&%uAuch~89 zAKV6?MnC=mhCQU=o@p%2+QWzD7-azm$GYkdD+*?f6>hp!!LsbTR5D3_Q7Aa~vR6@tlCERea0o?- z12RQlTD&a$Vsa?Eq$5?hT-z-sgJ7eI2PM}}&Zsj8>xQR6jxHN`TsoGh@vv-CFbPU0 zDcBXjV$ITy$914;*wP9ohl7HZdWQ6QRhY{4!#~u&ogE(?+wtrf;Uh*i(V~K-wF3OguZ_b zJdA$y8a#o{z5{Q2WA{S0(oUlH{Q;js4>Z&IM=sF)9s5bwKe!OhA9et3v*D$05l(e# zDi^CY(lBL1R;L`H9Hkti9H*S1%u`O1HPUHyx<;L@QEwPb*QnDq>SJV{5u#BdI&z$7 zf+$Zk8NC@SQ}4m`i#&}~(nagtw_tCz-^^A&#J&ox!iU}^tgz^Rl^kP7kOu$&$<%l# diff --git a/scomps.Rcheck/scomps/html/00Index.html b/scomps.Rcheck/scomps/html/00Index.html deleted file mode 100644 index 9c12d593..00000000 --- a/scomps.Rcheck/scomps/html/00Index.html +++ /dev/null @@ -1,76 +0,0 @@ - - -R: Scalable R geospatial computation - - - -
-

Scalable R geospatial computation - -

-
-
-[Up] -[Top] -

Documentation for package ‘scomps’ version 0.0.3.10042023

- - - -

Help Pages

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aw_covariatesComputing area weighted covariates using two polygon sf or SpatVector objects
calculate_sedcCalculate SEDC covariates
check_bboxCheck if the data extent is inside the reference bounding box
check_crsCheck Coordinate Reference System
check_crs2check_crs2: Coordinate system checker
check_packboundReturn the package the input object is based on
check_within_referenceCheck if the boundary of the vector/raster object is inside the reference
clip_as_extentExtent clipping
clip_as_extent_rasclip_as_extent_ras: Clip input raster.
clip_as_extent_ras2clip_as_extent_ras2: Clip input raster (version 2).
distribute_processProcess a given function in the entire or partial computational grids (under construction)
estimate_demandsEstimate computational demands from inputs (to be written)
extent_to_polygonGenerate a rectangular polygon from extent
extract_withExtract raster values with point buffers or polygons
extract_with_bufferExtract summarized values from raster with points and a buffer radius (to be written)
extract_with_polygonsExtract summarized values from raster with generic polygons
get_computational_regionsGet a set of computational regions
grid_mergegrid_merge: Merge grid polygons with given rules
initate_logTurn on logging
rast_shortQuick call for SpatRaster with a window
set_clip_extentSetting the clipping extent
sp_indexingCreate integer indices for grid
sp_index_gridsp_index_grid: Generate grid polygons
switch_packboundSwitch spatial data class
validate_and_repair_vectorsValidate and repair input vector data
-
diff --git a/scomps.Rcheck/scomps/html/R.css b/scomps.Rcheck/scomps/html/R.css deleted file mode 100644 index c2289098..00000000 --- a/scomps.Rcheck/scomps/html/R.css +++ /dev/null @@ -1,130 +0,0 @@ -@media screen { - .container { - padding-right: 10px; - padding-left: 10px; - margin-right: auto; - margin-left: auto; - max-width: 900px; - } -} - -.rimage img { /* from knitr - for examples and demos */ - width: 96%; - margin-left: 2%; -} - -.katex { font-size: 1.1em; } - -code { - color: inherit; - background: inherit; -} - -body { - line-height: 1.4; - background: white; - color: black; -} - -a:link { - background: white; - color: blue; -} - -a:visited { - background: white; - color: rgb(50%, 0%, 50%); -} - -h1 { - background: white; - color: rgb(55%, 55%, 55%); - font-family: monospace; - font-size: 1.4em; /* x-large; */ - text-align: center; -} - -h2 { - background: white; - color: rgb(40%, 40%, 40%); - font-family: monospace; - font-size: 1.2em; /* large; */ - text-align: center; -} - -h3 { - background: white; - color: rgb(40%, 40%, 40%); - font-family: monospace; - font-size: 1.2em; /* large; */ -} - -h4 { - background: white; - color: rgb(40%, 40%, 40%); - font-family: monospace; - font-style: italic; - font-size: 1.2em; /* large; */ -} - -h5 { - background: white; - color: rgb(40%, 40%, 40%); - font-family: monospace; -} - -h6 { - background: white; - color: rgb(40%, 40%, 40%); - font-family: monospace; - font-style: italic; -} - -img.toplogo { - width: 4em; - vertical-align: middle; -} - -img.arrow { - width: 30px; - height: 30px; - border: 0; -} - -span.acronym { - font-size: small; -} - -span.env { - font-family: monospace; -} - -span.file { - font-family: monospace; -} - -span.option{ - font-family: monospace; -} - -span.pkg { - font-weight: bold; -} - -span.samp{ - font-family: monospace; -} - -div.vignettes a:hover { - background: rgb(85%, 85%, 85%); -} - -tr { - vertical-align: top; -} - -span.rlang { - font-family: Courier New, Courier; - color: #666666; -} - diff --git a/scomps.Rcheck/tests/startup.Rs b/scomps.Rcheck/tests/startup.Rs deleted file mode 100644 index 8ad6d250..00000000 --- a/scomps.Rcheck/tests/startup.Rs +++ /dev/null @@ -1,4 +0,0 @@ -## A custom startup file for tests -## Run as if a system Rprofile, so no packages, no assignments -options(useFancyQuotes = FALSE) - diff --git a/scomps.Rcheck/tests/testthat.R b/scomps.Rcheck/tests/testthat.R deleted file mode 100644 index b465b524..00000000 --- a/scomps.Rcheck/tests/testthat.R +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of the standard setup for testthat. -# It is recommended that you do not modify it. -# -# Where should you do additional test configuration? -# Learn more about the roles of various files in: -# * https://r-pkgs.org/testing-design.html#sec-tests-files-overview -# * https://testthat.r-lib.org/articles/special-files.html - -library(testthat) -library(scomps) - -test_check("scomps") diff --git a/scomps.Rcheck/tests/testthat.Rout b/scomps.Rcheck/tests/testthat.Rout deleted file mode 100644 index dfb13fbb..00000000 --- a/scomps.Rcheck/tests/testthat.Rout +++ /dev/null @@ -1,37 +0,0 @@ - -R version 4.3.1 (2023-06-16) -- "Beagle Scouts" -Copyright (C) 2023 The R Foundation for Statistical Computing -Platform: aarch64-apple-darwin20 (64-bit) - -R is free software and comes with ABSOLUTELY NO WARRANTY. -You are welcome to redistribute it under certain conditions. -Type 'license()' or 'licence()' for distribution details. - -R is a collaborative project with many contributors. -Type 'contributors()' for more information and -'citation()' on how to cite R or R packages in publications. - -Type 'demo()' for some demos, 'help()' for on-line help, or -'help.start()' for an HTML browser interface to help. -Type 'q()' to quit R. - -> # This file is part of the standard setup for testthat. -> # It is recommended that you do not modify it. -> # -> # Where should you do additional test configuration? -> # Learn more about the roles of various files in: -> # * https://r-pkgs.org/testing-design.html#sec-tests-files-overview -> # * https://testthat.r-lib.org/articles/special-files.html -> -> library(testthat) -> library(scomps) -> -> test_check("scomps") -pr, tas, -pr, tas, -pr, tas, -[ FAIL 0 | WARN 0 | SKIP 0 | PASS 8 ] -> -> proc.time() - user system elapsed - 1.703 0.063 1.763 diff --git a/scomps.Rcheck/tests/testthat/tests.R b/scomps.Rcheck/tests/testthat/tests.R deleted file mode 100644 index 6efa4142..00000000 --- a/scomps.Rcheck/tests/testthat/tests.R +++ /dev/null @@ -1,65 +0,0 @@ -# Generated from scomps_rmarkdown_litr.rmd: do not edit by hand -testthat::test_that("What package does the input object belong?", -{ - withr::local_package("stars") - withr::local_package("terra") - withr::local_options(list(sf_use_s2 = FALSE)) - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) - - packbound_stars = check_packbound(bcsd_stars) - sprast_bcsd = terra::rast(bcsd_path) - packbound_terra = check_packbound(sprast_bcsd) - - testthat::expect_equal(packbound_stars, "sf") - testthat::expect_equal(packbound_terra, "terra") -}) - - -testthat::test_that("What package does the input object belong?", -{ - withr::local_package("stars") - withr::local_package("terra") - withr::local_options(list(sf_use_s2 = FALSE)) - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) - - nc = system.file(package = "sf", "shape/nc.shp") - nc = sf::read_sf(nc) - - datatype_stars = check_datatype(bcsd_stars) - datatype_sf = check_datatype(nc) - - testthat::expect_equal(datatype_stars, "raster") - testthat::expect_equal(datatype_sf, "vector") -}) - - -testthat::test_that("Format is well converted", -{ - withr::local_package("stars") - withr::local_package("terra") - withr::local_options(list(sf_use_s2 = FALSE)) - - # starts from sf/stars - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) - nc = system.file(package = "sf", "shape/nc.shp") - nc = sf::read_sf(nc) - - stars_bcsd_tr = switch_packbound(bcsd_stars) - sf_nc_tr = switch_packbound(nc) - - testthat::expect_equal(check_packbound(stars_bcsd_tr), "terra") - testthat::expect_equal(check_packbound(sf_nc_tr), "terra") - - stars_bcsd_trb = switch_packbound(stars_bcsd_tr) - sf_nc_trb = switch_packbound(sf_nc_tr) - - testthat::expect_equal(check_packbound(stars_bcsd_trb), "sf") - testthat::expect_equal(check_packbound(sf_nc_trb), "sf") - -}) - - - diff --git a/scomps/DESCRIPTION b/scomps/DESCRIPTION index acb3b95d..8858880b 100644 --- a/scomps/DESCRIPTION +++ b/scomps/DESCRIPTION @@ -32,4 +32,4 @@ Suggests: VignetteBuilder: knitr Config/testthat/edition: 3 LitrVersionUsed: 0.9.0 -LitrId: 27d90205fd42be403e707a6a559e8eae +LitrId: b724f15aefeda747a5a888516d5c7129 diff --git a/scomps/R/check.R b/scomps/R/check.R index 2e1bbcf2..3b30feda 100644 --- a/scomps/R/check.R +++ b/scomps/R/check.R @@ -32,8 +32,11 @@ check_datatype <- function(input) { #' @return A (reprojected) sf or SpatVector object. #' @export check_crs2 <- function(input, crs_standard = "EPSG:4326") { - check_crs.sf <- function(input){ - if (is.na(sf::st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} + check_crs_sf <- function(input) { + if (is.na(sf::st_crs(input))) { + cat('Please check the coordinate system or its EPSG code of your input object.') + return(NULL) + } if (sf::st_crs(input)$epsg == crs_standard ) { return(input) } @@ -41,17 +44,17 @@ check_crs2 <- function(input, crs_standard = "EPSG:4326") { return(input_transformed) } - check_crs.terra <- function(input) { + check_crs_terra <- function(input) { if (terra::crs(input, describe = TRUE)$code == crs_standard) { return(input) } - input_transformed = terra::project(input, terra::crs(crs_standard)) + input_transformed <- terra::project(input, terra::crs(crs_standard)) return(input_transformed) } - detected = check_packbound(input) + detected <- check_packbound(input) switch(detected, - terra = check_crs.terra(input), - sf = check_crs.sf(input)) + terra = check_crs_terra(input), + sf = check_crs_sf(input)) } #' Generate a rectangular polygon from extent @@ -69,20 +72,20 @@ extent_to_polygon <- function(extent, output_class = "terra", crs = "EPSG:4326") if (is.null(attr(extent, "names"))) { stop("Your extent is an unnamed numeric vector. Please define names xmin/xmax/ymin/ymax explicitly.\n") } - extent = switch( + extent <- switch( output_class, sf = sf::st_bbox(extent), terra = terra::ext(extent) ) } - extent_polygon = switch( + extent_polygon <- switch( output_class, sf = sf::st_as_sfc(extent), terra = terra::vect(extent) ) - extent_polygon = switch( + extent_polygon <- switch( output_class, sf = sf::st_set_crs(extent_polygon, sf::st_crs(crs)), terra = terra::set.crs(extent_polygon, terra::crs(crs)) @@ -110,18 +113,18 @@ check_bbox <- function( stop("CRS should be entered when the reference extent is a vector.\n") } if (is.numeric(reference) && !is.null(reference_crs)) { - reference = sf::st_as_sfc(sf::st_bbox(reference), crs = reference_crs) + reference <- sf::st_as_sfc(sf::st_bbox(reference), crs = reference_crs) } - query_crs = check_crs(data_query) - ref_crs = check_crs(reference) + query_crs <- check_crs(data_query) + ref_crs <- check_crs(reference) if (is.na(query_crs) || is.null(query_crs)) { stop("The dataset you queried has no CRS. Please make sure your dataset has the correct CRS.\n") } - query_matched = sf::st_transform(data_query, sf::st_crs(ref_crs)) + query_matched <- sf::st_transform(data_query, sf::st_crs(ref_crs)) - check_result = sf::st_within() + check_result <- sf::st_within() return(check_result) } @@ -144,12 +147,14 @@ check_crs <- function(x) { stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) if (methods::is(x, "sf") || methods::is(x, "stars")) { - crs_wkt = sf::st_crs(x) + crs_wkt <- sf::st_crs(x) } else { - crs_wkt = terra::crs(x) + crs_wkt <- terra::crs(x) } - stopifnot("No CRS is defined in the input. Please consult the metadata or the data source.\n" = !is.na(crs_wkt) || crs_wkt != "") + stopifnot( + "No CRS is defined in the input. Please consult the metadata or the data source.\n" = + !is.na(crs_wkt) || crs_wkt != "") return(crs_wkt) } @@ -160,20 +165,20 @@ check_crs <- function(x) { #' @author Insang Song \email{geoissong@@gmail.com} #' @export check_within_reference <- function(input_object, reference) { - stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) - stopifnot("Reference is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) + stopifnot("Input is invalid.\n" = (methods::is(input_object, "sf") || methods::is(input_object, "stars") || methods::is(input_object, "SpatVector") || methods::is(input_object, "SpatRaster"))) + stopifnot("Reference is invalid.\n" = (methods::is(input_object, "sf") || methods::is(input_object, "stars") || methods::is(input_object, "SpatVector") || methods::is(input_object, "SpatRaster"))) bbox_input <- input_object sf::st_bbox() |> sf::st_as_sfc() - bbox_reference = reference |> + bbox_reference <- reference |> sf::st_bbox() |> sf::st_as_sfc() - iswithin = sf::st_covered_by(bbox_input, bbox_reference) - iswithin = length(iswithin[[1]]) - iswithin = (iswithin == 1) + iswithin <- sf::st_covered_by(bbox_input, bbox_reference) + iswithin <- length(iswithin[[1]]) + iswithin <- (iswithin == 1) invisible(iswithin) } diff --git a/scomps/R/estimate_demands.R b/scomps/R/estimate_demands.R index 0c0bf6d7..02dcb346 100644 --- a/scomps/R/estimate_demands.R +++ b/scomps/R/estimate_demands.R @@ -2,7 +2,7 @@ #' Estimate computational demands from inputs (to be written) #' -#' @param inputs a list of sf/Spat* objects or file paths +#' @param inputs character vector of file paths #' @param nx integer(1). #' @param ny integer(1). #' @param padding numeric(1). Extrusion factor diff --git a/scomps/R/indexing.R b/scomps/R/indexing.R index 7555a3f9..bfd3cf8b 100644 --- a/scomps/R/indexing.R +++ b/scomps/R/indexing.R @@ -7,7 +7,7 @@ #' @param ncutsx integer(1). The number of splits along x-axis. #' @param ncutsy integer(1). The number of splits along y-axis. #' @export -sp_indexing <- function(points_in, ncutsx, ncutsy){ +sp_indexing <- function(points_in, ncutsx, ncutsy) { # pts <- data.table(pnts) points_in <- points_in |> dplyr::mutate(or_id = seq(1, dim(points_in)[1])) diff --git a/scomps/R/interpret_computational_domain.R b/scomps/R/interpret_computational_domain.R index 90132a7f..f1a565fb 100644 --- a/scomps/R/interpret_computational_domain.R +++ b/scomps/R/interpret_computational_domain.R @@ -16,16 +16,24 @@ #' @examples #' # data #' library(sf) -#' ncpath = system.file("shape/nc.shp", package = "sf") -#' nc = read_sf(ncpath) -#' nc = st_transform(nc, "EPSG:5070") +#' ncpath <- system.file("shape/nc.shp", package = "sf") +#' nc <- read_sf(ncpath) +#' nc <- st_transform(nc, "EPSG:5070") #' # run -#' # nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) +#' # nc_comp_region <- get_computational_regions(nc, nx = 12, ny = 8) #' #' @export -get_computational_regions <- function(input, mode = "grid", nx = 10, ny = 10, grid_min_features = 30, padding = NULL, unit = NULL, ...) { +get_computational_regions <- function( + input, + mode = "grid", + nx = 10, + ny = 10, + grid_min_features = 30, + padding = NULL, + unit = NULL, + ...) { # type check - package_detected = check_packbound(input) + package_detected <- check_packbound(input) # stopifnot("Invalid input.\n" = !any(grepl("^(sf|Spat)", class(input)))) stopifnot("Argument mode should be one of 'grid', 'grid_advanced', or 'density'.\n" = !mode %in% c("grid", "grid_advanced", "density")) stopifnot("Ensure that nx, ny, and grid_min_features are all integer.\n" = all(is.integer(nx), is.integer(y), is.integer(grid_min_features))) @@ -48,25 +56,25 @@ get_computational_regions <- function(input, mode = "grid", nx = 10, ny = 10, gr #' @return A sf or SpatVector object of computation grids with unique grid id (CGRIDID). #' @export sp_index_grid <- function(points_in, ncutsx, ncutsy){ - package_detected = check_packbound(points_in) + package_detected <- check_packbound(points_in) - sp_index_grid.sf = function(points_in, ncutsx, ncutsy) { + sp_index_grid_sf <- function(points_in, ncutsx, ncutsy) { grid1 <- sf::st_make_grid(points_in, n = c(ncutsx, ncutsy)) |> as.data.frame() |> sf::st_as_sf() grid1 <- grid1[points_in, ] return(grid1) } - sp_index_grid.terra = function(points_in, ncutsx, ncutsy) { + sp_index_grid_terra <- function(points_in, ncutsx, ncutsy) { grid1 <- terra::rast(points_in, nrows = ncutsy, ncols = ncutsx) grid1 <- terra::as.polygons(grid1) return(grid1) } - grid_out = switch(package_detected, - sf = sp_index_grid.sf(points_in, ncutsx, ncutsy), - terra = sp_index_grid.terra(points_in, ncutsx, ncutsy)) + grid_out <- switch(package_detected, + sf = sp_index_grid_sf(points_in, ncutsx, ncutsy), + terra = sp_index_grid_terra(points_in, ncutsx, ncutsy)) - grid_out$CGRIDID = seq(1, nrow(x = grid_out)) + grid_out$CGRIDID <- seq(1, nrow(x = grid_out)) return(grid_out) } @@ -93,28 +101,28 @@ sp_index_grid <- function(points_in, ncutsx, ncutsy){ #' # dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) #' #### NOT RUN #### #' @export -grid_merge <- function(points_in, grid_in, grid_min_features){ - package_detected = check_packbound(points_in) +grid_merge <- function(points_in, grid_in, grid_min_features) { + package_detected <- check_packbound(points_in) if (package_detected == "terra") { - points_in = sf::st_as_sf(points_in) - grid_in = sf::st_as_sf(grid_in) + points_in <- sf::st_as_sf(points_in) + grid_in <- sf::st_as_sf(grid_in) } - n_points_in_grid = lengths(sf::st_intersects(grid_in, points_in)) - grid_self = sf::st_relate(grid_in, grid_in, pattern = "2********") - grid_rook = sf::st_relate(grid_in, grid_in, pattern = "F***1****") - grid_rooks = mapply(c, grid_self, grid_rook, SIMPLIFY = FALSE) - grid_lt_threshold = (n_points_in_grid < grid_min_features) + n_points_in_grid <- lengths(sf::st_intersects(grid_in, points_in)) + grid_self <- sf::st_relate(grid_in, grid_in, pattern = "2********") + grid_rook <- sf::st_relate(grid_in, grid_in, pattern = "F***1****") + grid_rooks <- mapply(c, grid_self, grid_rook, SIMPLIFY = FALSE) + grid_lt_threshold <- (n_points_in_grid < grid_min_features) stopifnot("Threshold is too low. Please try higher threshold.\n" = sum(grid_lt_threshold) != 0) - grid_lt_threshold = seq(1, nrow(grid_in))[grid_lt_threshold] + grid_lt_threshold <- seq(1, nrow(grid_in))[grid_lt_threshold] # This part does not work as expected. Should investigate edge list and actual row index of the grid object; - identified = lapply(grid_rooks, \(x) sort(x[which(x %in% grid_lt_threshold)])) - identified = identified[grid_lt_threshold] - identified = unique(identified) - identified = identified[sapply(identified, length) > 1] + identified <- lapply(grid_rooks, \(x) sort(x[which(x %in% grid_lt_threshold)])) + identified <- identified[grid_lt_threshold] + identified <- unique(identified) + identified <- identified[sapply(identified, length) > 1] - identified_graph = lapply(identified, \(x) t(utils::combn(x, 2))) |> + identified_graph <- lapply(identified, \(x) t(utils::combn(x, 2))) |> Reduce(f = rbind, x = _) |> unique() |> apply(X = _, 2, as.character) |> @@ -123,30 +131,30 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ igraph::components() # return(identified_graph) - identified_graph_member = identified_graph$membership + identified_graph_member <- identified_graph$membership - merge_idx = as.integer(names(identified_graph_member)) - merge_member = split(merge_idx, identified_graph_member) - merge_member_label = unlist(lapply(merge_member, \(x) paste(x, collapse = "_"))) - merge_member_label = merge_member_label[identified_graph_member] + merge_idx <- as.integer(names(identified_graph_member)) + merge_member <- split(merge_idx, identified_graph_member) + merge_member_label <- unlist(lapply(merge_member, \(x) paste(x, collapse = "_"))) + merge_member_label <- merge_member_label[identified_graph_member] # sf object manipulation - grid_out = grid_in - grid_out[["CGRIDID"]][merge_idx] = merge_member_label + grid_out <- grid_in + grid_out[["CGRIDID"]][merge_idx] <- merge_member_label # for (k in seq_along(merge_member_label)) { # target_idx = merge_member_label[[k]] # grid_out[["CGRIDID"]][target_idx] = paste("M_", paste(target_idx, collapse = "_"), sep = "") # } - grid_out = grid_out |> + grid_out <- grid_out |> dplyr::group_by(!!rlang::sym("CGRIDID")) |> dplyr::summarize(n_merged = dplyr::n()) |> dplyr::ungroup() ## polsby-popper test for shape compactness - grid_merged = grid_out[which(grid_out$n_merged > 1),] - grid_merged_area = as.numeric(sf::st_area(grid_merged)) - grid_merged_perimeter = as.numeric(sf::st_length(sf::st_cast(grid_merged, "LINESTRING"))) - grid_merged_pptest = (4 * pi * grid_merged_area) / (grid_merged_perimeter ^ 2) + grid_merged <- grid_out[which(grid_out$n_merged > 1),] + grid_merged_area <- as.numeric(sf::st_area(grid_merged)) + grid_merged_perimeter <- as.numeric(sf::st_length(sf::st_cast(grid_merged, "LINESTRING"))) + grid_merged_pptest <- (4 * pi * grid_merged_area) / (grid_merged_perimeter ^ 2) # pptest value is bounded [0,1]; 0.3 threshold is groundless at this moment, possibly will make it defined by users. if (max(unique(identified_graph_member)) > floor(0.1 * nrow(grid_in)) || any(grid_merged_pptest < 0.3)) { @@ -188,23 +196,23 @@ distribute_process <- function(grids, grid_id = NULL, fun, ...) { # subset using grids and grid_id if (!is.null(grid_id)) { if (is.character(grid_id)) { - grid_id_parsed = strsplit(grid_id, ":", fixed = TRUE)[[1]] - grid_ids = c(which(unique(grids[["CGRIDID"]]) == grid_id_parsed[1]), + grid_id_parsed <- strsplit(grid_id, ":", fixed = TRUE)[[1]] + grid_ids <- c(which(unique(grids[["CGRIDID"]]) == grid_id_parsed[1]), which(unique(grids[["CGRIDID"]]) == grid_id_parsed[2])) } if (is.numeric(grid_id)) { - grid_ids = unique(grids[["CGRIDID"]])[grid_id] + grid_ids <- unique(grids[["CGRIDID"]])[grid_id] } } - grids_target = grids[grid_ids,] - grids_target_list = split(grids_target, grids_target[["CGRIDID"]]) + grids_target <- grids[grid_ids,] + grids_target_list <- split(grids_target, grids_target[["CGRIDID"]]) - results_distributed = future.apply::future_lapply( + results_distributed <- future.apply::future_lapply( \(x, ...) { fun(...) }, grids_target_list, future.seed = TRUE) - results_distributed = do.call(rbind, results_distributed) + results_distributed <- do.call(rbind, results_distributed) return(results_distributed) } diff --git a/scomps/R/preprocessing.R b/scomps/R/preprocessing.R index 93b3ad93..093186bc 100644 --- a/scomps/R/preprocessing.R +++ b/scomps/R/preprocessing.R @@ -8,11 +8,11 @@ #' @return A terra::ext or sfc_POLYGON object of the computation extent. #' @export set_clip_extent <- function(pnts, buffer_r) { - detected = check_packbound(pnts) + detected <- check_packbound(pnts) if (detected == "terra") { - ext_input = terra::ext(pnts) + ext_input <- terra::ext(pnts) # Note that `+` operation on terra::ext output accounts for the operand as it is. - ext_input = ext_input + (1.1 * buffer_r + 30) + ext_input <- ext_input + (1.1 * buffer_r + 30) } if (detected == "sf") { ext_input <- pnts |> sf::st_bbox() diff --git a/scomps/R/processing.R b/scomps/R/processing.R index 00b3e1d3..d53b8f59 100644 --- a/scomps/R/processing.R +++ b/scomps/R/processing.R @@ -9,28 +9,28 @@ #' @param target_input sf or SpatVector object to be clipped #' @return A clipped sf or SpatVector object. #' @export -clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input){ +clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input) { if (any(sapply(list(pnts, buffer_r, target_input), is.null))) { stop("One or more required arguments are NULL. Please check.\n") } - detected_pnts = check_packbound(pnts) - detected_target = check_packbound(target_input) + detected_pnts <- check_packbound(pnts) + detected_target <- check_packbound(target_input) if (detected_pnts != detected_target) { warning("Inputs are not the same class.\n") - target_input = switch(detected_target, + target_input <- switch(detected_target, sf = terra::vect(target_input), terra = sf::st_as_sf(target_input)) } - ext_input = set_clip_extent(pnts, buffer_r) + ext_input <- set_clip_extent(pnts, buffer_r) cat("Clip target features with the input feature extent...\n") if (detected_pnts == "sf") { - cae = ext_input |> + cae <- ext_input |> sf::st_intersection(x = target_input) } if (detected_pnts == "terra") { - cae = terra::intersect(target_input, ext_input) + cae <- terra::intersect(target_input, ext_input) } return(cae) @@ -44,11 +44,11 @@ clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input){ #' @param nqsegs integer(1). the number of points per a quarter circle #' @param ras SpatRaster object to be clipped #' @export -clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras){ +clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras) { if (any(sapply(list(pnts, buffer_r, ras), is.null))) { stop("Any of required arguments are NULL. Please check.\n") } - ext_input = set_clip_extent(pnts, buffer_r) |> + ext_input <- set_clip_extent(pnts, buffer_r) |> terra::ext() cae <- terra::crop(ras, ext_input, snap = 'out') @@ -63,11 +63,11 @@ clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras){ #' @param nqsegs integer(1). the number of points per a quarter circle #' @param ras SpatRaster object to be clipped #' @export -clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras){ +clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras) { if (any(sapply(list(points_in, buffer_r, ras), is.null))) { stop("Any of required arguments are NULL. Please check.\n") } - ext_input = set_clip_extent(points_in, buffer_r) |> + ext_input <- set_clip_extent(points_in, buffer_r) |> terra::ext() cae <- terra::crop(ras, ext_input, snap = 'out') @@ -94,15 +94,15 @@ extract_with_polygons <- function( stopifnot("Check class of the input raster.\n" = any(methods::is(surf, "stars"), methods::is(surf, "SpatRaster"))) stopifnot(is.character(id)) - cls_polys = check_packbound(polys) - cls_surf = check_packbound(surf) + cls_polys <- check_packbound(polys) + cls_surf <- check_packbound(surf) if (cls_polys != cls_surf) { - polys = switch_packbound(polys) + polys <- switch_packbound(polys) } - extract_with_polygons.sf = function(polys, surf, id, func) { - extracted = stars::st_extract(x = surf, at = polys, FUN = func) + extract_with_polygons_sf <- function(polys, surf, id, func) { + extracted <- stars::st_extract(x = surf, at = polys, FUN = func) # extracted = extracted |> # group_by(!!sym(id)) |> # summarize(across(-!!sym(id), ~func)) |> @@ -110,19 +110,19 @@ extract_with_polygons <- function( return(extracted) } - extract_with_polygons.terra = function(polys, surf, id, func) { - extracted = terra::extract(surf, polys) - extracted = extracted |> + extract_with_polygons_terra <- function(polys, surf, id, func) { + extracted <- terra::extract(surf, polys) + extracted <- extracted |> dplyr::group_by(!!rlang::sym(id)) |> dplyr::summarize(dplyr::across(-!!rlang::sym(id), ~func)) |> dplyr::ungroup() return(extracted) } - extracted_poly = switch( + extracted_poly <- switch( cls_surf, - sf = extract_with_polygons.sf(polys = polys, surf = surf, id = id, func = func), - terra = extract_with_polygons.terra(polys = polys, surf = surf, id = id, func = func) + sf = extract_with_polygons_sf(polys = polys, surf = surf, id = id, func = func), + terra = extract_with_polygons_terra(polys = polys, surf = surf, id = id, func = func) ) return(extracted_poly) } @@ -146,7 +146,7 @@ extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) stopifnot(is.character(id)) stopifnot(id %in% names(vector)) - extracted = + extracted <- switch(mode, polygon = extract_with_polygons(vector, raster, id, func), buffer = extract_with_buffer(vector, raster, id = id, func = func, ...)) @@ -166,26 +166,26 @@ extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) #' @export calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, target_fields) { # define sources, set SEDC exponential decay range - len_point_from = seq_len(nrow(point_from)) - len_point_to = seq_len(nrow(point_to)) + len_point_from <- seq_len(nrow(point_from)) + len_point_to <- seq_len(nrow(point_to)) - point_from$from_id = len_point_from + point_from$from_id <- len_point_from # select egrid_v only if closer than 3e5 meters from each aqs - point_from_buf = terra::buffer(point_from_buf, threshold = threshold, quadsegs = 90) - point_to = point_to[point_from_buf,] - point_to$to_id = len_point_to + point_from_buf <- terra::buffer(point_from_buf, threshold = threshold, quadsegs = 90) + point_to <- point_to[point_from_buf,] + point_to$to_id <- len_point_to # near features with distance argument: only returns integer indices - near_from_to = terra::nearby(point_from, point_to, distance = threshold) + near_from_to <- terra::nearby(point_from, point_to, distance = threshold) # attaching actual distance - dist_near_to = terra::distance(point_from, point_to) - dist_near_to_df = as.vector(dist_near_to) + dist_near_to <- terra::distance(point_from, point_to) + dist_near_to_df <- as.vector(dist_near_to) # adding integer indices - dist_near_to_tdf = expand.grid(from_id = len_point_from, to_id = len_point_to) - dist_near_to_df = cbind(dist_near_to_tdf, dist = dist_near_to_df) + dist_near_to_tdf <- expand.grid(from_id = len_point_from, to_id = len_point_to) + dist_near_to_df <- cbind(dist_near_to_tdf, dist = dist_near_to_df) # summary - near_from_to = near_from_to |> + near_from_to <- near_from_to |> dplyr::as_tibble() |> dplyr::left_join(data.frame(point_from)) |> dplyr::left_join(data.frame(point_to)) |> @@ -214,15 +214,15 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' library(sf) #' #' # run -#' nc = sf::st_read(system.file("shape/nc.shp", package="sf")) -#' nc = sf::st_transform(nc, 5070) -#' pp = sf::st_sample(nc, size = 300) -#' pp = sf::st_as_sf(pp) -#' pp[["id"]] = seq(1, nrow(pp)) -#' sf::st_crs(pp) = "EPSG:5070" -#' ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +#' nc <- sf::st_read(system.file("shape/nc.shp", package="sf")) +#' nc <- sf::st_transform(nc, 5070) +#' pp <- sf::st_sample(nc, size = 300) +#' pp <- sf::st_as_sf(pp) +#' pp[["id"]] <- seq(1, nrow(pp)) +#' sf::st_crs(pp) <- "EPSG:5070" +#' ppb <- sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' -#' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) +#' system.time({ppb_nc_aw <- aw_covariates(ppb, nc, 'id')}) #' summary(ppb_nc_aw) #' #### Example of aw_covariates ends #### #' @export @@ -232,13 +232,13 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { #check_crs() ## distinguish numeric and nonnumeric columns - index_numeric = grep("(integer|numeric)", unlist(sapply(poly_weight, class))) + index_numeric <- grep("(integer|numeric)", unlist(sapply(poly_weight, class))) aw_covariates.terra = function(poly_in, poly_weight, id_poly_in = id_poly_in) { - poly_intersected = terra::intersect(poly_in, poly_weight) - poly_intersected[["area_segment_"]] = terra::expanse(poly_intersected) - poly_intersected = data.frame(poly_intersected) |> + poly_intersected <- terra::intersect(poly_in, poly_weight) + poly_intersected[["area_segment_"]] <- terra::expanse(poly_intersected) + poly_intersected <- data.frame(poly_intersected) |> dplyr::group_by(!!rlang::sym(id_poly_in)) |> dplyr::summarize(dplyr::across(is.numeric, ~stats::weighted.mean(., w = area_segment_))) |> @@ -246,11 +246,11 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { return(poly_intersected) } - class_poly_in = check_packbound(poly_in) - class_poly_weight = check_packbound(poly_weight) + class_poly_in <- check_packbound(poly_in) + class_poly_weight <- check_packbound(poly_weight) if (class_poly_in != class_poly_weight) { - class_poly_weight = switch_packbound(class_poly_weight) + class_poly_weight <- switch_packbound(class_poly_weight) } switch(class_poly_in, @@ -296,7 +296,7 @@ extract_with_buffer <- function( stopifnot(is.integer(qsegs)) if (!is.null(kernel)) { - extracted = extract_with_buffer.flat(points = points, + extracted <- extract_with_buffer.flat(points = points, surf = surf, radius = radius, id = id, @@ -305,7 +305,7 @@ extract_with_buffer <- function( return(extracted) } - extracted = extract_with_buffer.kernel(points = points, + extracted <- extract_with_buffer.kernel(points = points, surf = surf, radius = radius, id = id, @@ -322,17 +322,17 @@ extract_with_buffer.flat <- function( points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL ) { # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + bufs <- terra::buffer(points, width = radius, quadsegs = qsegs) # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) + bufs_extent <- terra::ext(bufs) + surf_cropped <- terra::crop(surf, bufs_extent) + name_surf_val <- names(surf) # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = + surf_at_bufs <- terra::extract(surf_cropped, bufs) + surf_at_bufs_summary <- surf_at_bufs |> dplyr::group_by(ID) |> - dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm = TRUE)) |> dplyr::ungroup() return(surf_at_bufs_summary) } @@ -343,18 +343,18 @@ extract_with_buffer.kernel <- function( points, surf, radius, id, qsegs, func = mean, kernel, bandwidth ) { # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + bufs <- terra::buffer(points, width = radius, quadsegs = qsegs) # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) + bufs_extent <- terra::ext(bufs) + surf_cropped <- terra::crop(surf, bufs_extent) + name_surf_val <- names(surf) # TODO: kernel implementation # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = + surf_at_bufs <- terra::extract(surf_cropped, bufs) + surf_at_bufs_summary <- surf_at_bufs |> dplyr::group_by(ID) |> dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> diff --git a/scomps/R/switch_format.R b/scomps/R/switch_format.R index a0c38e8f..868c3da5 100644 --- a/scomps/R/switch_format.R +++ b/scomps/R/switch_format.R @@ -8,10 +8,10 @@ #' @export switch_packbound <- function(input) { stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) - cls_input = check_packbound(input) - type_input = check_datatype(input) + cls_input <- check_packbound(input) + type_input <- check_datatype(input) - switched = + switched <- switch(cls_input, sf = switch(type_input, vector = terra::vect(input), diff --git a/scomps/R/validate.R b/scomps/R/validate.R index 545869c2..43ea82b2 100644 --- a/scomps/R/validate.R +++ b/scomps/R/validate.R @@ -7,9 +7,9 @@ #' @return A repaired sf or SpatVector object depending on the class of input_vector. #' @export validate_and_repair_vectors <- function(input_vector) { - detected = check_packbound(input_vector) + detected <- check_packbound(input_vector) - validated = switch(detected, + validated <- switch(detected, terra = terra::makeValid(input_vector), sf = sf::st_make_valid(input_vector)) diff --git a/scomps/man/aw_covariates.Rd b/scomps/man/aw_covariates.Rd index ca836de6..9743d66a 100644 --- a/scomps/man/aw_covariates.Rd +++ b/scomps/man/aw_covariates.Rd @@ -24,15 +24,15 @@ When poly_in and poly_weight are different classes, poly_weight will be converte library(sf) # run -nc = sf::st_read(system.file("shape/nc.shp", package="sf")) -nc = sf::st_transform(nc, 5070) -pp = sf::st_sample(nc, size = 300) -pp = sf::st_as_sf(pp) -pp[["id"]] = seq(1, nrow(pp)) -sf::st_crs(pp) = "EPSG:5070" -ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +nc <- sf::st_read(system.file("shape/nc.shp", package="sf")) +nc <- sf::st_transform(nc, 5070) +pp <- sf::st_sample(nc, size = 300) +pp <- sf::st_as_sf(pp) +pp[["id"]] <- seq(1, nrow(pp)) +sf::st_crs(pp) <- "EPSG:5070" +ppb <- sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) -system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) +system.time({ppb_nc_aw <- aw_covariates(ppb, nc, 'id')}) summary(ppb_nc_aw) #### Example of aw_covariates ends #### } diff --git a/scomps/man/estimate_demands.Rd b/scomps/man/estimate_demands.Rd index 787ad77f..a22698fc 100644 --- a/scomps/man/estimate_demands.Rd +++ b/scomps/man/estimate_demands.Rd @@ -7,7 +7,7 @@ estimate_demands(inputs, nx, ny, padding) } \arguments{ -\item{inputs}{a list of sf/Spat* objects or file paths} +\item{inputs}{character vector of file paths} \item{nx}{integer(1).} diff --git a/scomps/man/get_computational_regions.Rd b/scomps/man/get_computational_regions.Rd index 6a864a55..5cd1bb49 100644 --- a/scomps/man/get_computational_regions.Rd +++ b/scomps/man/get_computational_regions.Rd @@ -41,11 +41,11 @@ TODO. Using input points, the bounding box is split to the predefined numbers of \examples{ # data library(sf) -ncpath = system.file("shape/nc.shp", package = "sf") -nc = read_sf(ncpath) -nc = st_transform(nc, "EPSG:5070") +ncpath <- system.file("shape/nc.shp", package = "sf") +nc <- read_sf(ncpath) +nc <- st_transform(nc, "EPSG:5070") # run -# nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) +# nc_comp_region <- get_computational_regions(nc, nx = 12, ny = 8) } \author{ diff --git a/scomps/tests/testthat/tests.R b/scomps/tests/testthat/tests.R index 6efa4142..a0674e10 100644 --- a/scomps/tests/testthat/tests.R +++ b/scomps/tests/testthat/tests.R @@ -4,12 +4,12 @@ testthat::test_that("What package does the input object belong?", withr::local_package("stars") withr::local_package("terra") withr::local_options(list(sf_use_s2 = FALSE)) - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) + bcsd_path <- system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars <- stars::read_stars(bcsd_path) - packbound_stars = check_packbound(bcsd_stars) - sprast_bcsd = terra::rast(bcsd_path) - packbound_terra = check_packbound(sprast_bcsd) + packbound_stars <- check_packbound(bcsd_stars) + sprast_bcsd <- terra::rast(bcsd_path) + packbound_terra <- check_packbound(sprast_bcsd) testthat::expect_equal(packbound_stars, "sf") testthat::expect_equal(packbound_terra, "terra") @@ -21,14 +21,14 @@ testthat::test_that("What package does the input object belong?", withr::local_package("stars") withr::local_package("terra") withr::local_options(list(sf_use_s2 = FALSE)) - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) + bcsd_path <- system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars <- stars::read_stars(bcsd_path) - nc = system.file(package = "sf", "shape/nc.shp") - nc = sf::read_sf(nc) + nc <- system.file(package = "sf", "shape/nc.shp") + nc <- sf::read_sf(nc) - datatype_stars = check_datatype(bcsd_stars) - datatype_sf = check_datatype(nc) + datatype_stars <- check_datatype(bcsd_stars) + datatype_sf <- check_datatype(nc) testthat::expect_equal(datatype_stars, "raster") testthat::expect_equal(datatype_sf, "vector") @@ -42,19 +42,19 @@ testthat::test_that("Format is well converted", withr::local_options(list(sf_use_s2 = FALSE)) # starts from sf/stars - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) - nc = system.file(package = "sf", "shape/nc.shp") - nc = sf::read_sf(nc) + bcsd_path <- system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars <- stars::read_stars(bcsd_path) + nc <- system.file(package = "sf", "shape/nc.shp") + nc <- sf::read_sf(nc) - stars_bcsd_tr = switch_packbound(bcsd_stars) - sf_nc_tr = switch_packbound(nc) + stars_bcsd_tr <- switch_packbound(bcsd_stars) + sf_nc_tr <- switch_packbound(nc) testthat::expect_equal(check_packbound(stars_bcsd_tr), "terra") testthat::expect_equal(check_packbound(sf_nc_tr), "terra") - stars_bcsd_trb = switch_packbound(stars_bcsd_tr) - sf_nc_trb = switch_packbound(sf_nc_tr) + stars_bcsd_trb <- switch_packbound(stars_bcsd_tr) + sf_nc_trb <- switch_packbound(sf_nc_tr) testthat::expect_equal(check_packbound(stars_bcsd_trb), "sf") testthat::expect_equal(check_packbound(sf_nc_trb), "sf") diff --git a/scomps_coverage_report.html b/scomps_coverage_report.html index 60117c09..95ef497a 100644 --- a/scomps_coverage_report.html +++ b/scomps_coverage_report.html @@ -545,14 +545,14 @@

scomps coverage - 6.75%

62 ! -
        sf = sp_index_grid.sf(points_in, ncutsx, ncutsy),
+
        sf = sp_index_grid.sf(points_in, ncutsx, ncutsy),
63 ! -
        terra = sp_index_grid.terra(points_in, ncutsx, ncutsy))
+
        terra = sp_index_grid.terra(points_in, ncutsx, ncutsy))
@@ -2427,14 +2427,14 @@

scomps coverage - 6.75%

124 ! -
        sf = extract_with_polygons.sf(polys = polys, surf = surf, id = id, func = func),
+
        sf = extract_with_polygons.sf(polys = polys, surf = surf, id = id, func = func),
125 ! -
        terra = extract_with_polygons.terra(polys = polys, surf = surf, id = id, func = func)
+
        terra = extract_with_polygons.terra(polys = polys, surf = surf, id = id, func = func)
diff --git a/scomps_rmarkdown_litr.html b/scomps_rmarkdown_litr.html index 44adce73..3bc16cb8 100644 --- a/scomps_rmarkdown_litr.html +++ b/scomps_rmarkdown_litr.html @@ -449,12 +449,12 @@

Create functions

withr::local_package("stars") withr::local_package("terra") withr::local_options(list(sf_use_s2 = FALSE)) - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) + bcsd_path <- system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars <- stars::read_stars(bcsd_path) - packbound_stars = check_packbound(bcsd_stars) - sprast_bcsd = terra::rast(bcsd_path) - packbound_terra = check_packbound(sprast_bcsd) + packbound_stars <- check_packbound(bcsd_stars) + sprast_bcsd <- terra::rast(bcsd_path) + packbound_terra <- check_packbound(sprast_bcsd) testthat::expect_equal(packbound_stars, "sf") testthat::expect_equal(packbound_terra, "terra") @@ -466,14 +466,14 @@

Create functions

withr::local_package("stars") withr::local_package("terra") withr::local_options(list(sf_use_s2 = FALSE)) - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) + bcsd_path <- system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars <- stars::read_stars(bcsd_path) - nc = system.file(package = "sf", "shape/nc.shp") - nc = sf::read_sf(nc) + nc <- system.file(package = "sf", "shape/nc.shp") + nc <- sf::read_sf(nc) - datatype_stars = check_datatype(bcsd_stars) - datatype_sf = check_datatype(nc) + datatype_stars <- check_datatype(bcsd_stars) + datatype_sf <- check_datatype(nc) testthat::expect_equal(datatype_stars, "raster") testthat::expect_equal(datatype_sf, "vector") @@ -490,10 +490,10 @@

Create functions

#' @export switch_packbound <- function(input) { stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) - cls_input = check_packbound(input) - type_input = check_datatype(input) + cls_input <- check_packbound(input) + type_input <- check_datatype(input) - switched = + switched <- switch(cls_input, sf = switch(type_input, vector = terra::vect(input), @@ -513,19 +513,19 @@

Create functions

withr::local_options(list(sf_use_s2 = FALSE)) # starts from sf/stars - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) - nc = system.file(package = "sf", "shape/nc.shp") - nc = sf::read_sf(nc) + bcsd_path <- system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars <- stars::read_stars(bcsd_path) + nc <- system.file(package = "sf", "shape/nc.shp") + nc <- sf::read_sf(nc) - stars_bcsd_tr = switch_packbound(bcsd_stars) - sf_nc_tr = switch_packbound(nc) + stars_bcsd_tr <- switch_packbound(bcsd_stars) + sf_nc_tr <- switch_packbound(nc) testthat::expect_equal(check_packbound(stars_bcsd_tr), "terra") testthat::expect_equal(check_packbound(sf_nc_tr), "terra") - stars_bcsd_trb = switch_packbound(stars_bcsd_tr) - sf_nc_trb = switch_packbound(sf_nc_tr) + stars_bcsd_trb <- switch_packbound(stars_bcsd_tr) + sf_nc_trb <- switch_packbound(sf_nc_tr) testthat::expect_equal(check_packbound(stars_bcsd_trb), "sf") testthat::expect_equal(check_packbound(sf_nc_trb), "sf") @@ -542,8 +542,11 @@

Create functions

#' @return A (reprojected) sf or SpatVector object. #' @export check_crs2 <- function(input, crs_standard = "EPSG:4326") { - check_crs.sf <- function(input){ - if (is.na(sf::st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} + check_crs_sf <- function(input) { + if (is.na(sf::st_crs(input))) { + cat('Please check the coordinate system or its EPSG code of your input object.') + return(NULL) + } if (sf::st_crs(input)$epsg == crs_standard ) { return(input) } @@ -551,17 +554,17 @@

Create functions

return(input_transformed) } - check_crs.terra <- function(input) { + check_crs_terra <- function(input) { if (terra::crs(input, describe = TRUE)$code == crs_standard) { return(input) } - input_transformed = terra::project(input, terra::crs(crs_standard)) + input_transformed <- terra::project(input, terra::crs(crs_standard)) return(input_transformed) } - detected = check_packbound(input) + detected <- check_packbound(input) switch(detected, - terra = check_crs.terra(input), - sf = check_crs.sf(input)) + terra = check_crs_terra(input), + sf = check_crs_sf(input)) }
#' Validate and repair input vector data
 #' @description It tries repairing input vector data. Vector validity violation usually appears in polygon data with self-crossing or hole orders. This function will pass the input_vector object to sf::st_make_valid() (if input_vector is sf) or terra::makeValid() (if input_vector is SpatVector). May take some time depending on the geometry complexity.
@@ -570,9 +573,9 @@ 

Create functions

#' @return A repaired sf or SpatVector object depending on the class of input_vector. #' @export validate_and_repair_vectors <- function(input_vector) { - detected = check_packbound(input_vector) + detected <- check_packbound(input_vector) - validated = switch(detected, + validated <- switch(detected, terra = terra::makeValid(input_vector), sf = sf::st_make_valid(input_vector)) @@ -605,11 +608,11 @@

Create functions

#' @return A terra::ext or sfc_POLYGON object of the computation extent. #' @export set_clip_extent <- function(pnts, buffer_r) { - detected = check_packbound(pnts) + detected <- check_packbound(pnts) if (detected == "terra") { - ext_input = terra::ext(pnts) + ext_input <- terra::ext(pnts) # Note that `+` operation on terra::ext output accounts for the operand as it is. - ext_input = ext_input + (1.1 * buffer_r + 30) + ext_input <- ext_input + (1.1 * buffer_r + 30) } if (detected == "sf") { ext_input <- pnts |> sf::st_bbox() @@ -628,28 +631,28 @@

Create functions

#' @param target_input sf or SpatVector object to be clipped #' @return A clipped sf or SpatVector object. #' @export -clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input){ +clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input) { if (any(sapply(list(pnts, buffer_r, target_input), is.null))) { stop("One or more required arguments are NULL. Please check.\n") } - detected_pnts = check_packbound(pnts) - detected_target = check_packbound(target_input) + detected_pnts <- check_packbound(pnts) + detected_target <- check_packbound(target_input) if (detected_pnts != detected_target) { warning("Inputs are not the same class.\n") - target_input = switch(detected_target, + target_input <- switch(detected_target, sf = terra::vect(target_input), terra = sf::st_as_sf(target_input)) } - ext_input = set_clip_extent(pnts, buffer_r) + ext_input <- set_clip_extent(pnts, buffer_r) cat("Clip target features with the input feature extent...\n") if (detected_pnts == "sf") { - cae = ext_input |> + cae <- ext_input |> sf::st_intersection(x = target_input) } if (detected_pnts == "terra") { - cae = terra::intersect(target_input, ext_input) + cae <- terra::intersect(target_input, ext_input) } return(cae) @@ -662,11 +665,11 @@

Create functions

#' @param nqsegs integer(1). the number of points per a quarter circle #' @param ras SpatRaster object to be clipped #' @export -clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras){ +clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras) { if (any(sapply(list(pnts, buffer_r, ras), is.null))) { stop("Any of required arguments are NULL. Please check.\n") } - ext_input = set_clip_extent(pnts, buffer_r) |> + ext_input <- set_clip_extent(pnts, buffer_r) |> terra::ext() cae <- terra::crop(ras, ext_input, snap = 'out') @@ -680,11 +683,11 @@

Create functions

#' @param nqsegs integer(1). the number of points per a quarter circle #' @param ras SpatRaster object to be clipped #' @export -clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras){ +clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras) { if (any(sapply(list(points_in, buffer_r, ras), is.null))) { stop("Any of required arguments are NULL. Please check.\n") } - ext_input = set_clip_extent(points_in, buffer_r) |> + ext_input <- set_clip_extent(points_in, buffer_r) |> terra::ext() cae <- terra::crop(ras, ext_input, snap = 'out') @@ -697,7 +700,7 @@

Create functions

#' @param ncutsx integer(1). The number of splits along x-axis. #' @param ncutsy integer(1). The number of splits along y-axis. #' @export -sp_indexing <- function(points_in, ncutsx, ncutsy){ +sp_indexing <- function(points_in, ncutsx, ncutsy) { # pts <- data.table(pnts) points_in <- points_in |> dplyr::mutate(or_id = seq(1, dim(points_in)[1])) @@ -726,7 +729,7 @@

Create functions

#' Estimate computational demands from inputs (to be written)
 #' 
-#' @param inputs a list of sf/Spat* objects or file paths
+#' @param inputs character vector of file paths
 #' @param nx integer(1). 
 #' @param ny integer(1). 
 #' @param padding numeric(1). Extrusion factor 
@@ -762,16 +765,24 @@ 

Create functions

#' @examples #' # data #' library(sf) -#' ncpath = system.file("shape/nc.shp", package = "sf") -#' nc = read_sf(ncpath) -#' nc = st_transform(nc, "EPSG:5070") +#' ncpath <- system.file("shape/nc.shp", package = "sf") +#' nc <- read_sf(ncpath) +#' nc <- st_transform(nc, "EPSG:5070") #' # run -#' # nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) +#' # nc_comp_region <- get_computational_regions(nc, nx = 12, ny = 8) #' #' @export -get_computational_regions <- function(input, mode = "grid", nx = 10, ny = 10, grid_min_features = 30, padding = NULL, unit = NULL, ...) { +get_computational_regions <- function( + input, + mode = "grid", + nx = 10, + ny = 10, + grid_min_features = 30, + padding = NULL, + unit = NULL, + ...) { # type check - package_detected = check_packbound(input) + package_detected <- check_packbound(input) # stopifnot("Invalid input.\n" = !any(grepl("^(sf|Spat)", class(input)))) stopifnot("Argument mode should be one of 'grid', 'grid_advanced', or 'density'.\n" = !mode %in% c("grid", "grid_advanced", "density")) stopifnot("Ensure that nx, ny, and grid_min_features are all integer.\n" = all(is.integer(nx), is.integer(y), is.integer(grid_min_features))) @@ -794,25 +805,25 @@

Create functions

#' @return A sf or SpatVector object of computation grids with unique grid id (CGRIDID). #' @export sp_index_grid <- function(points_in, ncutsx, ncutsy){ - package_detected = check_packbound(points_in) + package_detected <- check_packbound(points_in) - sp_index_grid.sf = function(points_in, ncutsx, ncutsy) { + sp_index_grid_sf <- function(points_in, ncutsx, ncutsy) { grid1 <- sf::st_make_grid(points_in, n = c(ncutsx, ncutsy)) |> as.data.frame() |> sf::st_as_sf() grid1 <- grid1[points_in, ] return(grid1) } - sp_index_grid.terra = function(points_in, ncutsx, ncutsy) { + sp_index_grid_terra <- function(points_in, ncutsx, ncutsy) { grid1 <- terra::rast(points_in, nrows = ncutsy, ncols = ncutsx) grid1 <- terra::as.polygons(grid1) return(grid1) } - grid_out = switch(package_detected, - sf = sp_index_grid.sf(points_in, ncutsx, ncutsy), - terra = sp_index_grid.terra(points_in, ncutsx, ncutsy)) + grid_out <- switch(package_detected, + sf = sp_index_grid_sf(points_in, ncutsx, ncutsy), + terra = sp_index_grid_terra(points_in, ncutsx, ncutsy)) - grid_out$CGRIDID = seq(1, nrow(x = grid_out)) + grid_out$CGRIDID <- seq(1, nrow(x = grid_out)) return(grid_out) } @@ -839,28 +850,28 @@

Create functions

#' # dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) #' #### NOT RUN #### #' @export -grid_merge <- function(points_in, grid_in, grid_min_features){ - package_detected = check_packbound(points_in) +grid_merge <- function(points_in, grid_in, grid_min_features) { + package_detected <- check_packbound(points_in) if (package_detected == "terra") { - points_in = sf::st_as_sf(points_in) - grid_in = sf::st_as_sf(grid_in) + points_in <- sf::st_as_sf(points_in) + grid_in <- sf::st_as_sf(grid_in) } - n_points_in_grid = lengths(sf::st_intersects(grid_in, points_in)) - grid_self = sf::st_relate(grid_in, grid_in, pattern = "2********") - grid_rook = sf::st_relate(grid_in, grid_in, pattern = "F***1****") - grid_rooks = mapply(c, grid_self, grid_rook, SIMPLIFY = FALSE) - grid_lt_threshold = (n_points_in_grid < grid_min_features) + n_points_in_grid <- lengths(sf::st_intersects(grid_in, points_in)) + grid_self <- sf::st_relate(grid_in, grid_in, pattern = "2********") + grid_rook <- sf::st_relate(grid_in, grid_in, pattern = "F***1****") + grid_rooks <- mapply(c, grid_self, grid_rook, SIMPLIFY = FALSE) + grid_lt_threshold <- (n_points_in_grid < grid_min_features) stopifnot("Threshold is too low. Please try higher threshold.\n" = sum(grid_lt_threshold) != 0) - grid_lt_threshold = seq(1, nrow(grid_in))[grid_lt_threshold] + grid_lt_threshold <- seq(1, nrow(grid_in))[grid_lt_threshold] # This part does not work as expected. Should investigate edge list and actual row index of the grid object; - identified = lapply(grid_rooks, \(x) sort(x[which(x %in% grid_lt_threshold)])) - identified = identified[grid_lt_threshold] - identified = unique(identified) - identified = identified[sapply(identified, length) > 1] + identified <- lapply(grid_rooks, \(x) sort(x[which(x %in% grid_lt_threshold)])) + identified <- identified[grid_lt_threshold] + identified <- unique(identified) + identified <- identified[sapply(identified, length) > 1] - identified_graph = lapply(identified, \(x) t(utils::combn(x, 2))) |> + identified_graph <- lapply(identified, \(x) t(utils::combn(x, 2))) |> Reduce(f = rbind, x = _) |> unique() |> apply(X = _, 2, as.character) |> @@ -869,30 +880,30 @@

Create functions

igraph::components() # return(identified_graph) - identified_graph_member = identified_graph$membership + identified_graph_member <- identified_graph$membership - merge_idx = as.integer(names(identified_graph_member)) - merge_member = split(merge_idx, identified_graph_member) - merge_member_label = unlist(lapply(merge_member, \(x) paste(x, collapse = "_"))) - merge_member_label = merge_member_label[identified_graph_member] + merge_idx <- as.integer(names(identified_graph_member)) + merge_member <- split(merge_idx, identified_graph_member) + merge_member_label <- unlist(lapply(merge_member, \(x) paste(x, collapse = "_"))) + merge_member_label <- merge_member_label[identified_graph_member] # sf object manipulation - grid_out = grid_in - grid_out[["CGRIDID"]][merge_idx] = merge_member_label + grid_out <- grid_in + grid_out[["CGRIDID"]][merge_idx] <- merge_member_label # for (k in seq_along(merge_member_label)) { # target_idx = merge_member_label[[k]] # grid_out[["CGRIDID"]][target_idx] = paste("M_", paste(target_idx, collapse = "_"), sep = "") # } - grid_out = grid_out |> + grid_out <- grid_out |> dplyr::group_by(!!rlang::sym("CGRIDID")) |> dplyr::summarize(n_merged = dplyr::n()) |> dplyr::ungroup() ## polsby-popper test for shape compactness - grid_merged = grid_out[which(grid_out$n_merged > 1),] - grid_merged_area = as.numeric(sf::st_area(grid_merged)) - grid_merged_perimeter = as.numeric(sf::st_length(sf::st_cast(grid_merged, "LINESTRING"))) - grid_merged_pptest = (4 * pi * grid_merged_area) / (grid_merged_perimeter ^ 2) + grid_merged <- grid_out[which(grid_out$n_merged > 1),] + grid_merged_area <- as.numeric(sf::st_area(grid_merged)) + grid_merged_perimeter <- as.numeric(sf::st_length(sf::st_cast(grid_merged, "LINESTRING"))) + grid_merged_pptest <- (4 * pi * grid_merged_area) / (grid_merged_perimeter ^ 2) # pptest value is bounded [0,1]; 0.3 threshold is groundless at this moment, possibly will make it defined by users. if (max(unique(identified_graph_member)) > floor(0.1 * nrow(grid_in)) || any(grid_merged_pptest < 0.3)) { @@ -932,20 +943,20 @@

Create functions

if (is.null(attr(extent, "names"))) { stop("Your extent is an unnamed numeric vector. Please define names xmin/xmax/ymin/ymax explicitly.\n") } - extent = switch( + extent <- switch( output_class, sf = sf::st_bbox(extent), terra = terra::ext(extent) ) } - extent_polygon = switch( + extent_polygon <- switch( output_class, sf = sf::st_as_sfc(extent), terra = terra::vect(extent) ) - extent_polygon = switch( + extent_polygon <- switch( output_class, sf = sf::st_set_crs(extent_polygon, sf::st_crs(crs)), terra = terra::set.crs(extent_polygon, terra::crs(crs)) @@ -972,18 +983,18 @@

Create functions

stop("CRS should be entered when the reference extent is a vector.\n") } if (is.numeric(reference) && !is.null(reference_crs)) { - reference = sf::st_as_sfc(sf::st_bbox(reference), crs = reference_crs) + reference <- sf::st_as_sfc(sf::st_bbox(reference), crs = reference_crs) } - query_crs = check_crs(data_query) - ref_crs = check_crs(reference) + query_crs <- check_crs(data_query) + ref_crs <- check_crs(reference) if (is.na(query_crs) || is.null(query_crs)) { stop("The dataset you queried has no CRS. Please make sure your dataset has the correct CRS.\n") } - query_matched = sf::st_transform(data_query, sf::st_crs(ref_crs)) + query_matched <- sf::st_transform(data_query, sf::st_crs(ref_crs)) - check_result = sf::st_within() + check_result <- sf::st_within() return(check_result) } @@ -1008,15 +1019,15 @@

Create functions

stopifnot("Check class of the input raster.\n" = any(methods::is(surf, "stars"), methods::is(surf, "SpatRaster"))) stopifnot(is.character(id)) - cls_polys = check_packbound(polys) - cls_surf = check_packbound(surf) + cls_polys <- check_packbound(polys) + cls_surf <- check_packbound(surf) if (cls_polys != cls_surf) { - polys = switch_packbound(polys) + polys <- switch_packbound(polys) } - extract_with_polygons.sf = function(polys, surf, id, func) { - extracted = stars::st_extract(x = surf, at = polys, FUN = func) + extract_with_polygons_sf <- function(polys, surf, id, func) { + extracted <- stars::st_extract(x = surf, at = polys, FUN = func) # extracted = extracted |> # group_by(!!sym(id)) |> # summarize(across(-!!sym(id), ~func)) |> @@ -1024,19 +1035,19 @@

Create functions

return(extracted) } - extract_with_polygons.terra = function(polys, surf, id, func) { - extracted = terra::extract(surf, polys) - extracted = extracted |> + extract_with_polygons_terra <- function(polys, surf, id, func) { + extracted <- terra::extract(surf, polys) + extracted <- extracted |> dplyr::group_by(!!rlang::sym(id)) |> dplyr::summarize(dplyr::across(-!!rlang::sym(id), ~func)) |> dplyr::ungroup() return(extracted) } - extracted_poly = switch( + extracted_poly <- switch( cls_surf, - sf = extract_with_polygons.sf(polys = polys, surf = surf, id = id, func = func), - terra = extract_with_polygons.terra(polys = polys, surf = surf, id = id, func = func) + sf = extract_with_polygons_sf(polys = polys, surf = surf, id = id, func = func), + terra = extract_with_polygons_terra(polys = polys, surf = surf, id = id, func = func) ) return(extracted_poly) } @@ -1059,7 +1070,7 @@

Create functions

stopifnot(is.character(id)) stopifnot(id %in% names(vector)) - extracted = + extracted <- switch(mode, polygon = extract_with_polygons(vector, raster, id, func), buffer = extract_with_buffer(vector, raster, id = id, func = func, ...)) @@ -1083,12 +1094,14 @@

Create functions

stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) if (methods::is(x, "sf") || methods::is(x, "stars")) { - crs_wkt = sf::st_crs(x) + crs_wkt <- sf::st_crs(x) } else { - crs_wkt = terra::crs(x) + crs_wkt <- terra::crs(x) } - stopifnot("No CRS is defined in the input. Please consult the metadata or the data source.\n" = !is.na(crs_wkt) || crs_wkt != "") + stopifnot( + "No CRS is defined in the input. Please consult the metadata or the data source.\n" = + !is.na(crs_wkt) || crs_wkt != "") return(crs_wkt) }
#' Check if the boundary of the vector/raster object is inside the reference
@@ -1098,20 +1111,20 @@ 

Create functions

#' @author Insang Song \email{geoissong@@gmail.com} #' @export check_within_reference <- function(input_object, reference) { - stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) - stopifnot("Reference is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) + stopifnot("Input is invalid.\n" = (methods::is(input_object, "sf") || methods::is(input_object, "stars") || methods::is(input_object, "SpatVector") || methods::is(input_object, "SpatRaster"))) + stopifnot("Reference is invalid.\n" = (methods::is(input_object, "sf") || methods::is(input_object, "stars") || methods::is(input_object, "SpatVector") || methods::is(input_object, "SpatRaster"))) bbox_input <- input_object sf::st_bbox() |> sf::st_as_sfc() - bbox_reference = reference |> + bbox_reference <- reference |> sf::st_bbox() |> sf::st_as_sfc() - iswithin = sf::st_covered_by(bbox_input, bbox_reference) - iswithin = length(iswithin[[1]]) - iswithin = (iswithin == 1) + iswithin <- sf::st_covered_by(bbox_input, bbox_reference) + iswithin <- length(iswithin[[1]]) + iswithin <- (iswithin == 1) invisible(iswithin) } @@ -1128,26 +1141,26 @@

Create functions

#' @export calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, target_fields) { # define sources, set SEDC exponential decay range - len_point_from = seq_len(nrow(point_from)) - len_point_to = seq_len(nrow(point_to)) + len_point_from <- seq_len(nrow(point_from)) + len_point_to <- seq_len(nrow(point_to)) - point_from$from_id = len_point_from + point_from$from_id <- len_point_from # select egrid_v only if closer than 3e5 meters from each aqs - point_from_buf = terra::buffer(point_from_buf, threshold = threshold, quadsegs = 90) - point_to = point_to[point_from_buf,] - point_to$to_id = len_point_to + point_from_buf <- terra::buffer(point_from_buf, threshold = threshold, quadsegs = 90) + point_to <- point_to[point_from_buf,] + point_to$to_id <- len_point_to # near features with distance argument: only returns integer indices - near_from_to = terra::nearby(point_from, point_to, distance = threshold) + near_from_to <- terra::nearby(point_from, point_to, distance = threshold) # attaching actual distance - dist_near_to = terra::distance(point_from, point_to) - dist_near_to_df = as.vector(dist_near_to) + dist_near_to <- terra::distance(point_from, point_to) + dist_near_to_df <- as.vector(dist_near_to) # adding integer indices - dist_near_to_tdf = expand.grid(from_id = len_point_from, to_id = len_point_to) - dist_near_to_df = cbind(dist_near_to_tdf, dist = dist_near_to_df) + dist_near_to_tdf <- expand.grid(from_id = len_point_from, to_id = len_point_to) + dist_near_to_df <- cbind(dist_near_to_tdf, dist = dist_near_to_df) # summary - near_from_to = near_from_to |> + near_from_to <- near_from_to |> dplyr::as_tibble() |> dplyr::left_join(data.frame(point_from)) |> dplyr::left_join(data.frame(point_to)) |> @@ -1175,15 +1188,15 @@

Create functions

#' library(sf) #' #' # run -#' nc = sf::st_read(system.file("shape/nc.shp", package="sf")) -#' nc = sf::st_transform(nc, 5070) -#' pp = sf::st_sample(nc, size = 300) -#' pp = sf::st_as_sf(pp) -#' pp[["id"]] = seq(1, nrow(pp)) -#' sf::st_crs(pp) = "EPSG:5070" -#' ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +#' nc <- sf::st_read(system.file("shape/nc.shp", package="sf")) +#' nc <- sf::st_transform(nc, 5070) +#' pp <- sf::st_sample(nc, size = 300) +#' pp <- sf::st_as_sf(pp) +#' pp[["id"]] <- seq(1, nrow(pp)) +#' sf::st_crs(pp) <- "EPSG:5070" +#' ppb <- sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' -#' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) +#' system.time({ppb_nc_aw <- aw_covariates(ppb, nc, 'id')}) #' summary(ppb_nc_aw) #' #### Example of aw_covariates ends #### #' @export @@ -1193,13 +1206,13 @@

Create functions

#check_crs() ## distinguish numeric and nonnumeric columns - index_numeric = grep("(integer|numeric)", unlist(sapply(poly_weight, class))) + index_numeric <- grep("(integer|numeric)", unlist(sapply(poly_weight, class))) aw_covariates.terra = function(poly_in, poly_weight, id_poly_in = id_poly_in) { - poly_intersected = terra::intersect(poly_in, poly_weight) - poly_intersected[["area_segment_"]] = terra::expanse(poly_intersected) - poly_intersected = data.frame(poly_intersected) |> + poly_intersected <- terra::intersect(poly_in, poly_weight) + poly_intersected[["area_segment_"]] <- terra::expanse(poly_intersected) + poly_intersected <- data.frame(poly_intersected) |> dplyr::group_by(!!rlang::sym(id_poly_in)) |> dplyr::summarize(dplyr::across(is.numeric, ~stats::weighted.mean(., w = area_segment_))) |> @@ -1207,11 +1220,11 @@

Create functions

return(poly_intersected) } - class_poly_in = check_packbound(poly_in) - class_poly_weight = check_packbound(poly_weight) + class_poly_in <- check_packbound(poly_in) + class_poly_weight <- check_packbound(poly_weight) if (class_poly_in != class_poly_weight) { - class_poly_weight = switch_packbound(class_poly_weight) + class_poly_weight <- switch_packbound(class_poly_weight) } switch(class_poly_in, @@ -1256,7 +1269,7 @@

Create functions

stopifnot(is.integer(qsegs)) if (!is.null(kernel)) { - extracted = extract_with_buffer.flat(points = points, + extracted <- extract_with_buffer.flat(points = points, surf = surf, radius = radius, id = id, @@ -1265,7 +1278,7 @@

Create functions

return(extracted) } - extracted = extract_with_buffer.kernel(points = points, + extracted <- extract_with_buffer.kernel(points = points, surf = surf, radius = radius, id = id, @@ -1282,17 +1295,17 @@

Create functions

points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL ) { # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + bufs <- terra::buffer(points, width = radius, quadsegs = qsegs) # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) + bufs_extent <- terra::ext(bufs) + surf_cropped <- terra::crop(surf, bufs_extent) + name_surf_val <- names(surf) # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = + surf_at_bufs <- terra::extract(surf_cropped, bufs) + surf_at_bufs_summary <- surf_at_bufs |> dplyr::group_by(ID) |> - dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm = TRUE)) |> dplyr::ungroup() return(surf_at_bufs_summary) } @@ -1303,18 +1316,18 @@

Create functions

points, surf, radius, id, qsegs, func = mean, kernel, bandwidth ) { # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + bufs <- terra::buffer(points, width = radius, quadsegs = qsegs) # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) + bufs_extent <- terra::ext(bufs) + surf_cropped <- terra::crop(surf, bufs_extent) + name_surf_val <- names(surf) # TODO: kernel implementation # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = + surf_at_bufs <- terra::extract(surf_cropped, bufs) + surf_at_bufs_summary <- surf_at_bufs |> dplyr::group_by(ID) |> dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> @@ -1338,23 +1351,23 @@

Create functions

# subset using grids and grid_id if (!is.null(grid_id)) { if (is.character(grid_id)) { - grid_id_parsed = strsplit(grid_id, ":", fixed = TRUE)[[1]] - grid_ids = c(which(unique(grids[["CGRIDID"]]) == grid_id_parsed[1]), + grid_id_parsed <- strsplit(grid_id, ":", fixed = TRUE)[[1]] + grid_ids <- c(which(unique(grids[["CGRIDID"]]) == grid_id_parsed[1]), which(unique(grids[["CGRIDID"]]) == grid_id_parsed[2])) } if (is.numeric(grid_id)) { - grid_ids = unique(grids[["CGRIDID"]])[grid_id] + grid_ids <- unique(grids[["CGRIDID"]])[grid_id] } } - grids_target = grids[grid_ids,] - grids_target_list = split(grids_target, grids_target[["CGRIDID"]]) + grids_target <- grids[grid_ids,] + grids_target_list <- split(grids_target, grids_target[["CGRIDID"]]) - results_distributed = future.apply::future_lapply( + results_distributed <- future.apply::future_lapply( \(x, ...) { fun(...) }, grids_target_list, future.seed = TRUE) - results_distributed = do.call(rbind, results_distributed) + results_distributed <- do.call(rbind, results_distributed) return(results_distributed) }
@@ -1368,12 +1381,12 @@

Documenting the package and building

devtools::document(".") devtools::test() devtools::build() -devtools::install(dependencies = F, build_vignettes = TRUE) +devtools::install(dependencies = FALSE, build_vignettes = TRUE) # devtools::check(document = FALSE)
## ℹ Updating scomps documentation
 ## ℹ Loading scomps
-
## Warning: [check.R:133] @description requires a value
+
## Warning: [check.R:136] @description requires a value
## Warning: [processing.R:139] @return requires a value
## Writing 'NAMESPACE'
 ## Writing 'check_packbound.Rd'
@@ -1441,7 +1454,7 @@ 

Documenting the package and building

## Warning: invalid gid value replaced by that for user 'nobody' ## ## Running /Library/Frameworks/R.framework/Resources/bin/R CMD INSTALL \ -## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpdIhnyr/scomps_0.0.3.10042023.tar.gz \ +## /var/folders/58/7rn_bn5d6k3_cxwnzdhswpz4n0z2n9/T//RtmpXO9KMG/scomps_0.0.3.10042023.tar.gz \ ## --install-tests ## * installing to library ‘/Users/songi2/Library/R/arm64/4.3/library’ ## * installing *source* package ‘scomps’ ... diff --git a/scomps_rmarkdown_litr.rmd b/scomps_rmarkdown_litr.rmd index 854d21e4..c7ddd025 100644 --- a/scomps_rmarkdown_litr.rmd +++ b/scomps_rmarkdown_litr.rmd @@ -115,12 +115,12 @@ testthat::test_that("What package does the input object belong?", withr::local_package("stars") withr::local_package("terra") withr::local_options(list(sf_use_s2 = FALSE)) - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) + bcsd_path <- system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars <- stars::read_stars(bcsd_path) - packbound_stars = check_packbound(bcsd_stars) - sprast_bcsd = terra::rast(bcsd_path) - packbound_terra = check_packbound(sprast_bcsd) + packbound_stars <- check_packbound(bcsd_stars) + sprast_bcsd <- terra::rast(bcsd_path) + packbound_terra <- check_packbound(sprast_bcsd) testthat::expect_equal(packbound_stars, "sf") testthat::expect_equal(packbound_terra, "terra") @@ -132,14 +132,14 @@ testthat::test_that("What package does the input object belong?", withr::local_package("stars") withr::local_package("terra") withr::local_options(list(sf_use_s2 = FALSE)) - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) + bcsd_path <- system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars <- stars::read_stars(bcsd_path) - nc = system.file(package = "sf", "shape/nc.shp") - nc = sf::read_sf(nc) + nc <- system.file(package = "sf", "shape/nc.shp") + nc <- sf::read_sf(nc) - datatype_stars = check_datatype(bcsd_stars) - datatype_sf = check_datatype(nc) + datatype_stars <- check_datatype(bcsd_stars) + datatype_sf <- check_datatype(nc) testthat::expect_equal(datatype_stars, "raster") testthat::expect_equal(datatype_sf, "vector") @@ -155,10 +155,10 @@ testthat::test_that("What package does the input object belong?", #' @export switch_packbound <- function(input) { stopifnot("Input should be one of sf or Spat* object.\n" = any(methods::is(input, "sf"), methods::is(input, "stars"), methods::is(input, "SpatVector"), methods::is(input, "SpatRaster"))) - cls_input = check_packbound(input) - type_input = check_datatype(input) + cls_input <- check_packbound(input) + type_input <- check_datatype(input) - switched = + switched <- switch(cls_input, sf = switch(type_input, vector = terra::vect(input), @@ -182,19 +182,19 @@ testthat::test_that("Format is well converted", withr::local_options(list(sf_use_s2 = FALSE)) # starts from sf/stars - bcsd_path = system.file(package = "stars", "nc/bcsd_obs_1999.nc") - bcsd_stars = stars::read_stars(bcsd_path) - nc = system.file(package = "sf", "shape/nc.shp") - nc = sf::read_sf(nc) + bcsd_path <- system.file(package = "stars", "nc/bcsd_obs_1999.nc") + bcsd_stars <- stars::read_stars(bcsd_path) + nc <- system.file(package = "sf", "shape/nc.shp") + nc <- sf::read_sf(nc) - stars_bcsd_tr = switch_packbound(bcsd_stars) - sf_nc_tr = switch_packbound(nc) + stars_bcsd_tr <- switch_packbound(bcsd_stars) + sf_nc_tr <- switch_packbound(nc) testthat::expect_equal(check_packbound(stars_bcsd_tr), "terra") testthat::expect_equal(check_packbound(sf_nc_tr), "terra") - stars_bcsd_trb = switch_packbound(stars_bcsd_tr) - sf_nc_trb = switch_packbound(sf_nc_tr) + stars_bcsd_trb <- switch_packbound(stars_bcsd_tr) + sf_nc_trb <- switch_packbound(sf_nc_tr) testthat::expect_equal(check_packbound(stars_bcsd_trb), "sf") testthat::expect_equal(check_packbound(sf_nc_trb), "sf") @@ -212,8 +212,11 @@ testthat::test_that("Format is well converted", #' @return A (reprojected) sf or SpatVector object. #' @export check_crs2 <- function(input, crs_standard = "EPSG:4326") { - check_crs.sf <- function(input){ - if (is.na(sf::st_crs(input))){cat('Please check the coordinate system or its EPSG code of your input object.'); return(NULL)} + check_crs_sf <- function(input) { + if (is.na(sf::st_crs(input))) { + cat('Please check the coordinate system or its EPSG code of your input object.') + return(NULL) + } if (sf::st_crs(input)$epsg == crs_standard ) { return(input) } @@ -221,17 +224,17 @@ check_crs2 <- function(input, crs_standard = "EPSG:4326") { return(input_transformed) } - check_crs.terra <- function(input) { + check_crs_terra <- function(input) { if (terra::crs(input, describe = TRUE)$code == crs_standard) { return(input) } - input_transformed = terra::project(input, terra::crs(crs_standard)) + input_transformed <- terra::project(input, terra::crs(crs_standard)) return(input_transformed) } - detected = check_packbound(input) + detected <- check_packbound(input) switch(detected, - terra = check_crs.terra(input), - sf = check_crs.sf(input)) + terra = check_crs_terra(input), + sf = check_crs_sf(input)) } ``` @@ -243,9 +246,9 @@ check_crs2 <- function(input, crs_standard = "EPSG:4326") { #' @return A repaired sf or SpatVector object depending on the class of input_vector. #' @export validate_and_repair_vectors <- function(input_vector) { - detected = check_packbound(input_vector) + detected <- check_packbound(input_vector) - validated = switch(detected, + validated <- switch(detected, terra = terra::makeValid(input_vector), sf = sf::st_make_valid(input_vector)) @@ -285,11 +288,11 @@ initate_log <- function(expr, dolog = FALSE, logpath) { #' @return A terra::ext or sfc_POLYGON object of the computation extent. #' @export set_clip_extent <- function(pnts, buffer_r) { - detected = check_packbound(pnts) + detected <- check_packbound(pnts) if (detected == "terra") { - ext_input = terra::ext(pnts) + ext_input <- terra::ext(pnts) # Note that `+` operation on terra::ext output accounts for the operand as it is. - ext_input = ext_input + (1.1 * buffer_r + 30) + ext_input <- ext_input + (1.1 * buffer_r + 30) } if (detected == "sf") { ext_input <- pnts |> sf::st_bbox() @@ -312,28 +315,28 @@ set_clip_extent <- function(pnts, buffer_r) { #' @param target_input sf or SpatVector object to be clipped #' @return A clipped sf or SpatVector object. #' @export -clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input){ +clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input) { if (any(sapply(list(pnts, buffer_r, target_input), is.null))) { stop("One or more required arguments are NULL. Please check.\n") } - detected_pnts = check_packbound(pnts) - detected_target = check_packbound(target_input) + detected_pnts <- check_packbound(pnts) + detected_target <- check_packbound(target_input) if (detected_pnts != detected_target) { warning("Inputs are not the same class.\n") - target_input = switch(detected_target, + target_input <- switch(detected_target, sf = terra::vect(target_input), terra = sf::st_as_sf(target_input)) } - ext_input = set_clip_extent(pnts, buffer_r) + ext_input <- set_clip_extent(pnts, buffer_r) cat("Clip target features with the input feature extent...\n") if (detected_pnts == "sf") { - cae = ext_input |> + cae <- ext_input |> sf::st_intersection(x = target_input) } if (detected_pnts == "terra") { - cae = terra::intersect(target_input, ext_input) + cae <- terra::intersect(target_input, ext_input) } return(cae) @@ -350,11 +353,11 @@ clip_as_extent <- function(pnts, buffer_r, nqsegs=NULL, target_input){ #' @param nqsegs integer(1). the number of points per a quarter circle #' @param ras SpatRaster object to be clipped #' @export -clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras){ +clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras) { if (any(sapply(list(pnts, buffer_r, ras), is.null))) { stop("Any of required arguments are NULL. Please check.\n") } - ext_input = set_clip_extent(pnts, buffer_r) |> + ext_input <- set_clip_extent(pnts, buffer_r) |> terra::ext() cae <- terra::crop(ras, ext_input, snap = 'out') @@ -372,11 +375,11 @@ clip_as_extent_ras <- function(pnts, buffer_r, nqsegs = 180, ras){ #' @param nqsegs integer(1). the number of points per a quarter circle #' @param ras SpatRaster object to be clipped #' @export -clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras){ +clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras) { if (any(sapply(list(points_in, buffer_r, ras), is.null))) { stop("Any of required arguments are NULL. Please check.\n") } - ext_input = set_clip_extent(points_in, buffer_r) |> + ext_input <- set_clip_extent(points_in, buffer_r) |> terra::ext() cae <- terra::crop(ras, ext_input, snap = 'out') @@ -393,7 +396,7 @@ clip_as_extent_ras2 <- function(points_in, buffer_r, nqsegs=180, ras){ #' @param ncutsx integer(1). The number of splits along x-axis. #' @param ncutsy integer(1). The number of splits along y-axis. #' @export -sp_indexing <- function(points_in, ncutsx, ncutsy){ +sp_indexing <- function(points_in, ncutsx, ncutsy) { # pts <- data.table(pnts) points_in <- points_in |> dplyr::mutate(or_id = seq(1, dim(points_in)[1])) @@ -430,7 +433,7 @@ rast_short <- function(rasterpath, win) { ```{r} #' Estimate computational demands from inputs (to be written) #' -#' @param inputs a list of sf/Spat* objects or file paths +#' @param inputs character vector of file paths #' @param nx integer(1). #' @param ny integer(1). #' @param padding numeric(1). Extrusion factor @@ -470,16 +473,24 @@ estimate_demands <- function( #' @examples #' # data #' library(sf) -#' ncpath = system.file("shape/nc.shp", package = "sf") -#' nc = read_sf(ncpath) -#' nc = st_transform(nc, "EPSG:5070") +#' ncpath <- system.file("shape/nc.shp", package = "sf") +#' nc <- read_sf(ncpath) +#' nc <- st_transform(nc, "EPSG:5070") #' # run -#' # nc_comp_region = get_computational_regions(nc, nx = 12, ny = 8) +#' # nc_comp_region <- get_computational_regions(nc, nx = 12, ny = 8) #' #' @export -get_computational_regions <- function(input, mode = "grid", nx = 10, ny = 10, grid_min_features = 30, padding = NULL, unit = NULL, ...) { +get_computational_regions <- function( + input, + mode = "grid", + nx = 10, + ny = 10, + grid_min_features = 30, + padding = NULL, + unit = NULL, + ...) { # type check - package_detected = check_packbound(input) + package_detected <- check_packbound(input) # stopifnot("Invalid input.\n" = !any(grepl("^(sf|Spat)", class(input)))) stopifnot("Argument mode should be one of 'grid', 'grid_advanced', or 'density'.\n" = !mode %in% c("grid", "grid_advanced", "density")) stopifnot("Ensure that nx, ny, and grid_min_features are all integer.\n" = all(is.integer(nx), is.integer(y), is.integer(grid_min_features))) @@ -502,25 +513,25 @@ get_computational_regions <- function(input, mode = "grid", nx = 10, ny = 10, gr #' @return A sf or SpatVector object of computation grids with unique grid id (CGRIDID). #' @export sp_index_grid <- function(points_in, ncutsx, ncutsy){ - package_detected = check_packbound(points_in) + package_detected <- check_packbound(points_in) - sp_index_grid.sf = function(points_in, ncutsx, ncutsy) { + sp_index_grid_sf <- function(points_in, ncutsx, ncutsy) { grid1 <- sf::st_make_grid(points_in, n = c(ncutsx, ncutsy)) |> as.data.frame() |> sf::st_as_sf() grid1 <- grid1[points_in, ] return(grid1) } - sp_index_grid.terra = function(points_in, ncutsx, ncutsy) { + sp_index_grid_terra <- function(points_in, ncutsx, ncutsy) { grid1 <- terra::rast(points_in, nrows = ncutsy, ncols = ncutsx) grid1 <- terra::as.polygons(grid1) return(grid1) } - grid_out = switch(package_detected, - sf = sp_index_grid.sf(points_in, ncutsx, ncutsy), - terra = sp_index_grid.terra(points_in, ncutsx, ncutsy)) + grid_out <- switch(package_detected, + sf = sp_index_grid_sf(points_in, ncutsx, ncutsy), + terra = sp_index_grid_terra(points_in, ncutsx, ncutsy)) - grid_out$CGRIDID = seq(1, nrow(x = grid_out)) + grid_out$CGRIDID <- seq(1, nrow(x = grid_out)) return(grid_out) } @@ -547,28 +558,28 @@ sp_index_grid <- function(points_in, ncutsx, ncutsy){ #' # dg_merged = grid_merge(sf::st_as_sf(sss), dgs, 100) #' #### NOT RUN #### #' @export -grid_merge <- function(points_in, grid_in, grid_min_features){ - package_detected = check_packbound(points_in) +grid_merge <- function(points_in, grid_in, grid_min_features) { + package_detected <- check_packbound(points_in) if (package_detected == "terra") { - points_in = sf::st_as_sf(points_in) - grid_in = sf::st_as_sf(grid_in) + points_in <- sf::st_as_sf(points_in) + grid_in <- sf::st_as_sf(grid_in) } - n_points_in_grid = lengths(sf::st_intersects(grid_in, points_in)) - grid_self = sf::st_relate(grid_in, grid_in, pattern = "2********") - grid_rook = sf::st_relate(grid_in, grid_in, pattern = "F***1****") - grid_rooks = mapply(c, grid_self, grid_rook, SIMPLIFY = FALSE) - grid_lt_threshold = (n_points_in_grid < grid_min_features) + n_points_in_grid <- lengths(sf::st_intersects(grid_in, points_in)) + grid_self <- sf::st_relate(grid_in, grid_in, pattern = "2********") + grid_rook <- sf::st_relate(grid_in, grid_in, pattern = "F***1****") + grid_rooks <- mapply(c, grid_self, grid_rook, SIMPLIFY = FALSE) + grid_lt_threshold <- (n_points_in_grid < grid_min_features) stopifnot("Threshold is too low. Please try higher threshold.\n" = sum(grid_lt_threshold) != 0) - grid_lt_threshold = seq(1, nrow(grid_in))[grid_lt_threshold] + grid_lt_threshold <- seq(1, nrow(grid_in))[grid_lt_threshold] # This part does not work as expected. Should investigate edge list and actual row index of the grid object; - identified = lapply(grid_rooks, \(x) sort(x[which(x %in% grid_lt_threshold)])) - identified = identified[grid_lt_threshold] - identified = unique(identified) - identified = identified[sapply(identified, length) > 1] + identified <- lapply(grid_rooks, \(x) sort(x[which(x %in% grid_lt_threshold)])) + identified <- identified[grid_lt_threshold] + identified <- unique(identified) + identified <- identified[sapply(identified, length) > 1] - identified_graph = lapply(identified, \(x) t(utils::combn(x, 2))) |> + identified_graph <- lapply(identified, \(x) t(utils::combn(x, 2))) |> Reduce(f = rbind, x = _) |> unique() |> apply(X = _, 2, as.character) |> @@ -577,30 +588,30 @@ grid_merge <- function(points_in, grid_in, grid_min_features){ igraph::components() # return(identified_graph) - identified_graph_member = identified_graph$membership + identified_graph_member <- identified_graph$membership - merge_idx = as.integer(names(identified_graph_member)) - merge_member = split(merge_idx, identified_graph_member) - merge_member_label = unlist(lapply(merge_member, \(x) paste(x, collapse = "_"))) - merge_member_label = merge_member_label[identified_graph_member] + merge_idx <- as.integer(names(identified_graph_member)) + merge_member <- split(merge_idx, identified_graph_member) + merge_member_label <- unlist(lapply(merge_member, \(x) paste(x, collapse = "_"))) + merge_member_label <- merge_member_label[identified_graph_member] # sf object manipulation - grid_out = grid_in - grid_out[["CGRIDID"]][merge_idx] = merge_member_label + grid_out <- grid_in + grid_out[["CGRIDID"]][merge_idx] <- merge_member_label # for (k in seq_along(merge_member_label)) { # target_idx = merge_member_label[[k]] # grid_out[["CGRIDID"]][target_idx] = paste("M_", paste(target_idx, collapse = "_"), sep = "") # } - grid_out = grid_out |> + grid_out <- grid_out |> dplyr::group_by(!!rlang::sym("CGRIDID")) |> dplyr::summarize(n_merged = dplyr::n()) |> dplyr::ungroup() ## polsby-popper test for shape compactness - grid_merged = grid_out[which(grid_out$n_merged > 1),] - grid_merged_area = as.numeric(sf::st_area(grid_merged)) - grid_merged_perimeter = as.numeric(sf::st_length(sf::st_cast(grid_merged, "LINESTRING"))) - grid_merged_pptest = (4 * pi * grid_merged_area) / (grid_merged_perimeter ^ 2) + grid_merged <- grid_out[which(grid_out$n_merged > 1),] + grid_merged_area <- as.numeric(sf::st_area(grid_merged)) + grid_merged_perimeter <- as.numeric(sf::st_length(sf::st_cast(grid_merged, "LINESTRING"))) + grid_merged_pptest <- (4 * pi * grid_merged_area) / (grid_merged_perimeter ^ 2) # pptest value is bounded [0,1]; 0.3 threshold is groundless at this moment, possibly will make it defined by users. if (max(unique(identified_graph_member)) > floor(0.1 * nrow(grid_in)) || any(grid_merged_pptest < 0.3)) { @@ -643,20 +654,20 @@ extent_to_polygon <- function(extent, output_class = "terra", crs = "EPSG:4326") if (is.null(attr(extent, "names"))) { stop("Your extent is an unnamed numeric vector. Please define names xmin/xmax/ymin/ymax explicitly.\n") } - extent = switch( + extent <- switch( output_class, sf = sf::st_bbox(extent), terra = terra::ext(extent) ) } - extent_polygon = switch( + extent_polygon <- switch( output_class, sf = sf::st_as_sfc(extent), terra = terra::vect(extent) ) - extent_polygon = switch( + extent_polygon <- switch( output_class, sf = sf::st_set_crs(extent_polygon, sf::st_crs(crs)), terra = terra::set.crs(extent_polygon, terra::crs(crs)) @@ -686,18 +697,18 @@ check_bbox <- function( stop("CRS should be entered when the reference extent is a vector.\n") } if (is.numeric(reference) && !is.null(reference_crs)) { - reference = sf::st_as_sfc(sf::st_bbox(reference), crs = reference_crs) + reference <- sf::st_as_sfc(sf::st_bbox(reference), crs = reference_crs) } - query_crs = check_crs(data_query) - ref_crs = check_crs(reference) + query_crs <- check_crs(data_query) + ref_crs <- check_crs(reference) if (is.na(query_crs) || is.null(query_crs)) { stop("The dataset you queried has no CRS. Please make sure your dataset has the correct CRS.\n") } - query_matched = sf::st_transform(data_query, sf::st_crs(ref_crs)) + query_matched <- sf::st_transform(data_query, sf::st_crs(ref_crs)) - check_result = sf::st_within() + check_result <- sf::st_within() return(check_result) } @@ -743,15 +754,15 @@ extract_with_polygons <- function( stopifnot("Check class of the input raster.\n" = any(methods::is(surf, "stars"), methods::is(surf, "SpatRaster"))) stopifnot(is.character(id)) - cls_polys = check_packbound(polys) - cls_surf = check_packbound(surf) + cls_polys <- check_packbound(polys) + cls_surf <- check_packbound(surf) if (cls_polys != cls_surf) { - polys = switch_packbound(polys) + polys <- switch_packbound(polys) } - extract_with_polygons.sf = function(polys, surf, id, func) { - extracted = stars::st_extract(x = surf, at = polys, FUN = func) + extract_with_polygons_sf <- function(polys, surf, id, func) { + extracted <- stars::st_extract(x = surf, at = polys, FUN = func) # extracted = extracted |> # group_by(!!sym(id)) |> # summarize(across(-!!sym(id), ~func)) |> @@ -759,19 +770,19 @@ extract_with_polygons <- function( return(extracted) } - extract_with_polygons.terra = function(polys, surf, id, func) { - extracted = terra::extract(surf, polys) - extracted = extracted |> + extract_with_polygons_terra <- function(polys, surf, id, func) { + extracted <- terra::extract(surf, polys) + extracted <- extracted |> dplyr::group_by(!!rlang::sym(id)) |> dplyr::summarize(dplyr::across(-!!rlang::sym(id), ~func)) |> dplyr::ungroup() return(extracted) } - extracted_poly = switch( + extracted_poly <- switch( cls_surf, - sf = extract_with_polygons.sf(polys = polys, surf = surf, id = id, func = func), - terra = extract_with_polygons.terra(polys = polys, surf = surf, id = id, func = func) + sf = extract_with_polygons_sf(polys = polys, surf = surf, id = id, func = func), + terra = extract_with_polygons_terra(polys = polys, surf = surf, id = id, func = func) ) return(extracted_poly) } @@ -797,7 +808,7 @@ extract_with <- function(raster, vector, id, func = mean, mode = "polygon", ...) stopifnot(is.character(id)) stopifnot(id %in% names(vector)) - extracted = + extracted <- switch(mode, polygon = extract_with_polygons(vector, raster, id, func), buffer = extract_with_buffer(vector, raster, id = id, func = func, ...)) @@ -824,12 +835,14 @@ check_crs <- function(x) { stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) if (methods::is(x, "sf") || methods::is(x, "stars")) { - crs_wkt = sf::st_crs(x) + crs_wkt <- sf::st_crs(x) } else { - crs_wkt = terra::crs(x) + crs_wkt <- terra::crs(x) } - stopifnot("No CRS is defined in the input. Please consult the metadata or the data source.\n" = !is.na(crs_wkt) || crs_wkt != "") + stopifnot( + "No CRS is defined in the input. Please consult the metadata or the data source.\n" = + !is.na(crs_wkt) || crs_wkt != "") return(crs_wkt) } ``` @@ -843,20 +856,20 @@ check_crs <- function(x) { #' @author Insang Song \email{geoissong@@gmail.com} #' @export check_within_reference <- function(input_object, reference) { - stopifnot("Input is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) - stopifnot("Reference is invalid.\n" = (methods::is(x, "sf") || methods::is(x, "stars") || methods::is(x, "SpatVector") || methods::is(x, "SpatRaster"))) + stopifnot("Input is invalid.\n" = (methods::is(input_object, "sf") || methods::is(input_object, "stars") || methods::is(input_object, "SpatVector") || methods::is(input_object, "SpatRaster"))) + stopifnot("Reference is invalid.\n" = (methods::is(input_object, "sf") || methods::is(input_object, "stars") || methods::is(input_object, "SpatVector") || methods::is(input_object, "SpatRaster"))) bbox_input <- input_object sf::st_bbox() |> sf::st_as_sfc() - bbox_reference = reference |> + bbox_reference <- reference |> sf::st_bbox() |> sf::st_as_sfc() - iswithin = sf::st_covered_by(bbox_input, bbox_reference) - iswithin = length(iswithin[[1]]) - iswithin = (iswithin == 1) + iswithin <- sf::st_covered_by(bbox_input, bbox_reference) + iswithin <- length(iswithin[[1]]) + iswithin <- (iswithin == 1) invisible(iswithin) } @@ -877,26 +890,26 @@ check_within_reference <- function(input_object, reference) { #' @export calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, target_fields) { # define sources, set SEDC exponential decay range - len_point_from = seq_len(nrow(point_from)) - len_point_to = seq_len(nrow(point_to)) + len_point_from <- seq_len(nrow(point_from)) + len_point_to <- seq_len(nrow(point_to)) - point_from$from_id = len_point_from + point_from$from_id <- len_point_from # select egrid_v only if closer than 3e5 meters from each aqs - point_from_buf = terra::buffer(point_from_buf, threshold = threshold, quadsegs = 90) - point_to = point_to[point_from_buf,] - point_to$to_id = len_point_to + point_from_buf <- terra::buffer(point_from_buf, threshold = threshold, quadsegs = 90) + point_to <- point_to[point_from_buf,] + point_to$to_id <- len_point_to # near features with distance argument: only returns integer indices - near_from_to = terra::nearby(point_from, point_to, distance = threshold) + near_from_to <- terra::nearby(point_from, point_to, distance = threshold) # attaching actual distance - dist_near_to = terra::distance(point_from, point_to) - dist_near_to_df = as.vector(dist_near_to) + dist_near_to <- terra::distance(point_from, point_to) + dist_near_to_df <- as.vector(dist_near_to) # adding integer indices - dist_near_to_tdf = expand.grid(from_id = len_point_from, to_id = len_point_to) - dist_near_to_df = cbind(dist_near_to_tdf, dist = dist_near_to_df) + dist_near_to_tdf <- expand.grid(from_id = len_point_from, to_id = len_point_to) + dist_near_to_df <- cbind(dist_near_to_tdf, dist = dist_near_to_df) # summary - near_from_to = near_from_to |> + near_from_to <- near_from_to |> dplyr::as_tibble() |> dplyr::left_join(data.frame(point_from)) |> dplyr::left_join(data.frame(point_to)) |> @@ -927,15 +940,15 @@ calculate_sedc <- function(point_from, point_to, id, sedc_bandwidth, threshold, #' library(sf) #' #' # run -#' nc = sf::st_read(system.file("shape/nc.shp", package="sf")) -#' nc = sf::st_transform(nc, 5070) -#' pp = sf::st_sample(nc, size = 300) -#' pp = sf::st_as_sf(pp) -#' pp[["id"]] = seq(1, nrow(pp)) -#' sf::st_crs(pp) = "EPSG:5070" -#' ppb = sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) +#' nc <- sf::st_read(system.file("shape/nc.shp", package="sf")) +#' nc <- sf::st_transform(nc, 5070) +#' pp <- sf::st_sample(nc, size = 300) +#' pp <- sf::st_as_sf(pp) +#' pp[["id"]] <- seq(1, nrow(pp)) +#' sf::st_crs(pp) <- "EPSG:5070" +#' ppb <- sf::st_buffer(pp, nQuadSegs=180, dist = units::set_units(20, 'km')) #' -#' system.time({ppb_nc_aw = aw_covariates(ppb, nc, 'id')}) +#' system.time({ppb_nc_aw <- aw_covariates(ppb, nc, 'id')}) #' summary(ppb_nc_aw) #' #### Example of aw_covariates ends #### #' @export @@ -945,13 +958,13 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { #check_crs() ## distinguish numeric and nonnumeric columns - index_numeric = grep("(integer|numeric)", unlist(sapply(poly_weight, class))) + index_numeric <- grep("(integer|numeric)", unlist(sapply(poly_weight, class))) aw_covariates.terra = function(poly_in, poly_weight, id_poly_in = id_poly_in) { - poly_intersected = terra::intersect(poly_in, poly_weight) - poly_intersected[["area_segment_"]] = terra::expanse(poly_intersected) - poly_intersected = data.frame(poly_intersected) |> + poly_intersected <- terra::intersect(poly_in, poly_weight) + poly_intersected[["area_segment_"]] <- terra::expanse(poly_intersected) + poly_intersected <- data.frame(poly_intersected) |> dplyr::group_by(!!rlang::sym(id_poly_in)) |> dplyr::summarize(dplyr::across(is.numeric, ~stats::weighted.mean(., w = area_segment_))) |> @@ -959,11 +972,11 @@ aw_covariates <- function(poly_in, poly_weight, id_poly_in = "ID") { return(poly_intersected) } - class_poly_in = check_packbound(poly_in) - class_poly_weight = check_packbound(poly_weight) + class_poly_in <- check_packbound(poly_in) + class_poly_weight <- check_packbound(poly_weight) if (class_poly_in != class_poly_weight) { - class_poly_weight = switch_packbound(class_poly_weight) + class_poly_weight <- switch_packbound(class_poly_weight) } switch(class_poly_in, @@ -1012,7 +1025,7 @@ extract_with_buffer <- function( stopifnot(is.integer(qsegs)) if (!is.null(kernel)) { - extracted = extract_with_buffer.flat(points = points, + extracted <- extract_with_buffer.flat(points = points, surf = surf, radius = radius, id = id, @@ -1021,7 +1034,7 @@ extract_with_buffer <- function( return(extracted) } - extracted = extract_with_buffer.kernel(points = points, + extracted <- extract_with_buffer.kernel(points = points, surf = surf, radius = radius, id = id, @@ -1038,17 +1051,17 @@ extract_with_buffer.flat <- function( points, surf, radius, id, qsegs, func = mean, kernel = NULL, bandwidth = NULL ) { # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + bufs <- terra::buffer(points, width = radius, quadsegs = qsegs) # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) + bufs_extent <- terra::ext(bufs) + surf_cropped <- terra::crop(surf, bufs_extent) + name_surf_val <- names(surf) # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = + surf_at_bufs <- terra::extract(surf_cropped, bufs) + surf_at_bufs_summary <- surf_at_bufs |> dplyr::group_by(ID) |> - dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> + dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm = TRUE)) |> dplyr::ungroup() return(surf_at_bufs_summary) } @@ -1059,18 +1072,18 @@ extract_with_buffer.kernel <- function( points, surf, radius, id, qsegs, func = mean, kernel, bandwidth ) { # generate buffers - bufs = terra::buffer(points, width = radius, quadsegs = qsegs) + bufs <- terra::buffer(points, width = radius, quadsegs = qsegs) # crop raster - bufs_extent = terra::ext(bufs) - surf_cropped = terra::crop(surf, bufs_extent) - name_surf_val = names(surf) + bufs_extent <- terra::ext(bufs) + surf_cropped <- terra::crop(surf, bufs_extent) + name_surf_val <- names(surf) # TODO: kernel implementation # extract raster values - surf_at_bufs = terra::extract(surf_cropped, bufs) - surf_at_bufs_summary = + surf_at_bufs <- terra::extract(surf_cropped, bufs) + surf_at_bufs_summary <- surf_at_bufs |> dplyr::group_by(ID) |> dplyr::summarize(dplyr::across(dplyr::all_of(name_surf_val), ~mean, na.rm=T)) |> @@ -1098,23 +1111,23 @@ distribute_process <- function(grids, grid_id = NULL, fun, ...) { # subset using grids and grid_id if (!is.null(grid_id)) { if (is.character(grid_id)) { - grid_id_parsed = strsplit(grid_id, ":", fixed = TRUE)[[1]] - grid_ids = c(which(unique(grids[["CGRIDID"]]) == grid_id_parsed[1]), + grid_id_parsed <- strsplit(grid_id, ":", fixed = TRUE)[[1]] + grid_ids <- c(which(unique(grids[["CGRIDID"]]) == grid_id_parsed[1]), which(unique(grids[["CGRIDID"]]) == grid_id_parsed[2])) } if (is.numeric(grid_id)) { - grid_ids = unique(grids[["CGRIDID"]])[grid_id] + grid_ids <- unique(grids[["CGRIDID"]])[grid_id] } } - grids_target = grids[grid_ids,] - grids_target_list = split(grids_target, grids_target[["CGRIDID"]]) + grids_target <- grids[grid_ids,] + grids_target_list <- split(grids_target, grids_target[["CGRIDID"]]) - results_distributed = future.apply::future_lapply( + results_distributed <- future.apply::future_lapply( \(x, ...) { fun(...) }, grids_target_list, future.seed = TRUE) - results_distributed = do.call(rbind, results_distributed) + results_distributed <- do.call(rbind, results_distributed) return(results_distributed) } @@ -1129,7 +1142,7 @@ We finish by running commands that will document, build, and install the package devtools::document(".") devtools::test() devtools::build() -devtools::install(dependencies = F, build_vignettes = TRUE) +devtools::install(dependencies = FALSE, build_vignettes = TRUE) # devtools::check(document = FALSE) ``` \ No newline at end of file diff --git a/tools/slurm_test/merra1h_aero_extract_local_stars.r b/tools/slurm_test/merra1h_aero_extract_local_stars.r index 55daf243..2ab335df 100644 --- a/tools/slurm_test/merra1h_aero_extract_local_stars.r +++ b/tools/slurm_test/merra1h_aero_extract_local_stars.r @@ -1,8 +1,8 @@ library(sf) library(stars) library(dplyr) -sf_use_s2(F) -us_extent = +sf_use_s2(FALSE) +us_extent <- sf::st_bbox(c(xmin = -129.5, xmax = -61.1, ymin = 19.5, ymax = 51.8)) # terra::ext(us_extent) @@ -11,19 +11,19 @@ extract_with_buffer.flat <- function( points, surf, radius, id, qsegs, crs_projection = 5070, func = mean, kernel = NULL, bandwidth = NULL ) { # generate buffers - bufs = points |> + bufs <- points |> sf::st_transform(crs_projection) |> sf::st_buffer(dist = radius, nQuadSegs = qsegs) |> sf::st_transform(st_crs(points)) # crop raster - bufs_extent = sf::st_bbox(bufs, crs = st_crs(surf)) + bufs_extent <- sf::st_bbox(bufs, crs = st_crs(surf)) # surf_cropped = sf::st_crop(surf, bufs_extent) - surf_cropped = surf - name_surf_val = names(surf) + surf_cropped <- surf + name_surf_val <- names(surf) # extract raster values - surf_at_bufs = stars::st_extract(surf_cropped, bufs) + surf_at_bufs <- stars::st_extract(surf_cropped, bufs) return(surf_at_bufs) - surf_at_bufs_summary = + surf_at_bufs_summary <- surf_at_bufs |> st_drop_geometry() |> group_by(ID) |> @@ -32,12 +32,12 @@ extract_with_buffer.flat <- function( return(surf_at_bufs_summary) } -pathappend = "/Users/songi2/Documents/GitHub/Scalable_GIS/largedata/" -merraname = "MERRA2_400.tavg1_2d_aer_Nx.20220820.nc4" -pointname = "aqs-test-data.gpkg" +pathappend <- "/Users/songi2/Documents/GitHub/Scalable_GIS/largedata/" +merraname <- "MERRA2_400.tavg1_2d_aer_Nx.20220820.nc4" +pointname <- "aqs-test-data.gpkg" # pathappend = "/ddn/gs1/home/songi2/covartest/" -merra = stars::read_ncdf(paste(pathappend, merraname, sep= ""), proxy = TRUE) -point = sf::read_sf(paste(pathappend, pointname, sep = "")) |> +merra <- stars::read_ncdf(paste(pathappend, merraname, sep= ""), proxy = TRUE) +point <- sf::read_sf(paste(pathappend, pointname, sep = "")) |> st_transform(4326) ## I was confused with the notion of time info in SpatRaster. @@ -53,7 +53,7 @@ point = sf::read_sf(paste(pathappend, pointname, sep = "")) |> merra -merra_daily = stars::st_apply(merra, MARGIN = 1:2, FUN = mean) +merra_daily <- stars::st_apply(merra, MARGIN = 1:2, FUN = mean) # ok # timeindex = rep(seq_along(varnames(merra)), each = 24) @@ -65,7 +65,7 @@ merra_daily = stars::st_apply(merra, MARGIN = 1:2, FUN = mean) # merra_daily -targ_cols = c("BCCMASS", +targ_cols <- c("BCCMASS", "BCSMASS", "DMSCMASS", "DMSSMASS", @@ -83,13 +83,13 @@ targ_cols = c("BCCMASS", "SSSMASS", "SSCMASS25", "SSSMASS25") -st_crs(merra_daily_t) = "EPSG:4326" +st_crs(merra_daily_t) <- "EPSG:4326" -st_crs(merra_daily) = st_crs(point) -merra_daily_t = merra_daily[targ_cols][st_bbox(st_buffer(point, 3e4))] -merra_daily_t = st_as_stars(merra_daily_t) +st_crs(merra_daily) <- st_crs(point) +merra_daily_t <- merra_daily[targ_cols][st_bbox(st_buffer(point, 3e4))] +merra_daily_t <- st_as_stars(merra_daily_t) -extracted = extract_with_buffer.flat(point, merra_daily_t, "ID.Code", +extracted <- extract_with_buffer.flat(point, merra_daily_t, "ID.Code", radius = 20000, qsegs = 90L) extracted diff --git a/tools/tarballs/scomps_0.0.3.10042023.tar.gz b/tools/tarballs/scomps_0.0.3.10042023.tar.gz index 985b79de1e3f2475eff4cb27e057a411db827b1c..fc6fb7f95834551d6b007412582cf4d50a18cda6 100644 GIT binary patch literal 22672 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 literal 22596 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

OmQ~g0 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 z zpi`v(dg894|EWyUWa~Y(K{DR%?o#;=J_h~of&Raai%Z}5?4~7d7U~#DMGi3-$C_BF{hM|GV`h>7i>ly~5 zc}&vDU!l?y5KBUU1T|gI^Vrir2Kj@8Bb8&0x{tz3A8LFlbQodWn!O$+6h4T+FqnR8D0>B zc*%(3IA)oS-YwU z_@Js0_xqE`b0-5;6*dSOOJIL2FTuHvD@t&Da^hfUuagW1^F$7ko^~B?aE&uB@dp)g zt7e=kb)hNhp|?fFqqAht{rc;#+o4xCps-!%fbBc|J_ohpcPDEEc0U%+j8<74zL`EZ zX5|36fn-MBj`$c#D}@LjnXqlpY~(6~HbANF-n5WP6wGYAVNjVjfuZ_iRxgk2tg5?q^VaC9%j>4zevoI4 zTTtI+L(D7lHmX&~e|avAKivKU&%3)jnE!9B|9>#~KcD~ePG>NRBA^`@AQ5;HR#c1$ zdM3d?*tC5-_3u>v@9pgF+wy;JXK#NU|MNjUtyZf>M=X6&{~o4Y=xL`j4_X|22=Mpk zhxHnssX)P3u{c>I?MLv-X}qe}_&Sol$drbDAGP6uUR5>yr7s=;1^eRHpVaTi=)H0j zrt#v+UUTD_cWsqCg4qe>)$0(n5#UF@&Z&N_wy_}|qSHL{{#uI{0q8*IcqT<@gOVgb zhaEtaU^_@GE~5A~l%)e@bh}AFn&EhW{Gv&pjW0U0premu0vJp@i&!?D {D;B zMq?SbCi2`!jfg#~KYsq`NVHnwaY#-`O&AO)ocQGtK=EZ$99>Ee@K(<{fTue=a6U_K z>9aME1SjqSp#Fd-L9cAzU>F~ajZW}fAI(?f_o{AoV;u2ueMO2-b$tKI4EuUT$4EdT z&r~e0U&tJ-&|zfM?2A{N1L8nsfH+Y39}c=5PW}L28n5&KI7gN00HU(5QT$K`hUjxY zox4qPeo0mAc^007Ios?3(bOo`7*rANwGdxGcfM$5ZX*?MV z(EXp|fNl(WHJoFfkG4CTO%|^NA7o-Cr;y`);%Gh^s|%&6Wn;(y=6D{W%Q5DQ6Ydm* z9I{o?K_&KB--kzQB1%ga!1B#_0Ow?WHVrV2`nTvz2iE~&=)&v_tX&rqeZjK$RL}oR z{@)$wBs2vtevS*7`fnrut&IQJ*)H<`?X~^y58(egwxZ(R-N_pJTzgA2Y8pC%e;NVNAZ}T{YFp<)mX~7}wpnm4 zRf1L!?oQ}y}(HXSX_0Q3O>?$c7E