Type: | Package |
Title: | A Sky Illuminance Location Tracker |
Version: | 1.0 |
Maintainer: | Koen Hufkens <koen.hufkens@gmail.com> |
Description: | Calculate geolocations by light using template matching. The routine uses a calibration free optimization of a sky illuminance model to determine locations robustly using a template matching approach, as described by Ekstrom (2004) https://nipr.repo.nii.ac.jp/records/2496, and behaviourly informed constraints (step-selection). |
URL: | https://github.com/bluegreen-labs/skytrackr |
BugReports: | https://github.com/bluegreen-labs/skytrackr/issues |
Depends: | R (≥ 4.2) |
License: | AGPL-3 |
Encoding: | UTF-8 |
LazyData: | true |
ByteCompile: | true |
RoxygenNote: | 7.3.2 |
Imports: | skylight, circular, BayesianTools, cli, utils, memoise, stats, rlang, sf, terra, geosphere, tidyr, dplyr, ggplot2, plotly, patchwork, mapview |
Suggests: | knitr, rmarkdown, bookdown, covr, testthat, multidplyr |
VignetteBuilder: | knitr |
NeedsCompilation: | no |
Packaged: | 2025-10-04 17:34:31 UTC; khufkens |
Author: | Koen Hufkens |
Repository: | CRAN |
Date/Publication: | 2025-10-08 19:50:08 UTC |
Migrate Technology Ltd demo data
Description
Demo data for a single day of Common swift light logger data as read from a Migrate Technology Ltd .lux file using stk_read_lux().
Usage
cc876
Format
DataFrame
- logger
logger ID
- date
date
- date_time
date and time
- hour
decimal hour
- lux
light levels in lux
Details
The format is consistent with what is required by the skytrackr() routine.
Land area polygon
Description
Vector polygon of world land areas to constrain model optimization.
Usage
land
Format
sf
- MULTIPOLYGON
sf multipolygon
Log likelihood cost function
Description
Main cost function used during optimization, combining both the fit of the illuminance data with the step-selection function.
Usage
likelihood(par, data, model, loc, roi, step_selection, ...)
Arguments
par |
A vector of parameter values, including one for the uncertainty on the target values. |
data |
A nested data structure with validation data included. |
model |
A model to run with data and par settings. |
loc |
The previous modeled step location. |
roi |
A region of interest with valid sampling locations. |
step_selection |
A step selection function on the distance of a proposed move. |
... |
extra arguments to pass to the function |
Value
The single log-likelihood cost of a proposed parameter set.
Simulate illuminance value
Description
Calculates log(lux) values for a give location, date, time and sky conditions.
Usage
log_lux(par, data, ...)
Arguments
par |
Three parameters specifying the illuminance model. |
data |
A data frame with the required drivers for the illuminance model. |
... |
optional other parameters to forward |
Value
Sky illuminance as log(lux).
Read lux and deg files
Description
This function is wrapped by the 'stk_read_lux()' function.
Usage
read_deg_lux(file, verbose = TRUE)
Arguments
file |
A lux or deg file. |
verbose |
provide detailed feedback |
Value
A skytrackr data frame with logger data.
Sky (illuminance) location estimation routine
Description
Skytrack compares geolocator based light measurements in lux with those modelled by the sky illuminance model of Janiczek and DeYoung (1987).
Usage
skytrackr(
data,
start_location,
tolerance = 1500,
range = c(0.09, 148),
scale = log(c(1e-05, 50)),
control = list(sampler = "DEzs", settings = list(burnin = 250, iterations = 3000,
message = FALSE)),
mask,
step_selection,
plot = TRUE,
verbose = TRUE
)
Arguments
data |
A skytrackr data frame. |
start_location |
A start location of logging as a vector of latitude and longitude |
tolerance |
Tolerance distance on the search window for optimization, given in km (left/right, top/bottom). Sets a hard limit on the search window regardless of the step selection function used. |
range |
Range of values to consider during processing, should be provided in lux c(min, max) or the equivalent if non-calibrated. |
scale |
Scale / sky condition factor, by default covering the skylight() range of 1-10 (from clear sky to extensive cloud coverage) but can be extended for more flexibility to account for coverage by plumage, note that in case of non-physical accurate lux measurements values can have a range starting at 0.0001 (a multiplier instead of a divider). Values need to be provided on a log scale (default = log(c(0.00001, 50))) |
control |
Control settings for the Bayesian optimization, generally should not be altered (defaults to a Monte Carlo method). For detailed information I refer to the BayesianTools package documentation. |
mask |
Mask to constrain positions to land |
step_selection |
A step selection function on the distance of a proposed move, step selection is specified on distance (in km) basis. |
plot |
Plot a map during location estimation (updated every seven days) |
verbose |
Give feedback including a progress bar (TRUE or FALSE) |
Details
Model fits are applied by default to values up to sunrise or after sunset only as most critical to the model fit (capturing daylength, i.e. latitude and the location of the diurnal pattern - longitudinal displacement).
Value
A data frame with location estimate, their uncertainties, and ancillary model parameters useful in quality control.
Examples
# define land mask with a bounding box
# and an off-shore buffer (in km), in addition
# you can specify the resolution of the resulting raster
mask <- stk_mask(
bbox = c(-20, -40, 60, 60), #xmin, ymin, xmax, ymax
buffer = 150, # in km
resolution = 0.5 # map grid in degrees
)
# define a step selection distribution/function
ssf <- function(x, shape = 0.9, scale = 100, tolerance = 1500){
norm <- sum(stats::dgamma(1:tolerance, shape = shape, scale = scale))
prob <- stats::dgamma(x, shape = shape, scale = scale) / norm
}
# estimate locations
locations <- cc876 |> skytrackr(
plot = TRUE,
mask = mask,
step_selection = ssf,
start_location = c(50, 4),
control = list(
sampler = 'DEzs',
settings = list(
iterations = 10, # change iterations
message = FALSE
)
)
)
Cluster geolocator co-variates
Description
Uses k-means and hierarchical clustering to group geolocator covariates into consistent groups for visual analysis
Usage
stk_cluster(df, k = 2, method = "kmeans")
Arguments
df |
A skytrackr data frame. |
k |
The number of k-means/hierarchical clusters to consider. |
method |
The method to use, "kmeans" (default), "hclust" can be set. |
Value
The original data frame with attached cluster labels.
Fit illuminance (lux) profile
Description
Fits a simulated lux profile to observed light logger data to estimate locations (parameters).
Usage
stk_fit(data, roi, loc, scale, control, step_selection)
Arguments
data |
A skytrackr data frame |
roi |
A region of interest defined by a dynamic bounding box (set via the tolerance value and relative to the previous step) |
loc |
The location of the previous step |
scale |
Scale / sky condition factor covering the skylight() range of 1-10 (from clear sky to extensive cloud coverage) but can be extended for more flexibility to account for coverage by plumage, note that in case of non-physical accurate lux measurements values can have a range starting at 0.0001 (a multiplier instead of a divider). |
control |
Control settings for the Bayesian optimization, generally should not be altered (defaults to a Monte Carlo method). For detailed information I refer to the BayesianTools package documentation. |
step_selection |
A step selection function on the distance of a proposed move, step selection is specified on distance (in km) basis. |
Value
An estimated illuminance based location (and its uncertainties).
Plot skytrackr results
Description
Create a map of estimated locations as a static or dynamic map.
Usage
stk_map(df, bbox, start_location, roi, dynamic = FALSE)
Arguments
df |
A data frame with locations produced with the skytrackr() function |
bbox |
A geographic bounding box provided as a vector with the format xmin, ymin, xmax, ymax. |
start_location |
A start location as lat/lon to indicate the starting position of the track (optional) |
roi |
A region of interest under consideration, only used in plots during optimization |
dynamic |
Option to create a dynamic interactive graph rather than a static plot. Both the path as the locations are shown. The size of the points is proportional to the latitudinal uncertainty, while equinox windows are marked with red points. (default = FALSE) |
Value
A ggplot map of tracked locations or mapview dynamic overview.
Examples
# define land mask with a bounding box
# and an off-shore buffer (in km), in addition
# you can specify the resolution of the resulting raster
mask <- stk_mask(
bbox = c(-20, -40, 60, 60), #xmin, ymin, xmax, ymax
buffer = 150, # in km
resolution = 0.5 # map grid in degrees
)
# define a step selection distribution/function
ssf <- function(x, shape = 0.9, scale = 100, tolerance = 1500){
norm <- sum(stats::dgamma(1:tolerance, shape = shape, scale = scale))
prob <- stats::dgamma(x, shape = shape, scale = scale) / norm
}
# estimate locations
locations <- cc876 |> skytrackr(
plot = TRUE,
mask = mask,
step_selection = ssf,
start_location = c(50, 4),
control = list(
sampler = 'DEzs',
settings = list(
iterations = 10, # change iterations
message = FALSE
)
)
)
#----- actual plotting routines ----
# static plot, with required bounding box
locations |> stk_map(bbox = c(-20, -40, 60, 60))
# dynamic plot
locations |> stk_map(dynamic = TRUE)
Generate a land surface mask
Description
Returns a (buffered) land mask to constrain potential model results.
Usage
stk_mask(buffer = 0, resolution = 1, bbox, sf = FALSE)
Arguments
buffer |
The buffer distance from land areas (in km, default = 0 excluding all water bodies). |
resolution |
The resolution of the spatial grid in degrees, when exporting as a terra SpatRaster (default = 1). |
bbox |
A bounding box of the mask to constrain the estimated location parameter space. |
sf |
Return the land mask as an 'sf' polygon, not a rasterized map for. use in map plotting, not used for processing (default = FALSE) |
Value
A buffered land mask as an 'sf' or 'terra' map object.
Examples
# define land mask with a bounding box
# and an off-shore buffer (in km), in addition
# you can specifiy the resolution of the resulting raster
mask <- stk_mask(
bbox = c(-20, -40, 60, 60), #xmin, ymin, xmax, ymax
buffer = 150, # in km
resolution = 0.5 # map grid in degrees
)
Plot seasonal profiles
Description
Provides static or dynamic (plotly) seasonal profile plot
Usage
stk_profile(data, logger, range = c(0, 1e+05), center = "day", plotly = FALSE)
Arguments
data |
A skytrackr compatible data frame. |
logger |
The logger to plot. |
range |
The light range to plot. |
center |
Set the data to center data on "day" or "night" (default = "day"). |
plotly |
Logical, convert to dynamic plotly plot or not (default = FALSE) |
Value
A static or dynamic graph of light levels for a given logger.
Read Swiss Ornithology institute GLF files
Description
Read Swiss Ornithology institute files in the '.glf' and re-formats them to a skytrackr compatible format.
Usage
stk_read_glf(files, verbose = TRUE)
Arguments
files |
A '.glf' file or list of '.glf' files with light level values. |
verbose |
provide detailed feedback |
Value
A skytrackr compatible data frame for use in further location estimation.
Examples
## Not run:
df <- stk_read_glf("your_SOI_glf_file.glf")
## End(Not run)
Read Migrate Technology .lux files
Description
Read Migrate Technology Ltd. '.lux' files and re-formats them to a skytrackr compatible format.
Usage
stk_read_lux(files, verbose = TRUE)
Arguments
files |
A '.lux' file or list of '.lux' files with light level values |
verbose |
provide detailed feedback |
Value
A skytrackr compatible data frame for use in further location estimation.
Examples
# read in the demo lux file
df <- stk_read_lux(
system.file("extdata/cc876.lux", package="skytrackr")
)
Twilight screening routine
Description
Removes poor quality data based on twilight heuristics. Allows for quick screening of data containing "false" twilight values.
Usage
stk_screen_twl(df, threshold = 1.5, dips = 3, step = 100, filter = TRUE)
Arguments
df |
A skytrackr data frame. |
threshold |
A twilight threshold (default = 1.5). |
dips |
The allowed number of interruptions during a daylight profile below the twilight threshold before flagging as a poor quality "suspect" day. |
step |
A threshold of the allowed step change in illuminance values between the twilight value and the preceding one. Large jumps and the lack of a smooth transition suggest a false twilight (bird leaving a dark nest site long after or long before dawn or dusk). |
filter |
Logical if to return data pre-filtered, removing all poor quality days or false twilight ones (default = TRUE) |
Value
A skytrackr data frame with poor twilight quality days removed and dusk and dawn timings marked (data is returned as a long format, not a wide format).
Examples
# set demo values artificially low as a demonstration
library(dplyr)
df <- cc876 |>
mutate(
value = ifelse(
date_time > "2021-08-15 05:00:00" & date_time < "2021-08-15 12:00:00",
0.1,
value)
)
# screen values and remove them (filter = TRUE)
df <- df |> stk_screen_twl(filter = TRUE)