# Running ecological niche models
# Bruno Carvalho
# GHR Tutorial 23 Jun 2023

# Load packages
#library(sf)
library(raster)
library(dismo)
library(readr)
library(dplyr)

# load harmonized dataset
df <- read_csv("./output/01_harmonized_data.csv")

# load predictors dataset
predictors <- stack("./output/01_predictors.grd")

#### 1. Split data into train and test sets ####

# create ID column in df
df$id <- 1:nrow(df)

# split 70% as training set and 30% as test set

# presences
prestrain <- df %>% 
  filter(pa == 1) %>% 
  sample_frac(0.70)

prestest <- df %>% 
  filter(pa == 1) %>% 
  anti_join(prestrain, by = 'id')

# absences
abstrain <- df %>% 
  filter(pa == 0) %>% 
  sample_frac(0.70)

abstest <- df %>% 
  filter(pa == 0) %>% 
  anti_join(abstrain, by = 'id')

# build separate data frames for train and test
train_df <- bind_rows(prestrain, abstrain)
test_df <- bind_rows(prestest, abstest)


#### 2. Run and evaluate models ####

# define model formula
model <- pa ~ bio1 + bio12 + bio15 + bio4

# bioclim
bc <- bioclim(predictors, select(prestrain, lon, lat))
evbc <- evaluate(select(prestest, lon, lat), 
                 select(abstest, lon, lat),
                 bc, predictors)
evbc

# glm - logistic
lr <- glm(model, family=binomial(link="logit"), data=train_df)
evlr <- evaluate(select(prestest, lon, lat), 
                 select(abstest, lon, lat),
                 lr, predictors)

evlr

# maxent
mx <- maxent(predictors, as.data.frame(select(prestrain, lon, lat)), a=as.data.frame(select(abstrain, lon, lat)))
evmx <- evaluate(select(prestest, lon, lat), 
                 select(abstest, lon, lat),
                 mx, predictors)
evmx

# optional: maxent with random background points
#mx2 <- maxent(predictors, as.data.frame(select(prestrain, lon, lat)), nbg = 10000)

#evmx2 <- evaluate(select(prestest, lon, lat), 
#                 select(abstest, lon, lat),
#                 mx2, predictors)
#evmx2


#### 3. Predict into study area ####

# bioclim
out_bc <- predict(predictors, bc, progress='text')

# logistic regression
out_lr <- predict(predictors, lr, progress='text')

# maxent
out_mx <- predict(predictors, mx, progress='text')


par(mfrow=c(2,2))
plot(out_mx, main = "bioclim")
points(prestest$lon, prestest$lat, pch = 20, cex=0.5)

plot(out_lr, main = "GLM (logit)")
points(prestest$lon, prestest$lat, pch = 20, cex=0.5)

plot(out_mx, main = "maxent")
points(prestest$lon, prestest$lat, pch = 20, cex=0.5)

plot(x = 0:10, y = 0:10, ann = F,bty = "n",type = "n",
     xaxt = "n", yaxt = "n")
text(x = 5,y = 5,"Model outputs in their\n native continuous outputs")


# binary outputs
out_bc_bin <- out_bc >= threshold(evbc, "spec_sens")
plot(out_bc_bin, main = "bioclim")

out_lr_bin <- out_lr >= threshold(evlr, "spec_sens")
plot(out_lr_bin, main = "GLM (logit)")

out_mx_bin <- out_mx >= threshold(evmx, "spec_sens")
plot(out_mx_bin, main = "maxent")
