This approach supsersedes the functionality of the QPAD package (but estimates are still stored in the package).
This repository contains geospatial layers that are consistent with QPAD v3 estimates.
We discovered and fixed a bug in the code for calculating QPAD offsets in late March 2025 that dated back approximately ten years. The bug was within the code used to adjust time zones and therefore affects QPAD offsets used for
- species with time since sunrise in the top model and
- in areas outside the mountain time zone.
Since QPAD offsets only adjust the intercept of model estimates, this bug will only affect model outcomes if
- models were built for density or population estimates per se, or
- models were compared or integrated across time zones. Relative patterns of density (e.g., habitat coefficients) within time zones should be unaffected.
If you have been affected by this bug, please see the BAM QPAD correction repository for further details or email [email protected] for assistance.
Install R then get the R dependencies:
if (!requireNamespace("QPAD")) {
if (!requireNamespace("remotes"))
install.packages("remotes")
remotes::install_github("psolymos/QPAD")
}
if (!requireNamespace("sp"))
install.packages("sp")
if (!requireNamespace("maptools"))
install.packages("maptools")
if (!requireNamespace("raster"))
install.packages("raster")
if (!requireNamespace("intrval"))
install.packages("intrval")
Download or clone this GitHub repository:
git clone https://https://github.com/borealbirds/qpad-offsets.git
Then set your working directory to the project directory (qpad-offsets
).
Easiest, if using RStudio, is to double click on the offset.Rproj
file
which will open up the project and set the working directory.
An example can be found in the
index.R
file.
## load packages
library(QPAD)
library(suntools)
library(intrval)
library(terra)
## load v3 estimates
load_BAM_QPAD(version = 3)
if (getBAMversion() != "3")
stop("This script requires BAM version 3")
## read raster data
rlcc <- rast("./data/lcc.tif")
rtree <- rast("./data/tree.tif")
rtz <- rast("./data/utcoffset.tif")
rd1 <- rast("./data/seedgrow.tif")
crs <- crs(rtree)
## source functions
source("functions.R")
The date/time and coordinate specifications will make sure that required predictors are extracted in the way that match the estimates.
- the species ID need to be a single 4-letter AOU code (see
getBAMspecieslist()
for a full list) - coordinates and time: can be single values or vectors (shorter objects recycled)
dt
: date, ISO 8601 in YYYY-MM-DD (0-padded)tm
: time, ISO 8601 in hh:mm (24 hr clock, 0-padded)lat
: latitude [WGS84 (EPSG: 4326)]lon
: longitude [WGS84 (EPSG: 4326)]
- methods descriptors: can be single value or vector (recycled as needed)
dur
: duration in minutesdis
: distance in meters
## species of interest
spp <- "OVEN"
## date and time
## https://en.wikipedia.org/wiki/ISO_8601
dt <- "2019-06-07" # ISO 8601 in YYYY-MM-DD (0-padded)
tm <- "05:20" # ISO 8601 in hh:mm (24 hr clock, 0-padded)
## spatial coordinates
lon <- -113.4938 # longitude WGS84 (EPSG: 4326)
lat <- 53.5461 # latitude WGS84 (EPSG: 4326)
## point count duration
## and truncation distance (Inf for unlimited)
dur <- 10 # minutes
dis <- 100 # meters
This object can be reused for multiple species:
x <- make_x(dt, tm, lon, lat, dur, dis)
str(x)
##'data.frame': 1 obs. of 8 variables:
## $ TSSR : num 0.0089
## $ JDAY : num 0.43
## $ DSLS : num 0.14
## $ LCC2 : Factor w/ 2 levels "Forest","OpenWet": 2
## $ LCC4 : Factor w/ 4 levels "DecidMixed","Conif",..: 3
## $ TREE : num 2.55
## $ MAXDUR: num 10
## $ MAXDIS: num 1
A
is the known or estimated area of survey, p
is availability given presence, q
is detectability given avaibalility.
o <- make_off(spp, x)
str(o)
##'data.frame': 1 obs. of 5 variables:
## $ p : num 0.991
## $ q : num 0.562
## $ A : num 3.14
## $ correction: num 1.75
## $ offset : num 0.559
NOTE: offset
is log(correction)
, correction
= A*p*q
, thus offset=log(A) + log(p) + log(q)
.
Use a loop over multiple species:
SPP <- getBAMspecieslist()
OFF <- matrix(0, nrow(x), length(SPP))
rownames(OFF) <- rownames(x) # your survey IDs here
colnames(OFF) <- SPP
for (spp in SPP) {
cat(spp, "\n")
flush.console()
o <- make_off(spp, x)
OFF[,spp] <- o$offset
}
str(OFF)
##num [1, 1:151] 0.1365 0.9699 0.0643 0.5917 -0.3132 ...
## - attr(*, "dimnames")=List of 2
## ..$ : chr "17"
## ..$ : chr [1:151] "ALFL" "AMCR" "AMGO" "AMPI" ...
This repository originates from the archived https://github.com/ABbiodiversity/recurring project.