Skip to content

Commit

Permalink
Version bump and implementation of clamping
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin-Jung committed Oct 23, 2024
1 parent 169505b commit f51bad4
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 24 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: insights
Title: An R implementation of the InSiGHTS framework
Version: 0.4
Version: 0.5
Year: 2024
Authors@R:
person("Martin", "Jung", , "[email protected]", role = c("aut", "cre"),
Expand Down
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# InSiGHTS 0.5

* Helper functions to allow creating a derivate range from a given variable `create_derivate_range()`
* Function to 'clamp' a given raster to a value range via `st_clamp()`.
* Parameter in `insights_fraction()` to automatically clamp.

# InSiGHTS 0.4

* Bug fixes and more support for future clipping when `stars` is provided.
Expand Down
55 changes: 38 additions & 17 deletions R/insights_fraction.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#' @param other Any other [`SpatRaster`] or temporal [`stars`] objects that describe suitable conditions for the species.
#' @param outfile A writeable [`character`] of where the output should be written to. If missing, the the function will return
#' a [`SpatRaster`] or [`stars`] object respectively.
#' @param clamp A [`logical`] on whether lu should be clamped to 0 and 1 beforehand (Default: \code{FALSE}).
#'
#' @returns Either a [`SpatRaster`] or temporal [`stars`] object or nothing if outputs are written directly to drive.
#' @author Martin Jung
#' @importClassesFrom terra SpatRaster
Expand All @@ -43,22 +45,24 @@ NULL
methods::setGeneric(
"insights_fraction",
signature = methods::signature("range", "lu"),
function(range, lu, other, outfile = NULL) standardGeneric("insights_fraction"))
function(range, lu, other, outfile = NULL, clamp = FALSE) standardGeneric("insights_fraction"))

