Author: glscalibrator authors
Date: 2025-11-24

# 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

- `GLSmergedata.csv` - Combined data for all birds in standard format
- `all_birds_calibrated.csv` - All positions with metadata
- `calibration_summary.csv` - Summary statistics
- `[bird_id]_calibrated.csv` - Individual bird positions
- `[bird_id]_GLSmergedata.csv` - Individual bird in standard format

### Figures

- `all_tracks_combined.png` - Map with all bird tracks
- `[bird_id]_track.png` - Individual bird track map
- `[bird_id]_calibration.png` - Calibration diagnostics

## 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

- Check if light threshold is appropriate (try 1-5 lux)
- Verify .lux file format is correct
- Ensure device was recording properly

### Wrong hemisphere

- Check colony coordinates (lon/lat order)
- Review individual track plots
- May indicate device malfunction

### Too few positions

- Check if equinox exclusions are too broad
- Review calibration period (might be at wrong location)
- Verify deployment duration

## Next Steps

- Combine with environmental data
- Perform movement analysis
- Create publication-quality figures
- Integrate with other tracking data

## Further Reading

- SGAT documentation
- GeoLight manual
- Light-level geolocation user’s guide (Lisovski et al. 2020)

## Getting Help

- GitHub Issues: https://github.com/fabbiologia/glscalibrator/issues
- Email: favoretto.fabio@gmail.com