Getting Started with glscalibrator

glscalibrator authors

2025-11-24

Introduction

Global Location Sensors (GLS) are widely used to track animal movements over long periods. However, processing GLS data has traditionally been a manual, time-consuming process requiring:

  1. Manual identification of calibration periods
  2. Custom scripting for each study
  3. Individual processing of each device
  4. Manual quality control

glscalibrator automates this entire workflow, allowing you to process entire datasets with a single command.

Installation

# Install from GitHub
# install.packages("devtools")
devtools::install_github("fabbiologia/glscalibrator")

# Load the package
library(glscalibrator)

Basic Workflow

1. Organize Your Data

For this vignette we’ll rely on the bundled example data that ships with the package, but the same structure applies to your own deployments. The examples live in:

system.file("extdata", package = "glscalibrator")

2. Run Batch Calibration

The main function calibrate_gls_batch() handles everything:

results <- calibrate_gls_batch(
  data_dir = system.file("extdata", package = "glscalibrator"),
  output_dir = "data/processed/calibration",
  colony_lat = 27.85178,    # Your colony latitude
  colony_lon = -115.17390,  # Your colony longitude
  light_threshold = 2,      # Light threshold in lux
  verbose = TRUE
)

3. Check Results

# Summary statistics for all birds
print(results$summary)

# Processing log (successes and failures)
print(results$processing_log)

# Access individual bird positions
bird_data <- results$results$BW154_05Jul24_225805
head(bird_data)

What Gets Created

After running calibrate_gls_batch(), you’ll have:

Data Files

Figures

Advanced Features

Excluding Equinox Periods

Light-based geolocation is unreliable near equinoxes. You can exclude these periods:

# Define equinox exclusion windows
equinoxes <- list(
  c("2024-08-24", "2024-10-23"),  # Autumn
  c("2024-02-19", "2024-04-19"),  # Spring
  c("2023-08-24", "2023-10-23")   # Previous year
)

results <- calibrate_gls_batch(
  data_dir = "data/raw/birds",
  output_dir = "data/processed/calibration",
  colony_lat = 27.85,
  colony_lon = -115.17,
  exclude_equinoxes = equinoxes
)

Customizing Thresholds

results <- calibrate_gls_batch(
  data_dir = "data/raw/birds",
  output_dir = "data/processed/calibration",
  colony_lat = 27.85,
  colony_lon = -115.17,
  light_threshold = 3,      # Higher threshold
  min_positions = 20,       # Require more positions
  create_plots = FALSE      # Skip plot generation
)

# metadata table is also exported for programmatic access
glscalibrator_example_metadata

Step-by-Step Processing

If you need more control, you can use the individual functions:

1. Read Light Data

light_data <- read_lux_file(gls_example("W086"))
head(light_data)

2. Auto-Detect Calibration Period

calib_period <- auto_detect_calibration(
  light_data,
  colony_lat = 27.85178,
  colony_lon = -115.17390,
  threshold = 2
)

print(calib_period)
# $start
# [1] "2024-07-05 22:58:05 UTC"
# $end
# [1] "2024-07-07 22:58:05 UTC"
# $twilights
# [1] 5

3. Detect Twilights

twilights <- detect_twilights(light_data, threshold = 2)
head(twilights)

4. Filter Twilights

twilights_clean <- filter_twilights(
  twilights,
  light_data = light_data,
  threshold = 2,
  strict = TRUE
)

5. Estimate the Sun Elevation

calib_result <- estimate_sun_elevation(
  twilight = twilights_clean$Twilight,
  rise = twilights_clean$Rise,
  lon = -115.17390,
  lat = 27.85178
)

zenith <- calib_result["z1"]
print(paste("Zenith angle:", round(zenith, 2), "degrees"))

Understanding the Output

Calibration Summary

# Example calibration_summary.csv structure:
# bird_id              zenith  sun_elevation  n_twilights_calib  n_positions  hemisphere_check
# BW154_05Jul24_225805  98.74       -8.74              5              143     CORRECT (Western)
# BW157_05Jul24_231215  98.39       -8.39              5              274     CORRECT (Western)

Key columns: - zenith: Calculated sun elevation angle for this device - n_twilights_calib: Twilights used for calibration - n_positions: Final number of position estimates - hemisphere_check: Quality control (should match your study area)

Position Data

# Example [bird_id]_calibrated.csv structure:
# bird_id    datetime            date        Longitude  Latitude  zenith  method
# BW154      2024-07-08 05:30:00 2024-07-08  -115.2     27.9      98.74   threshold_crossing_internal_gamma

Quality Control

The package performs automatic quality checks:

  1. Twilight Filtering
    • Removes twilights < 1 hour apart
    • Filters unusual intervals (not ~12 or ~24 hours)
    • Checks light quality around transitions
  2. Position Filtering
    • Removes impossible coordinates (outside reasonable bounds)
    • Excludes equinox periods if specified
    • Validates hemisphere
  3. Hemisphere Check
    • Verifies positions are in expected hemisphere
    • Reports in summary for manual review

Reviewing Quality

# Check calibration diagnostics
# Look at [bird_id]_calibration.png files

# Check hemisphere in summary
summary <- read.csv("data/processed/calibration/data/calibration_summary.csv")
table(summary$hemisphere_check)

# Review failed birds
failed <- results$processing_log[
  sapply(results$processing_log, function(x) x$status == "FAILED")
]
print(failed)

Troubleshooting

No twilights detected

Wrong hemisphere

Too few positions

Next Steps

Further Reading

Getting Help