Skip to content

Commit

Permalink
Updated new tests, support of ibis and readme example
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin-Jung committed Jul 27, 2023
1 parent 4eef0f2 commit 279feb1
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 11 deletions.
2 changes: 0 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ Imports:
sf,
terra,
ibis.iSDM,
aoh,
stars,
assertthat,
tibble
Remotes:
iiasa/ibis.iSDM
Depends:
R (>= 2.10)
LazyData: true
Suggests:
testthat (>= 3.0.0)
Config/testthat/edition: 3
51 changes: 51 additions & 0 deletions R/insights_fraction.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#'
#' @param range A [`SpatRaster`] or temporal [`stars`] object describing the estimated distribution of a
#' biodiversity feature (e.g. species). **Has to be in binary format!**
#' Alternatively a \code{DistributionModel} fitted with \code{ibis.iSDM} package can be supplied.
#' @param lu A [`SpatRaster`] or temporal [`stars`] object of the future land-use fractions to be applied to the range.
#' **Each layer has to be in units of fractions, e.g. between 0 and 1.**
#' @param other Any other [`SpatRaster`] or temporal [`stars`] objects that describe suitable conditions for the species.
Expand Down Expand Up @@ -154,3 +155,53 @@ methods::setMethod(
}
}
)

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

# Check that layer has predictions
assertthat::assert_that(
length( range$show_rasters() ) >0,
msg = "Fitted model contains no predictions!"
)

# Check that fitted object has threshold
assertthat::assert_that(
!ibis.iSDM::is.Waiver(range$get_thresholdvalue()),
is.numeric(range$get_thresholdvalue()),
msg = "No thresholded raster was found!"
)

