## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment  = "#>"
)

## ----setup--------------------------------------------------------------------
library(soReta)

head(camOp_soReta[, 1:6])   # only the first 6 of 120 days, or the table gets too wide
head(recordTable_soReta)
head(recordTableIndividuals_soReta)

## -----------------------------------------------------------------------------
# 1 row = 1 site x 1 day (no RAI column here: with n_days_active always
# equal to 1, RAI would just be N x 100 -- no extra information over N)
ds_day <- build_site_day(recordTable_soReta, camOp_soReta, threshold_min = 30)
head(ds_day[ds_day$N_sp > 0, ])

## -----------------------------------------------------------------------------
wolf_burst <- recordTable_soReta[
  recordTable_soReta$Station == "S_02" &
    recordTable_soReta$Species == "wolf" &
    format(recordTable_soReta$DateTimeOriginal, "%Y-%m-%d") == "2026-02-14",
]
wolf_burst
wolf_burst_camOp <- camOp_soReta["S_02", "2026-02-14", drop = FALSE]

build_site_day(wolf_burst, wolf_burst_camOp, threshold_min = 30, independence_method = "chain")$wolf_N
build_site_day(wolf_burst, wolf_burst_camOp, threshold_min = 30, independence_method = "window")$wolf_N

## -----------------------------------------------------------------------------
interrupted_burst <- recordTable_soReta[
  recordTable_soReta$Station == "S_04" &
    format(recordTable_soReta$DateTimeOriginal, "%Y-%m-%d") == "2026-03-10",
]
interrupted_burst

interrupted_burst_camOp <- camOp_soReta["S_04", "2026-03-10", drop = FALSE]

build_site_day(interrupted_burst, interrupted_burst_camOp, threshold_min = 30, require_uninterrupted = FALSE)$wolf_N
build_site_day(interrupted_burst, interrupted_burst_camOp, threshold_min = 30, require_uninterrupted = TRUE)$wolf_N

## -----------------------------------------------------------------------------
# 1 row = 1 site x 1 fixed N-day block
ds_week <- build_site_block(recordTable_soReta, camOp_soReta, block_days = 7, threshold_min = 30)
head(ds_week)

# 1 row = 1 site x 1 calendar month
ds_month <- build_site_month(recordTable_soReta, camOp_soReta, threshold_min = 30)
head(ds_month)

# 1 row = 1 site x 1 named period, recurring every year -- our example
# data only spans January to April 2026, so a two-period split fits
# better here than a full four-season year
ds_period <- build_site_period(
  recordTable_soReta, camOp_soReta,
  period_names  = c("early", "late"),
  period_starts = c("01/01/2026", "01/03/2026"),
  threshold_min = 30
)
head(ds_period)

## ----eval = FALSE-------------------------------------------------------------
# # example: joining a per-day covariate you already have, e.g. lunar fraction
# ds_month |> dplyr::left_join(my_lunar_fraction, by = c("mid_day" = "Date"))

## ----eval = FALSE-------------------------------------------------------------
# ds_month |> dplyr::left_join(my_station_covariates, by = "Station")

## ----eval = FALSE-------------------------------------------------------------
# recordTable_soReta |> dplyr::filter(!Species %in% c("...")) |> build_site_month(camOp_soReta, threshold_min = 30)

## -----------------------------------------------------------------------------
# 1 row = 1 site
ds_site_tot <- build_site_total(recordTable_soReta, camOp_soReta, threshold_min = 30)
head(ds_site_tot)

# 1 row = 1 day
ds_day_tot <- build_day_total(recordTable_soReta, camOp_soReta, threshold_min = 30)
head(ds_day_tot)

## -----------------------------------------------------------------------------
gr_size_ev <- build_group_size_events(recordTable_soReta, camOp_soReta, countCol = "N_individuals",
                         independence_method = "window", threshold_min = 30)
head(gr_size_ev)


## -----------------------------------------------------------------------------
# most site x day x species combinations are genuinely empty
# at this grain, so filter for the informative rows
ds_group_day <- build_group_size_day(recordTable_soReta, camOp_soReta,
                                       countCol = "N_individuals",
                                       threshold_min = 30)
ds_group_day[!is.na(ds_group_day$red_deer_mean_group_size), ] |>
  head() |>
  print(width = 90)

## -----------------------------------------------------------------------------
ds_group_total <- build_group_size_total(recordTable_soReta, camOp_soReta,
                                           countCol = "N_individuals",
                                           threshold_min = 30)
print(ds_group_total, width = 100)

## -----------------------------------------------------------------------------
occ_day <- build_occupancy_day(recordTable_soReta, camOp_soReta)
head(occ_day[["wolf"]])

occ_week <- build_occupancy_block(recordTable_soReta, camOp_soReta, block_days = 7, min_days = 4)
head(occ_week[["wolf"]])

## -----------------------------------------------------------------------------
rad <- extract_radians(recordTable_soReta, threshold_min = 30)
names(rad)
# overlap::densityPlot(rad[["wolf"]], xcenter = "midnight")

## -----------------------------------------------------------------------------
recordTable_soReta$bimonth <- paste0("bim", ceiling(lubridate::month(recordTable_soReta$DateTimeOriginal) / 2))

# one level: split by station
rad_by_station <- extract_radians(recordTable_soReta, threshold_min = 30, group_col = "Station")
rad_by_station[["wolf"]][["S_01"]]