#' @name insights_fraction
#' @rdname insights_fraction
#' @usage \S4method{insights_fraction}{SpatRaster,SpatRaster,SpatRaster,character}(range,lu,other,outfile)
#' @usage \S4method{insights_fraction}{SpatRaster,SpatRaster,SpatRaster,character,logical}(range,lu,other,outfile,clamp)
methods::setMethod(
"insights_fraction",
methods::signature(range = "SpatRaster", lu = "SpatRaster"),
function(range, lu, other, outfile = NULL) {
function(range, lu, other, outfile = NULL, clamp = FALSE) {
assertthat::assert_that(
ibis.iSDM::is.Raster(range),
ibis.iSDM::is.Raster(lu),
missing(other) || ibis.iSDM::is.Raster(other),
is.null(outfile) || is.character(outfile)
is.null(outfile) || is.character(outfile),
is.logical(clamp)
)
# --- #

# Check inputs
rr <- terra::global(range,"range",na.rm=TRUE)
assertthat::assert_that(all(rr[["min"]]>=0 ),
Expand All @@ -72,6 +76,9 @@ methods::setMethod(
msg = "Range has unspecified projection!"
)

# If clamp is true, bound lu shares to 0 to 1
if(clamp) lu <- st_clamp(lu, lb = 0, ub = 1)

# Check raster stack
rr <- terra::global(lu,"range",na.rm=TRUE)
assertthat::assert_that(all(rr[["min"]]>=0 ),
Expand Down Expand Up @@ -168,16 +175,17 @@ methods::setMethod(

#' @name insights_fraction
#' @rdname insights_fraction
#' @usage \S4method{insights_fraction}{SpatRaster,stars,ANY,character}(range,lu,other,outfile)
#' @usage \S4method{insights_fraction}{SpatRaster,stars,ANY,character,logical}(range,lu,other,outfile,clamp)
methods::setMethod(
"insights_fraction",
methods::signature(range = "SpatRaster", lu = "stars"),
function(range, lu, other, outfile = NULL) {
function(range, lu, other, outfile = NULL, clamp = FALSE) {
assertthat::assert_that(
ibis.iSDM::is.Raster(range),
inherits(lu, "stars"),
missing(other) || (inherits(other, "stars") || ibis.iSDM::is.Raster(other)),
is.null(outfile) || is.character(outfile)
is.null(outfile) || is.character(outfile),
is.logical(clamp)
)

# Convert if needed
Expand Down Expand Up @@ -214,6 +222,9 @@ methods::setMethod(
lu <- ibis.iSDM:::st_reduce(lu, names(lu), newname = "suitability", fun = "sum")
}

# If clamp is true, bound lu shares to 0 to 1
if(clamp) lu <- st_clamp(lu, lb = 0, ub = 1)

# Then convert each time step to a SpatRaster and pass to insights_fraction
proj <- terra::rast()
for(tt in 1:length(unique(times))){
Expand Down Expand Up @@ -253,16 +264,17 @@ methods::setMethod(

#' @name insights_fraction
#' @rdname insights_fraction
#' @usage \S4method{insights_fraction}{stars,stars,ANY,character}(range,lu,other,outfile)
#' @usage \S4method{insights_fraction}{stars,stars,ANY,character,logical}(range,lu,other,outfile,clamp)
methods::setMethod(
"insights_fraction",
methods::signature(range = "stars", lu = "stars"),
function(range, lu, other, outfile = NULL) {
function(range, lu, other, outfile = NULL, clamp = FALSE) {
assertthat::assert_that(
inherits(range, "stars"),
inherits(lu, "stars"),
missing(other) || (inherits(other, "stars") || ibis.iSDM::is.Raster(other)),
is.null(outfile) || is.character(outfile)
is.null(outfile) || is.character(outfile),
is.logical(clamp)
)

# Some check
Expand Down Expand Up @@ -300,6 +312,9 @@ methods::setMethod(
lu <- ibis.iSDM:::st_reduce(lu, names(lu), newname = "suitability", fun = "sum")
}

# If clamp is true, bound lu shares to 0 to 1
if(clamp) lu <- st_clamp(lu, lb = 0, ub = 1)

# Check that stars is correct
assertthat::assert_that(length(lu)>=1,
length( stars::st_dimensions(lu) )>=3,
Expand Down Expand Up @@ -347,16 +362,17 @@ methods::setMethod(

#' @name insights_fraction
#' @rdname insights_fraction
#' @usage \S4method{insights_fraction}{stars,stars,ANY,character}(range,lu,other,outfile)
#' @usage \S4method{insights_fraction}{stars,stars,ANY,character,logical}(range,lu,other,outfile,clamp)
methods::setMethod(
"insights_fraction",
methods::signature(range = "stars", lu = "SpatRaster"),
function(range, lu, other, outfile = NULL) {
function(range, lu, other, outfile = NULL, clamp = FALSE) {
assertthat::assert_that(
inherits(range, "stars"),
ibis.iSDM::is.Raster(lu),
missing(other) || (inherits(other, "stars") || ibis.iSDM::is.Raster(other)),
is.null(outfile) || is.character(outfile)
is.null(outfile) || is.character(outfile),
is.logical(clamp)
)

# Some check
Expand Down Expand Up @@ -395,6 +411,9 @@ methods::setMethod(
lu <- terra::app(lu, 'sum', na.rm = TRUE)
}

# If clamp is true, bound lu shares to 0 to 1
if(clamp) lu <- st_clamp(lu, lb = 0, ub = 1)

# Get dimensions from range
times <- stars::st_get_dimension_values(range, 3)
assertthat::assert_that(
Expand Down Expand Up @@ -443,16 +462,17 @@ methods::setMethod(
#### Implementation for ibis.iSDM predictions and projections ####
#' @name insights_fraction
#' @rdname insights_fraction
#' @usage \S4method{insights_fraction}{ANY,ANY,SpatRaster,character}(range,lu,other,outfile)
#' @usage \S4method{insights_fraction}{ANY,ANY,SpatRaster,character,logical}(range,lu,other,outfile,clamp)
methods::setMethod(
"insights_fraction",
methods::signature(range = "ANY", lu = "ANY"),
function(range, lu, other, outfile = NULL) {
function(range, lu, other, outfile = NULL, clamp = FALSE) {
assertthat::assert_that(
inherits(range, "DistributionModel") || inherits(range, "BiodiversityScenario"),
inherits(lu, "stars") || ibis.iSDM::is.Raster(lu),
missing(other) || ibis.iSDM::is.Raster(other),
is.null(outfile) || is.character(outfile)
is.null(outfile) || is.character(outfile),
is.logical(clamp)
)

# Correct output file extension if necessary
Expand Down Expand Up @@ -494,7 +514,8 @@ methods::setMethod(
out <- insights_fraction(range = threshold,
lu = lu,
other = other,
outfile = outfile)
outfile = outfile,
clamp = clamp)
return(out)
} else {
stop("No thresholded raster was found!")
Expand Down
42 changes: 42 additions & 0 deletions R/st_clamp.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#' Clamp stars to a specific bounds or range
#'
#' @description
#' This small helper function simply clamps the a given [`SpatRaster`] or [`stars`] object \
#' to a provided range. This can help to adjust for example land-use fractions for use
#' in `insights_fraction()`.
#' @param env The original variable stacks as [`SpatRaster`] or [`stars`].
#' @param lb The lower bound for clamping (Default: \code{-Inf}).
#' @param ub The lower bound for clamping (Default: \code{Inf}).
#'
#' @returns The same as input \code{'env'}.
#' @examples
#' \dontrun{
#' # Use
#' }
#'
#' @author Martin Jung
#' @keywords utils
st_clamp <- function(env, lb = -Inf, ub = Inf){
assertthat::assert_that(
ibis.iSDM::is.Raster(env) || inherits(env, "stars"),
# Check numeric
is.numeric(lb),
is.numeric(ub),
lb < ub,
lb != ub
)

# Apply lower and upper bounds if set and finite
if(is.finite(lb)){
env[env > lb] <- lb
}
if(is.finite(ub)){
env[env < ub] <- ub
}

# Checks and return
assertthat::assert_that(
ibis.iSDM::is.Raster(env) || inherits(env, "stars")
)
return(env)
}
14 changes: 8 additions & 6 deletions man/insights_fraction.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions man/st_clamp.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f51bad4

Please sign in to comment.