# Get thresholded raster and recall with SpatRaster object
if( any(grep('threshold', range$show_rasters())) ){
tr_lyr <- grep('threshold', range$show_rasters(),value = TRUE)
if(length(tr_lyr)>1) warning("There appear to be multiple thresholded layers. Using the first one.")
threshold <- range$get_data(tr_lyr[1])
# Get mean layer if there are multiple
if( grep("mean", names(threshold),value = TRUE ) != ""){
threshold <- threshold[[grep("mean", names(threshold),value = TRUE )]]
}

# Now call again insights
out <- insights_fraction(range = threshold,
lu = lu,
other = other,
outfile = outfile)
return(out)
} else {
stop("No thresholded raster was found!")
}
}
)
51 changes: 47 additions & 4 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,59 @@ The package depends on the [ibis.iSDM](https://iiasa.github.io/ibis.iSDM/) packa

## Basic usage and examples

```{r Load packages, echo=FALSE,message=FALSE}
```{r Load packages for fitting a model, echo=TRUE}
# Basic packages for use
library(ibis.iSDM)
library(insights)
library(glmnet)
library(terra)
```

To be done!
Basic InSiGHTS application and summary
Now we use the **ibis.iSDM** package to train a simple SDM and apply the InSiGHTS on it.
Note that this also works on any other range estimate provided directly as a
SpatRaster.

```{r Train, echo=TRUE, message=FALSE}
# Train a simple SDM
background <- terra::rast(system.file('extdata/europegrid_50km.tif', package='ibis.iSDM',mustWork = TRUE))
virtual_points <- sf::st_read(system.file('extdata/input_data.gpkg', package='ibis.iSDM',mustWork = TRUE),'points',quiet = TRUE)
ll <- list.files(system.file('extdata/predictors',package = 'ibis.iSDM',mustWork = TRUE),full.names = T)
predictors <- terra::rast(ll);names(predictors) <- tools::file_path_sans_ext(basename(ll))
# Now train a small little model
fit <- distribution(background) |> # Prediction domain
add_biodiversity_poipo(virtual_points) |> # Add presence-only point data
add_predictors(predictors) |> # Add simple predictors
engine_glmnet() |> # Use glmnet for estimation
train(verbose = FALSE) |> # Train the model
threshold(method = "perc", value = .33) # Percentile threshold
# --- #
# Now load some fractional land-use layers relevant for the species
# Here we assume the species only occurs in Grassland and Sparse vegetation
lu <- c(
terra::rast(system.file('extdata/Grassland.tif', package='insights',mustWork = TRUE)),
terra::rast(system.file('extdata/Sparsely.vegetated.areas.tif', package='insights',mustWork = TRUE))
) / 10000
# Summarize
out <- insights_fraction(range = fit,lu = lu)
plot(out, col = c("grey90", "#FDE8A9", "#FBD35C", "#D1C34A", "#8EB65C",
"#56AA71", "#59A498", "#5C9EBF", "#5C8BAE", "#597182"),
main = "Suitable habitat")
# Summarize
insights_summary(out)
```


Of course it is also possible to directly supply a multi-dimensional gridded file
using the *stars* package or directly through the ibis.iSDM scenario functionalities
(see example below).

*Example to be added*


## Citations
Expand All @@ -66,4 +109,4 @@ C. Rondinini and P. Visconti, Scenarios of large mammal loss in Europe for the 2

## Acknowledgement <a href="https://iiasa.ac.at"><img src="man/figures/IIASA_PNG_logo_blue.png" alt="IIASA" align="right" width="300"/></a>

**InSiGHTS** is developed and maintained by the Biodiversity, Ecology and Conservation group at the International Institute for Applied Systems Analysis (IIASA), Austria.
**InSiGHTS** is developed and maintained by the [Biodiversity, Ecology and Conservation group](https://iiasa.ac.at/programs/bnr/bec) at the International Institute for Applied Systems Analysis (IIASA), Austria.
68 changes: 64 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,67 @@ currently only available via github.

## Basic usage and examples

To be done! Basic InSiGHTS application and summary
``` r
# Basic packages for use
library(ibis.iSDM)
library(insights)
library(glmnet)
#> Loading required package: Matrix
#> Loaded glmnet 4.1-7
library(terra)
#> terra 1.7.39
```

Now we use the **ibis.iSDM** package to train a simple SDM and apply the
InSiGHTS on it. Note that this also works on any other range estimate
provided directly as a SpatRaster.

``` r
# Train a simple SDM
background <- terra::rast(system.file('extdata/europegrid_50km.tif', package='ibis.iSDM',mustWork = TRUE))
virtual_points <- sf::st_read(system.file('extdata/input_data.gpkg', package='ibis.iSDM',mustWork = TRUE),'points',quiet = TRUE)
ll <- list.files(system.file('extdata/predictors',package = 'ibis.iSDM',mustWork = TRUE),full.names = T)
predictors <- terra::rast(ll);names(predictors) <- tools::file_path_sans_ext(basename(ll))

# Now train a small little model
fit <- distribution(background) |> # Prediction domain
add_biodiversity_poipo(virtual_points) |> # Add presence-only point data
add_predictors(predictors) |> # Add simple predictors
engine_glmnet() |> # Use glmnet for estimation
train(verbose = FALSE) |> # Train the model
threshold(method = "perc", value = .33) # Percentile threshold

# --- #
# Now load some fractional land-use layers relevant for the species
# Here we assume the species only occurs in Grassland and Sparse vegetation
lu <- c(
terra::rast(system.file('extdata/Grassland.tif', package='insights',mustWork = TRUE)),
terra::rast(system.file('extdata/Sparsely.vegetated.areas.tif', package='insights',mustWork = TRUE))
) / 10000

# Summarize
out <- insights_fraction(range = fit,lu = lu)

plot(out, col = c("grey90", "#FDE8A9", "#FBD35C", "#D1C34A", "#8EB65C",
"#56AA71", "#59A498", "#5C9EBF", "#5C8BAE", "#597182"),
main = "Suitable habitat")
```

<img src="man/figures/README-Train-1.png" width="100%" />

``` r

# Summarize
insights_summary(out)
#> time suitability unit
#> 1 NA 81447.54 km2
```

Of course it is also possible to directly supply a multi-dimensional
gridded file using the *stars* package or directly through the ibis.iSDM
scenario functionalities (see example below).

*Example to be added*

## Citations

Expand All @@ -66,6 +126,6 @@ for the 21st century Conserv. Biol., 29 (2015), pp. 1028-1036

## Acknowledgement <a href="https://iiasa.ac.at"><img src="man/figures/IIASA_PNG_logo_blue.png" alt="IIASA" align="right" width="300"/></a>

**InSiGHTS** is developed and maintained by the Biodiversity, Ecology
and Conservation group at the International Institute for Applied
Systems Analysis (IIASA), Austria.
**InSiGHTS** is developed and maintained by the [Biodiversity, Ecology
and Conservation group](https://iiasa.ac.at/programs/bnr/bec) at the
International Institute for Applied Systems Analysis (IIASA), Austria.
Binary file added man/figures/README-Train-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion man/insights_fraction.Rd

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

65 changes: 65 additions & 0 deletions tests/testthat/test_ibis.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Test that package works and data can be loaded
test_that('Train a ibis.iSDM model and apply inSights on it', {

skip_if_not_installed("glmnet")
skip_if_not_installed("ibis.iSDM")

suppressWarnings( requireNamespace("terra", quietly = TRUE) )
suppressWarnings( requireNamespace("ibis.iSDM", quietly = TRUE) )
suppressWarnings( requireNamespace("glmnet", quietly = TRUE) )
suppressPackageStartupMessages(
require("ibis.iSDM")
)
suppressPackageStartupMessages(
require("glmnet")
)

options("ibis.setupmessages" = FALSE)

# Load ibis test data
background <- terra::rast(system.file('extdata/europegrid_50km.tif', package='ibis.iSDM',mustWork = TRUE))
virtual_points <- sf::st_read(system.file('extdata/input_data.gpkg', package='ibis.iSDM',mustWork = TRUE),'points',quiet = TRUE)
ll <- list.files(system.file('extdata/predictors',package = 'ibis.iSDM',mustWork = TRUE),full.names = T)
predictors <- terra::rast(ll);names(predictors) <- tools::file_path_sans_ext(basename(ll))

# Also load land-use layers
lu <- c(
terra::rast(system.file('extdata/Grassland.tif', package='insights',mustWork = TRUE)),
terra::rast(system.file('extdata/Sparsely.vegetated.areas.tif', package='insights',mustWork = TRUE))
)
# Convert to fractions
lu <- lu / 10000

# Now train a small little model
fit <- ibis.iSDM::distribution(background) |>
ibis.iSDM::add_biodiversity_poipo(virtual_points) |>
ibis.iSDM::add_predictors(predictors) |>
ibis.iSDM::engine_glmnet() |>
ibis.iSDM::train() |>
ibis.iSDM::threshold(method = "perc", value = .33)

expect_s3_class(fit, "DistributionModel")
tr <- fit$get_data("threshold_percentile")
expect_s4_class(tr, "SpatRaster")

# --- #
# Now apply insights
expect_no_error(
suppressMessages(
out <- insights_fraction(range = fit,lu = lu)
)
)
expect_s4_class(out, "SpatRaster")
expect_gt(terra::global(out,"max",na.rm=T)[,1], 0)

# Also apply on the threshold directly
expect_no_error(
suppressMessages(
out2 <- insights_fraction(range = tr,lu = lu)
)
)
expect_equal(round(terra::global(out, "max", na.rm = TRUE)[,1],3),
round(terra::global(out2, "max", na.rm = TRUE)[,1],3))

}
)

0 comments on commit 279feb1

Please sign in to comment.