# two levels: station, then two-month period within station
rad_by_station_bimonth <- extract_radians(recordTable_soReta, threshold_min = 30,
                                            group_col = c("Station", "bimonth"))
names(rad_by_station_bimonth[["wolf"]][["S_01"]])   # check which periods actually
                                                       # exist for this species/station
                                                       # before indexing further
rad_by_station_bimonth[["wolf"]][["S_01"]][["bim1"]]

## -----------------------------------------------------------------------------
recordTable_soReta$Cluster <- ifelse(
  recordTable_soReta$Station %in% c("S_01", "S_02"),
  "S_01_S_02_cluster",
  recordTable_soReta$Station
)

# group_cols changes what counts as independent: the two real stations
# are now merged for this purpose
rad_clustered <- extract_radians(recordTable_soReta, threshold_min = 30,
                                   group_cols = c("Cluster", "Species"))

# group_col, unchanged in meaning: still just splits the finished
# result -- here, by the same clustered column, just to display it
rad_clustered_split <- extract_radians(recordTable_soReta, threshold_min = 30,
                                         group_cols = c("Cluster", "Species"),
                                         group_col  = "Cluster")
rad_clustered_split[["wolf"]][["S_01_S_02_cluster"]]

## -----------------------------------------------------------------------------
Rad_obj <- radians_to_env(rad_by_station, prefix = "Rad_", sep = "-")
Rad_obj
str(get(Rad_obj[1]))

## -----------------------------------------------------------------------------
pair_data <- build_species_pair_intervals(
  recordTable_soReta, camOp_soReta,
  speciesA = "wolf", speciesB = "wild boar",
  threshold_min = 30
)
head(pair_data)

## -----------------------------------------------------------------------------
# 1. linear model (log-transformed, as Niedballa et al. 2019 did to meet
#    linear model assumptions)
mod <- lm(log(delta_hours) ~ direction, data = pair_data[!pair_data$censored, ])
summary(mod)

# 2. Mann-Whitney U-test 
wilcox.test(delta_hours ~ direction, data = pair_data[!pair_data$censored, ])

# 3. permutation test (shuffle species labels, keeping real timestamps
#    and each species' total count fixed, recompute the AB/BA ratio
#    each time)
set.seed(1)
n_perm <- 999
rt_pair <- recordTable_soReta[recordTable_soReta$Species %in% c("wolf", "wild boar"), ]
obs_ratio <- median(pair_data$delta_hours[pair_data$direction == "AB" & !pair_data$censored]) /
  median(pair_data$delta_hours[pair_data$direction == "BA" & !pair_data$censored])
null_ratio <- replicate(n_perm, {
  rt_perm <- rt_pair
  rt_perm$Species <- sample(rt_perm$Species)
  out_perm <- build_species_pair_intervals(rt_perm, camOp_soReta, speciesA = "wolf", speciesB = "wild boar",
                                            threshold_min = 30)
  median(out_perm$delta_hours[out_perm$direction == "AB" & !out_perm$censored]) /
    median(out_perm$delta_hours[out_perm$direction == "BA" & !out_perm$censored])
})
mean(null_ratio >= obs_ratio, na.rm = TRUE)  # empirical p-value

## -----------------------------------------------------------------------------
interruptions <- build_species_pair_interruptions(
  recordTable_soReta,
  speciesA = "wolf", speciesB = "wild boar",
  threshold_min = 30
)
table(interruptions$type)

# permutation test on AA vs BB (same logic as above, applied to the
# interruption-type intervals instead of AB/BA)
obs_ratio_aabb <- median(interruptions$delta_hours[interruptions$type == "AA"]) /
  median(interruptions$delta_hours[interruptions$type == "BB"])
null_ratio_aabb <- replicate(n_perm, {
  rt_perm <- rt_pair
  rt_perm$Species <- sample(rt_perm$Species)
  out_perm <- build_species_pair_interruptions(rt_perm, speciesA = "wolf", speciesB = "wild boar",
                                                threshold_min = 30)
  median(out_perm$delta_hours[out_perm$type == "AA"]) /
    median(out_perm$delta_hours[out_perm$type == "BB"])
})
mean(null_ratio_aabb >= obs_ratio_aabb, na.rm = TRUE)

## ----eval = requireNamespace("GLMMadaptive", quietly = TRUE) && requireNamespace("mgcv", quietly = TRUE)----
diel_month <- build_diel_binomial_month(recordTable_soReta, camOp_soReta, bin_hours = 1, min_days = 10)
diel_wolf  <- diel_month[diel_month$Species == "wolf", ]
diel_wolf$Station <- factor(diel_wolf$Station)

# trigonometric GLMM (Iannarilli et al. 2024, section 3.3)
trig_model <- GLMMadaptive::mixed_model(
  fixed  = cbind(success, failure) ~ cos(2 * pi * Time / 24) + sin(2 * pi * Time / 24) +
                                      cos(2 * pi * Time / 12) + sin(2 * pi * Time / 12),
  random = ~ 1 | Station,
  data   = diel_wolf,
  family = binomial()
)
summary(trig_model)

## -----------------------------------------------------------------------------
ch <- build_cmr_block(recordTableIndividuals_soReta, camOp_soReta, block_days = 7, min_days = 4)
as_capture_strings(ch)

