diff --git a/.Rbuildignore b/.Rbuildignore index 8e7ee7ff..c6b10c45 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -9,3 +9,4 @@ ^README\.Rmd$ ^README-.*\.png$ ^\.github$ +^R/util-intern_pkg_man\.r$ diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 8d60ca8f..96316318 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -47,3 +47,4 @@ jobs: - uses: r-lib/actions/check-r-package@v2 with: upload-snapshots: true + error-on: '"error"' diff --git a/DESCRIPTION b/DESCRIPTION index 8e73381f..a4faecc9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -10,31 +10,32 @@ Imports: data.table, dplyr, fasterize, - fasttime, gdalUtilities, geodist, gdistance, geosphere, jsonlite, - knitr, lubridate, magrittr, - methods, plotrix, purrr, raster, readxl, - rmarkdown, sf, sp, tibble, tidyr, + units, zip Suggests: gganimate, gifski, + knitr, + methods, png, - testthat (>= 3.0.0), + rmarkdown, + terra, + testthat (>= 3.0.0), tint URL: https://github.com/ocean-tracking-network/glatos BugReports: https://github.com/ocean-tracking-network/glatos/issues diff --git a/R/class-glatos_animals.r b/R/class-glatos_animals.r index 998b0b5d..a2de0ad5 100644 --- a/R/class-glatos_animals.r +++ b/R/class-glatos_animals.r @@ -71,6 +71,8 @@ #' ga_tbl <- as_glatos_animals(x_tbl) #' #' +#' # All below will error as invalid +#' #' # data.frame input; missing column name #' library(dplyr) # for rename #' x2 <- rename(x, @@ -78,17 +80,19 @@ #' release_timestamp = utc_release_date_time #' ) #' -#' ga2 <- as_glatos_animals(x2) -#' +#' try( +#' ga2 <- as_glatos_animals(x2) +#' ) #' -#' # data.grame input; wrong column class +#' # data.frame input; wrong column class #' x3 <- mutate(x, #' animal_id = as.integer(animal_id), #' utc_release_date_time = as.character(utc_release_date_time) #' ) #' -#' ga3 <- as_glatos_animals(x3) -#' +#' try( +#' ga3 <- as_glatos_animals(x3) +#' ) #' #' # Validation and checking #' diff --git a/R/class-glatos_detections.r b/R/class-glatos_detections.r index 5905bcb5..3856b770 100644 --- a/R/class-glatos_detections.r +++ b/R/class-glatos_detections.r @@ -73,6 +73,8 @@ #' gd_tbl <- as_glatos_detections(x_tbl) #' #' +#' # All below will error as invalid +#' #' # data.frame input; missing column name #' library(dplyr) # for rename #' x2 <- rename(x, @@ -80,8 +82,9 @@ #' det_date_time = detection_timestamp_utc #' ) #' -#' gd2 <- as_glatos_detections(x2) -#' +#' try( +#' gd2 <- as_glatos_detections(x2) +#' ) #' #' # data.frame input; wrong column class #' x3 <- mutate(x, @@ -89,8 +92,9 @@ #' detection_timestamp_utc = as.character(detection_timestamp_utc) #' ) #' -#' gr3 <- as_glatos_detections(x3) -#' +#' try( +#' gr3 <- as_glatos_detections(x3) +#' ) #' #' # Validation and checking #' diff --git a/R/class-glatos_receivers.r b/R/class-glatos_receivers.r index 3d0b3786..d8f6c39a 100644 --- a/R/class-glatos_receivers.r +++ b/R/class-glatos_receivers.r @@ -86,6 +86,7 @@ #' #' gr_tbl <- as_glatos_receivers(x_tbl) #' +#' # All below will error as invalid #' #' # data.frame input; missing column name #' library(dplyr) # for rename @@ -94,8 +95,9 @@ #' deploy_timestamp = deploy_date_time #' ) #' -#' gr2 <- as_glatos_receivers(x2) -#' +#' try( +#' gr2 <- as_glatos_receivers(x2) +#' ) #' #' # data.frame input; wrong column class #' x3 <- mutate(x, @@ -103,8 +105,9 @@ #' deploy_date_time = as.character(deploy_date_time) #' ) #' -#' gr3 <- as_glatos_receivers(x3) -#' +#' try( +#' gr3 <- as_glatos_receivers(x3) +#' ) #' #' # Validation and checking #' diff --git a/R/load-read_glatos_detections.r b/R/load-read_glatos_detections.r index d53e77c9..a4b3d9f1 100644 --- a/R/load-read_glatos_detections.r +++ b/R/load-read_glatos_detections.r @@ -53,9 +53,9 @@ read_glatos_detections <- function(det_file, version = NULL) { # Identify detection file version id_det_version <- function(det_file) { det_col_names <- names(data.table::fread(det_file, nrows = 0)) - if (all(glatos:::glatos_detection_schema$v1.4$name %in% det_col_names)) { + if (all(glatos_detection_schema$v1.4$name %in% det_col_names)) { return("1.4") - } else if (all(glatos:::glatos_detection_schema$v1.3$name %in% det_col_names)) { + } else if (all(glatos_detection_schema$v1.3$name %in% det_col_names)) { return("1.3") } else { stop("Detection file version could not be identified.") @@ -65,7 +65,7 @@ read_glatos_detections <- function(det_file, version = NULL) { if (is.null(version)) { version <- id_det_version(det_file) } else if (!(paste0("v", version) %in% - names(glatos:::glatos_detection_schema))) { + names(glatos_detection_schema))) { stop(paste0("Detection file version ", version, " is not supported.")) } @@ -73,7 +73,7 @@ read_glatos_detections <- function(det_file, version = NULL) { if (version %in% c("1.3", "1.4")) { vversion <- paste0("v", version) - col_classes <- glatos:::glatos_detection_schema[[vversion]]$type + col_classes <- glatos_detection_schema[[vversion]]$type timestamp_cols <- which(col_classes == "POSIXct") date_cols <- which(col_classes == "Date") col_classes[c(timestamp_cols, date_cols)] <- "character" @@ -89,9 +89,9 @@ read_glatos_detections <- function(det_file, version = NULL) { options(lubridate.fasttime = TRUE) for (j in timestamp_cols) { data.table::set(dtc, - j = glatos:::glatos_detection_schema[[vversion]]$name[j], + j = glatos_detection_schema[[vversion]]$name[j], value = lubridate::parse_date_time( - dtc[[glatos:::glatos_detection_schema[[vversion]]$name[j]]], + dtc[[glatos_detection_schema[[vversion]]$name[j]]], orders = "ymd HMS", tz = "UTC" ) @@ -100,15 +100,15 @@ read_glatos_detections <- function(det_file, version = NULL) { # coerce dates to date for (j in date_cols) { data.table::set(dtc, - j = glatos:::glatos_detection_schema[[vversion]]$name[j], - value = ifelse(dtc[[glatos:::glatos_detection_schema[[vversion]]$name[j]]] == "", + j = glatos_detection_schema[[vversion]]$name[j], + value = ifelse(dtc[[glatos_detection_schema[[vversion]]$name[j]]] == "", NA, - dtc[[glatos:::glatos_detection_schema[[vversion]]$name[j]]] + dtc[[glatos_detection_schema[[vversion]]$name[j]]] ) ) data.table::set(dtc, - j = glatos:::glatos_detection_schema[[vversion]]$name[j], - value = as.Date(dtc[[glatos:::glatos_detection_schema[[vversion]]$name[j]]]) + j = glatos_detection_schema[[vversion]]$name[j], + value = as.Date(dtc[[glatos_detection_schema[[vversion]]$name[j]]]) ) } } diff --git a/R/load-read_glatos_receivers.r b/R/load-read_glatos_receivers.r index a5084d5a..5b45e328 100644 --- a/R/load-read_glatos_receivers.r +++ b/R/load-read_glatos_receivers.r @@ -49,9 +49,9 @@ read_glatos_receivers <- function(rec_file, version = NULL) { # Identify file version id_file_version <- function(rec_file) { col_names <- names(data.table::fread(rec_file, nrows = 0)) - if (all(glatos:::glatos_receivers_schema$v1.1$name %in% col_names)) { + if (all(glatos_receivers_schema$v1.1$name %in% col_names)) { return("1.1") - } else if (all(glatos:::glatos_receivers_schema$v1.0$name %in% col_names)) { + } else if (all(glatos_receivers_schema$v1.0$name %in% col_names)) { return("1.0") } else { stop("Receiver location file version could not be identified.") @@ -61,7 +61,7 @@ read_glatos_receivers <- function(rec_file, version = NULL) { if (is.null(version)) { version <- id_file_version(rec_file) } else if (!(paste0("v", version) %in% - names(glatos:::glatos_receivers_schema))) { + names(glatos_receivers_schema))) { stop(paste0( "Receiver locations file version ", version, " is not supported." @@ -72,7 +72,7 @@ read_glatos_receivers <- function(rec_file, version = NULL) { if (version %in% c("1.0", "1.1")) { ver_txt <- paste0("v", version) - col_classes <- glatos:::glatos_receivers_schema[[ver_txt]]$type + col_classes <- glatos_receivers_schema[[ver_txt]]$type timestamp_cols <- which(col_classes == "POSIXct") date_cols <- which(col_classes == "Date") col_classes[c(timestamp_cols, date_cols)] <- "character" diff --git a/R/load-read_glatos_workbook.r b/R/load-read_glatos_workbook.r index 6ba58b8b..b8ea3866 100644 --- a/R/load-read_glatos_workbook.r +++ b/R/load-read_glatos_workbook.r @@ -109,7 +109,7 @@ read_glatos_workbook <- function( # Identify workbook version (based on sheet names) id_workbook_version <- function(wb_file, sheets) { - if (all(names(glatos:::glatos_workbook_schema$v1.3) %in% sheets)) { + if (all(names(glatos_workbook_schema$v1.3) %in% sheets)) { return("1.3") } else { stop(paste0( @@ -124,7 +124,7 @@ read_glatos_workbook <- function( if (is.null(wb_version)) { wb_version <- id_workbook_version(wb_file, sheets) } else if (!(paste0("v", wb_version) %in% - names(glatos:::glatos_workbook_schema))) { + names(glatos_workbook_schema))) { stop(paste0("Workbook version ", wb_version, " is not supported.")) } @@ -134,7 +134,7 @@ read_glatos_workbook <- function( #-Workbook v1.3-------------------------------------------------------------- if (wb_version == "1.3") { - wb[names(glatos:::glatos_workbook_schema$v1.3)] <- NA + wb[names(glatos_workbook_schema$v1.3)] <- NA # Get project data tmp <- tryCatch( @@ -170,18 +170,18 @@ read_glatos_workbook <- function( # Read all sheets except project if (read_all) { sheets_to_read <- sheets - extra_sheets <- setdiff(sheets, names(glatos:::glatos_workbook_schema[[ + extra_sheets <- setdiff(sheets, names(glatos_workbook_schema[[ paste0("v", wb_version) ]])) } else { - sheets_to_read <- names(glatos:::glatos_workbook_schema[[ + sheets_to_read <- names(glatos_workbook_schema[[ paste0("v", wb_version) ]]) } sheets_to_read <- setdiff(sheets_to_read, "project") # exclude project for (i in 1:length(sheets_to_read)) { - schema_i <- glatos:::glatos_workbook_schema[[ + schema_i <- glatos_workbook_schema[[ paste0("v", wb_version) ]][[sheets_to_read[i]]] @@ -532,7 +532,7 @@ read_glatos_workbook <- function( # assign classes wb2$animals <- as_glatos_animals(wb2$animals) wb2$receivers <- as_glatos_receivers(wb2$receivers) - wb2 <- glatos:::glatos_workbook(wb2) + wb2 <- glatos_workbook(wb2) return(wb2) } diff --git a/R/load-read_otn_deployments.R b/R/load-read_otn_deployments.R index 774d4c0e..5f4aa9d7 100644 --- a/R/load-read_otn_deployments.R +++ b/R/load-read_otn_deployments.R @@ -31,11 +31,13 @@ #' @author A. Nunes, \email{anunes@dal.ca} #' #' @examples +#' \dontrun{ #' # get path to example deployments file #' deployment_file <- system.file("extdata", "hfx_deployments.csv", #' package = "glatos" #' ) #' dep <- read_otn_deployments(deployment_file) +#' } #' #' @importFrom lubridate parse_date_time #' @importFrom tidyr extract diff --git a/R/load-read_vdat_csv.r b/R/load-read_vdat_csv.r index d673dc18..ccc3230a 100644 --- a/R/load-read_vdat_csv.r +++ b/R/load-read_vdat_csv.r @@ -1,260 +1,289 @@ -#' Read data from an Innovasea Fathom VDAT CSV file -#' -#' Read data from an Innovasea Fathom VDAT CSV file -#' -#' @param src A character string with path and name of an Innovasea VDAT CSV -#' detection file. If only file name is given, then the file must be located -#' in the working directory. -#' -#' @param record_types An optional vector of character strings with names of -#' record types to read from the file. E.g., "DET" for detection records. -#' Default (\code{NULL}) will read all record types present in input CSV -#' \code{src}. -#' -#' @param show_progress Optional argument passed to \code{data.table::fread}'s -#' \code{showProgress}. -#' -#' @details Reading is done via \code{\link[data.table]{fread}}. -#' -#' @details All timestamp columns are assumed to be in UTC and are assigned -#' class \code{POSIXct}. The internal value of timestamps will include -#' fractional seconds but the printed value (i.e., displayed or written to -#' file) will be truncated according to \code{options()$digits.secs}. By -#' default (\code{options()$digits.secs = NULL}), values are truncated (i.e., -#' rounded down) to the nearest second. To maintain the full resolution -#' present in the input Fathom CSV file, set \code{options(digits.secs = 6)}. -#' -#' @return A list of class \code{vdat_list} with one named element for each -#' record type and attributes: \code{fathom_csv_format_version} with version -#' of the input Fathom CSV format; \code{source} with version of -#' VDAT.exe used to create the input file. -#' -#' -#' @author C. Holbrook (cholbrook@@usgs.gov) -#' -#' @examples -#' -#' # Example 1. Read a single file -#' -#' vrl_file <- system.file("extdata", "detection_files_raw", -#' "VR2W_109924_20110718_1.vrl", package="glatos") -#' -#' temp_dir <- tempdir() -#' -#' csv_file <- vdat_convert(vrl_file, out_dir = temp_dir) -#' -#' #utils::browseURL(temp_dir) -#' -#' #read all record types -#' vdat <- read_vdat_csv(csv_file) -#' -#' #read only one record type -#' vdat <- read_vdat_csv(csv_file, record_types = c("DET")) -#' -#' -#' # Example 2. Read and combine detection records from multiple files -#' -#' # get two example files -#' vrl_files <- system.file("extdata", "detection_files_raw", -#' c("VR2W_109924_20110718_1.vrl", -#' "HR2-180 461396 2021-04-20 173145.vdat"), -#' package="glatos") -#' -#' csv_files <- vdat_convert(vrl_files, out_dir = temp_dir) -#' -#' -#' # using dplyr -#' -#' library(dplyr) -#' -#' # basic steps: import each to list element, subset DET records, -#' add column with source file name, combine. -#' -#' det2_tbl <- csv_files %>% -#' lapply( -#' function(x) { -#' read_vdat_csv(x, record_types = "DET")$DET %>% -#' as_tibble %>% -#' mutate(source_file = basename(x)) -#' }) %>% -#' bind_rows -#' -#' -#' #using data.table -#' -#' library(data.table) -#' -#' det2_dt <- rbindlist( -#' lapply(csv_files, -#' function(x) { -#' read_vdat_csv(x, record_types = "DET")$DET[, -#' source_file := basename(x)] -#' })) -#' -#' \dontrun{ -#' -#' # get current version of digits.secs -#' op_digits.secs <- options()$digits.secs -#' -#' # set digits.secs = NULL (default, truncates to nearest second) -#' options(digits.secs = NULL) -#' -#' # note truncation to nearest second -#' vdat$DET$Time[2] -#' -#' # set digits.secs to see fractional seconds -#' options(digits.secs = 6) -#' -#' # note fractional seconds -#' vdat$DET$Time[2] -#' -#' # return to default values -#' options(digits.secs = op_digits.secs) -#' -#' # or specify via format %OSn e.g., when writing to disk or external database -#' # see ?strptime -#' format(vdat$DET$Time[2], format = "%Y-%m-%d %H:%M:%OS6") -#' -#' } -#' -#' @export -read_vdat_csv <- function(src, - record_types = NULL, - show_progress = FALSE){ - - #Check if exists - if(!file.exists(src)){ - warning("File not found: ", src) - return() - } - - #Identify vdat csv format version and vdat.exe version that created input csv - vdat_header <- data.table::fread(file = src, nrows = 1L, header = FALSE) - - #Check if fathom csv format (error if looks like VUE export format) - if(vdat_header$V1[1] == "VEMCO DATA LOG") { - # Set column names - src_version <- data.table::data.table(fathom_csv = vdat_header$V2[1], - vdat_exe = vdat_header$V3[1]) - } else if (all(c("Receiver", - "Transmitter", - "Transmitter Name", - "Transmitter Serial", - "Sensor Value", - "Sensor Unit", - "Station Name", - "Latitude", - "Longitude") %in% - as.character(vdat_header))) { - stop("Input file appears to be in VUE Export format, which is not ", - "supported.\n Only Fathom CSV format is supported. \n", - " Perhaps you want read_vue_detection_csv()?") - } - - #Read all data into character vector (like readLines) - vdat_txt <- data.table::fread(file = src, skip = 2, header = FALSE, - sep = NULL, col.names = "txt", - showProgress = show_progress) - - #Identify record type of each row - vdat_txt[ , record_type := data.table::fread(file = src, - skip = 2, - header = FALSE, - sep = ",", - select = 1, - fill = TRUE, - showProgress = show_progress)] - - #Drop _DESC from headers - vdat_txt[ , record_type := gsub("_DESC$", "", record_type)] - - - #Get record identifiers from csv file - csv_record_types <- unique(vdat_txt$record_type) - - - if(is.null(record_types)) { - - record_types <- csv_record_types - - } else { - - #Check if any record_types are not in csv - unknown_record_types <- setdiff(record_types, csv_record_types) - - if(length(unknown_record_types) > 0) stop("The following input ", - "'record_types' ", - "were not found in CSV file: \n\t", - paste(unknown_record_types, - collapse = ", ")) - } - - #Drop data types not requested by user - vdat_txt <- vdat_txt[record_type %in% record_types] - - #Split into list elements by record type - vdat_list <- split(vdat_txt, - by = "record_type", - keep.by = FALSE) - - data(vdat_csv_schema) - - vdat_csv_schema <- vdat_csv_schema[[paste0("v", src_version$fathom_csv)]] - - - # Preallocate list; element = record type - vdat <- setNames(object = vector("list", length(vdat_list)), - nm = names(vdat_list)) - - for(i in 1:length(vdat)){ - - # fread has issues with numerical precision (e.g., 'Time Correction (s)') - # so read all columns as character then coerce - vdat[[i]] <- data.table::fread( - text = paste0(c(vdat_list[[i]]$txt,""), - collapse = "\n"), - sep = ",", na.strings = "", - colClasses = "character", - header = TRUE, - drop = 1, - showProgress = show_progress) - - # Coerce to class - schema_i <- vdat_csv_schema[[names(vdat[i])]] - - # numeric - numeric_cols <- schema_i$name[schema_i$type == "numeric"] - - if(length(numeric_cols) > 0) { - vdat[[i]][, (numeric_cols) := lapply(.SD, as.numeric), - .SDcols = numeric_cols] - } - - # POSIXct - timestamp_cols <- schema_i$name[schema_i$type == "POSIXct"] - - if(length(timestamp_cols) > 0){ - vdat[[i]][, (timestamp_cols) := lapply(.SD, - function(x) - lubridate::fast_strptime( - x, - format = "%Y-%m-%d %H:%M:%OS", - lt = FALSE)), - .SDcols = timestamp_cols] - } - - # Assign class - new_class <- c(paste0("vdat_", names(vdat[i])), class(vdat[[i]])) - data.table::setattr(vdat[[i]], "class", new_class) - - } # end i - - #Assign class and other attributes - vdat_list <- structure(vdat, - class = c("vdat_list", class(vdat)), - fathom_csv_version = src_version$fathom_csv, - source = src_version$vdat_exe) - - return(vdat_list) -} - \ No newline at end of file +#' Read data from an Innovasea Fathom VDAT CSV file +#' +#' Read data from an Innovasea Fathom VDAT CSV file +#' +#' @param src A character string with path and name of an Innovasea VDAT CSV +#' detection file. If only file name is given, then the file must be located +#' in the working directory. +#' +#' @param record_types An optional vector of character strings with names of +#' record types to read from the file. E.g., "DET" for detection records. +#' Default (\code{NULL}) will read all record types present in input CSV +#' \code{src}. +#' +#' @param show_progress Optional argument passed to \code{data.table::fread}'s +#' \code{showProgress}. +#' +#' @details Reading is done via \code{\link[data.table]{fread}}. +#' +#' @details All timestamp columns are assumed to be in UTC and are assigned +#' class \code{POSIXct}. The internal value of timestamps will include +#' fractional seconds but the printed value (i.e., displayed or written to +#' file) will be truncated according to \code{options()$digits.secs}. By +#' default (\code{options()$digits.secs = NULL}), values are truncated (i.e., +#' rounded down) to the nearest second. To maintain the full resolution +#' present in the input Fathom CSV file, set \code{options(digits.secs = 6)}. +#' +#' @return A list of class \code{vdat_list} with one named element for each +#' record type and attributes: \code{fathom_csv_format_version} with version +#' of the input Fathom CSV format; \code{source} with version of +#' VDAT.exe used to create the input file. +#' +#' +#' @author C. Holbrook (cholbrook@@usgs.gov) +#' +#' @examples +#' \dontrun{ +#' # Example 1. Read a single file +#' +#' vrl_file <- system.file("extdata", "detection_files_raw", +#' "VR2W_109924_20110718_1.vrl", +#' package = "glatos" +#' ) +#' +#' temp_dir <- tempdir() +#' +#' csv_file <- vdat_convert(vrl_file, out_dir = temp_dir) +#' +#' # utils::browseURL(temp_dir) +#' +#' # read all record types +#' vdat <- read_vdat_csv(csv_file) +#' +#' # read only one record type +#' vdat <- read_vdat_csv(csv_file, record_types = c("DET")) +#' +#' +#' # Example 2. Read and combine detection records from multiple files +#' +#' # get two example files +#' vrl_files <- system.file("extdata", "detection_files_raw", +#' c( +#' "VR2W_109924_20110718_1.vrl", +#' "HR2-180 461396 2021-04-20 173145.vdat" +#' ), +#' package = "glatos" +#' ) +#' +#' csv_files <- vdat_convert(vrl_files, out_dir = temp_dir) +#' +#' +#' # using dplyr +#' +#' library(dplyr) +#' +#' # basic steps: import each to list element, subset DET records, +#' # add column with source file name, combine. +#' +#' det2_tbl <- csv_files %>% +#' lapply( +#' function(x) { +#' read_vdat_csv(x, record_types = "DET")$DET %>% +#' as_tibble() %>% +#' mutate(source_file = basename(x)) +#' } +#' ) %>% +#' bind_rows() +#' +#' +#' # using data.table +#' +#' library(data.table) +#' +#' det2_dt <- rbindlist( +#' lapply( +#' csv_files, +#' function(x) { +#' read_vdat_csv(x, record_types = "DET")$DET[ +#' , +#' source_file := basename(x) +#' ] +#' } +#' ) +#' ) +#' +#' +#' # get current version of digits.secs +#' op_digits.secs <- options()$digits.secs +#' +#' # set digits.secs = NULL (default, truncates to nearest second) +#' options(digits.secs = NULL) +#' +#' # note truncation to nearest second +#' vdat$DET$Time[2] +#' +#' # set digits.secs to see fractional seconds +#' options(digits.secs = 6) +#' +#' # note fractional seconds +#' vdat$DET$Time[2] +#' +#' # return to default values +#' options(digits.secs = op_digits.secs) +#' +#' # or specify via format %OSn e.g., when writing to disk or external database +#' # see ?strptime +#' format(vdat$DET$Time[2], format = "%Y-%m-%d %H:%M:%OS6") +#' } +#' +#' @export +read_vdat_csv <- function(src, + record_types = NULL, + show_progress = FALSE) { + # Check if exists + if (!file.exists(src)) { + warning("File not found: ", src) + return() + } + + # Identify vdat csv format version and vdat.exe version that created input csv + vdat_header <- data.table::fread(file = src, nrows = 1L, header = FALSE) + + # Check if fathom csv format (error if looks like VUE export format) + if (vdat_header$V1[1] == "VEMCO DATA LOG") { + # Set column names + src_version <- data.table::data.table( + fathom_csv = vdat_header$V2[1], + vdat_exe = vdat_header$V3[1] + ) + } else if (all(c( + "Receiver", + "Transmitter", + "Transmitter Name", + "Transmitter Serial", + "Sensor Value", + "Sensor Unit", + "Station Name", + "Latitude", + "Longitude" + ) %in% + as.character(vdat_header))) { + stop( + "Input file appears to be in VUE Export format, which is not ", + "supported.\n Only Fathom CSV format is supported. \n", + " Perhaps you want read_vue_detection_csv()?" + ) + } + + # Read all data into character vector (like readLines) + vdat_txt <- data.table::fread( + file = src, skip = 2, header = FALSE, + sep = NULL, col.names = "txt", + showProgress = show_progress + ) + + # Identify record type of each row + vdat_txt[, record_type := data.table::fread( + file = src, + skip = 2, + header = FALSE, + sep = ",", + select = 1, + fill = TRUE, + showProgress = show_progress + )] + + # Drop _DESC from headers + vdat_txt[, record_type := gsub("_DESC$", "", record_type)] + + + # Get record identifiers from csv file + csv_record_types <- unique(vdat_txt$record_type) + + + if (is.null(record_types)) { + record_types <- csv_record_types + } else { + # Check if any record_types are not in csv + unknown_record_types <- setdiff(record_types, csv_record_types) + + if (length(unknown_record_types) > 0) { + stop( + "The following input ", + "'record_types' ", + "were not found in CSV file: \n\t", + paste(unknown_record_types, + collapse = ", " + ) + ) + } + } + + # Drop data types not requested by user + vdat_txt <- vdat_txt[record_type %in% record_types] + + # Split into list elements by record type + vdat_list <- split(vdat_txt, + by = "record_type", + keep.by = FALSE + ) + + data(vdat_csv_schema) + + vdat_csv_schema <- vdat_csv_schema[[paste0("v", src_version$fathom_csv)]] + + + # Preallocate list; element = record type + vdat <- setNames( + object = vector("list", length(vdat_list)), + nm = names(vdat_list) + ) + + for (i in 1:length(vdat)) { + # fread has issues with numerical precision (e.g., 'Time Correction (s)') + # so read all columns as character then coerce + vdat[[i]] <- data.table::fread( + text = paste0(c(vdat_list[[i]]$txt, ""), + collapse = "\n" + ), + sep = ",", na.strings = "", + colClasses = "character", + header = TRUE, + drop = 1, + showProgress = show_progress + ) + + # Coerce to class + schema_i <- vdat_csv_schema[[names(vdat[i])]] + + # numeric + numeric_cols <- schema_i$name[schema_i$type == "numeric"] + + if (length(numeric_cols) > 0) { + vdat[[i]][, (numeric_cols) := lapply(.SD, as.numeric), + .SDcols = numeric_cols + ] + } + + # POSIXct + timestamp_cols <- schema_i$name[schema_i$type == "POSIXct"] + + if (length(timestamp_cols) > 0) { + vdat[[i]][, (timestamp_cols) := lapply( + .SD, + function(x) { + lubridate::fast_strptime( + x, + format = "%Y-%m-%d %H:%M:%OS", + lt = FALSE + ) + } + ), + .SDcols = timestamp_cols + ] + } + + # Assign class + new_class <- c(paste0("vdat_", names(vdat[i])), class(vdat[[i]])) + data.table::setattr(vdat[[i]], "class", new_class) + } # end i + + # Assign class and other attributes + vdat_list <- structure(vdat, + class = c("vdat_list", class(vdat)), + fathom_csv_version = src_version$fathom_csv, + source = src_version$vdat_exe + ) + + return(vdat_list) +} diff --git a/R/load-write_vdat_csv.r b/R/load-write_vdat_csv.r index d804f96c..6ffd201d 100644 --- a/R/load-write_vdat_csv.r +++ b/R/load-write_vdat_csv.r @@ -44,6 +44,7 @@ #' @author C. Holbrook (cholbrook@@usgs.gov) #' #' @examples +#' \dontrun{ #' #' # Example 1. Read and write a single file #' @@ -66,7 +67,7 @@ #' #' # write to multiple files #' write_vdat_csv(vdat, output_format = "csv.fathom.split") -#' +#' } #' @export write_vdat_csv <- function(vdat, record_types = NULL, diff --git a/R/sim-calc_collision_prob.r b/R/sim-calc_collision_prob.r index 93d2538f..158febc6 100644 --- a/R/sim-calc_collision_prob.r +++ b/R/sim-calc_collision_prob.r @@ -1,28 +1,28 @@ #' Estimate probability of collision for telemetry transmitters -#' -#' Estimate (by simulation) probability of collision for co-located telemetry -#' transmitters with pulse-period-modulation type encoding #' -#' @param delayRng A 2-element numeric vector with minimum and maximum delay +#' Estimate (by simulation) probability of collision for co-located telemetry +#' transmitters with pulse-period-modulation type encoding +#' +#' @param delayRng A 2-element numeric vector with minimum and maximum delay #' (time in seconds from end of one coded burst to beginning of next). -#' -#' @param burstDur A numeric scalar with duration (in seconds) of each coded +#' +#' @param burstDur A numeric scalar with duration (in seconds) of each coded #' burst (i.e., pulse train). -#' -#' @param maxTags A numeric scalar with maximum number of co-located +#' +#' @param maxTags A numeric scalar with maximum number of co-located #' transmitters (within detection range at same time). -#' -#' @param nTrans A numeric scalar with the number of transmissions to simulate +#' +#' @param nTrans A numeric scalar with the number of transmissions to simulate #' for each co-located transmitter. #' #' @details #' Calculates the detection probability associated with collision, given delay -#' range (delayRng), burst duration (burstDur), maximum number of co-located +#' range (delayRng), burst duration (burstDur), maximum number of co-located #' tags (maxTags), and number of simulated transmission per tag (nTrans). The #' simulation estimates detection probability due only to collisions (i.e., when -#' no other variables influence detection probability) and assuming that all +#' no other variables influence detection probability) and assuming that all #' tags are co-located at a receiver for the duration of the simulation. -#' +#' #' @return A data frame containing summary statistics: #' \item{nTags}{Number of tags within detection range at one time} #' \item{min}{Minimum detection probability among simulated tags} @@ -31,12 +31,12 @@ #' \item{q3}{Third quartile of detection probabilities among simulated tags} #' \item{max}{Maximum detection probability among simulated tags} #' \item{mean}{Mean detection probability among simulated tags} -#' \item{expDetsPerHr}{Expected number of detections per hour assuming -#' perfect detection probability, given the number of tags within +#' \item{expDetsPerHr}{Expected number of detections per hour assuming +#' perfect detection probability, given the number of tags within #' detection range} -#' \item{totDetsPerHr}{Observed number of detections per hour for a given +#' \item{totDetsPerHr}{Observed number of detections per hour for a given #' number of tags} -#' \item{effDelay}{Eeffective delay of the transmitter after incorporating +#' \item{effDelay}{Eeffective delay of the transmitter after incorporating #' collisions} #' \item{detsPerTagPerHr}{Mean number of detections per hour per tag} @@ -50,77 +50,86 @@ #' @author C. Holbrook (cholbrook@usgs.gov) and T. Binder #' #' @examples -#' #parameters analagous to Vemco tag, global coding, 45 s nominal delay -#' foo <- calc_collision_prob(delayRng = c(45, 90), burstDur = 5.12, maxTags = 50, -#' nTrans = 10000) -#' -#' #plot probabilities of detection -#' plot(med~nTags, data=foo, type='p', pch=20, ylim=c(0,1), -#' b -#' -#' #plot probability of collision by subtracting detection probability from 1 -#' plot((1 - med)~nTags, data=foo, type='p', pch=20, ylim=c(0,1), -#' xlab="# of transmitters within range", ylab="Probability of collision") +#' # parameters analagous to Vemco tag, global coding, 45 s nominal delay +#' foo <- calc_collision_prob( +#' delayRng = c(45, 90), burstDur = 5.12, maxTags = 50, +#' nTrans = 10000 +#' ) +#' +#' # plot probabilities of detection +#' plot(med ~ nTags, +#' data = foo, type = "p", pch = 20, ylim = c(0, 1), +#' xlab = "# of transmitters within range", ylab = "Probability of detection" +#' ) +#' +#' # plot probability of collision by subtracting detection probability from 1 +#' plot((1 - med) ~ nTags, +#' data = foo, type = "p", pch = 20, ylim = c(0, 1), +#' xlab = "# of transmitters within range", ylab = "Probability of collision" +#' ) #' #' @export -calc_collision_prob = function(delayRng = c(60, 180), burstDur = 5.0, - maxTags = 50, nTrans = 10000) - { +calc_collision_prob <- function( + delayRng = c(60, 180), burstDur = 5.0, + maxTags = 50, nTrans = 10000) { + # preallocate objects - # preallocate objects - # transmission history (before collisions) - pingHist <- vector("list", length = maxTags) - # list of logical value; indicates collision - collide <- vector("list", length = maxTags) - # preallocate - detProbs <- data.frame(nTags= 1:maxTags, min= NA, q1= NA, med= NA, q3= NA, - max= NA, mean= NA) - # observed detection history (after collisions) - pingHistObs <- vector("list", length = maxTags) + pingHist <- vector("list", length = maxTags) + # list of logical value; indicates collision + collide <- vector("list", length = maxTags) + # preallocate + detProbs <- data.frame( + nTags = 1:maxTags, min = NA, q1 = NA, med = NA, q3 = NA, + max = NA, mean = NA + ) + # observed detection history (after collisions) + pingHistObs <- vector("list", length = maxTags) # define transmission and detection histories for each tag - for (i in 1:maxTags){ - #create transmission history; each list element is a tag, - # odd ind = start, even ind = end - # draw transmissions from uniform distribution within delayRng - #random start time - pingStart <- cumsum(runif(nTrans, delayRng[1], delayRng[2])+burstDur) + for (i in 1:maxTags) { + # create transmission history; each list element is a tag, + # odd ind = start, even ind = end + # draw transmissions from uniform distribution within delayRng + # random start time + pingStart <- cumsum(runif(nTrans, delayRng[1], delayRng[2]) + burstDur) pingHist[[i]] <- sort(c(pingStart, pingStart + burstDur)) - - if(i==1) detProbs[i,] <- c(i, rep(1,6)) - if(i>1){ # check to see if collided with any previous tag - for(j in 1:(i-1)) { - #check to see if ith tag transmissions overlaps + + if (i == 1) detProbs[i, ] <- c(i, rep(1, 6)) + if (i > 1) { # check to see if collided with any previous tag + for (j in 1:(i - 1)) { + # check to see if ith tag transmissions overlaps # with any jth tag transmissions - pingInts <- findInterval(pingHist[[i]], pingHist[[j]]) - - #identify collisions (TRUE) or nonCollisions (FALSE) - collisions <- (pingInts/2) != floor(pingInts/2) - - collide[[j]] <- unique(c(collide[[j]], ceiling(pingInts[collisions]/2))) - collide[[i]] <- unique(c(collide[[i]], - ceiling(row(as.matrix(collisions))[collisions]/2))) + pingInts <- findInterval(pingHist[[i]], pingHist[[j]]) + + # identify collisions (TRUE) or nonCollisions (FALSE) + collisions <- (pingInts / 2) != floor(pingInts / 2) + + collide[[j]] <- unique(c(collide[[j]], ceiling(pingInts[collisions] / 2))) + collide[[i]] <- unique(c( + collide[[i]], + ceiling(row(as.matrix(collisions))[collisions] / 2) + )) } - - detProb.k <- 1 - (sapply(collide[1:i], length)/ - (sapply(pingHist[1:i], length)/2)) - - detProbs[i,2:7] <- c(fivenum(detProb.k), mean(detProb.k)) - } #end if - - detProbs <- round(detProbs, 3) - } #end i - + + detProb.k <- 1 - (sapply(collide[1:i], length) / + (sapply(pingHist[1:i], length) / 2)) + + detProbs[i, 2:7] <- c(fivenum(detProb.k), mean(detProb.k)) + } # end if + + detProbs <- round(detProbs, 3) + } # end i + # calculate total number of hourly detects across all fish nomDelay <- median(delayRng) # nominal delay - #expected detects per tag per hour - expDetsPerTagPerHr <- (3600/(nomDelay + burstDur)) + # expected detects per tag per hour + expDetsPerTagPerHr <- (3600 / (nomDelay + burstDur)) - detProbs$expDetsPerHr <- expDetsPerTagPerHr*detProbs$nTags - detProbs$totDetsPerHr <- round(with(detProbs, expDetsPerHr*mean), 0) - detProbs$effDelay <- round(with(detProbs, nomDelay*(1/mean)), 0) - detProbs$detsPerTagPerHr <- round(with(detProbs, totDetsPerHr/nTags)) + detProbs$expDetsPerHr <- expDetsPerTagPerHr * detProbs$nTags + detProbs$totDetsPerHr <- round(with(detProbs, expDetsPerHr * mean), 0) + detProbs$effDelay <- round(with(detProbs, nomDelay * (1 / mean)), 0) + detProbs$detsPerTagPerHr <- round(with(detProbs, totDetsPerHr / nTags)) return(detProbs) } diff --git a/R/sim-receiver_line_det_sim.r b/R/sim-receiver_line_det_sim.r index 81d93506..aba4638a 100644 --- a/R/sim-receiver_line_det_sim.r +++ b/R/sim-receiver_line_det_sim.r @@ -93,20 +93,20 @@ #' dp #' #' # Again with only 10 virtual fish and optional plot to see simulated data -#' dp <- receiver_line_det_sim(rngFun = pdrf, nsim = 10, showPlot = T) # w/ optional plot +#' dp <- receiver_line_det_sim(rngFun = pdrf, nsim = 10, showPlot = TRUE) # w/ optional plot #' dp #' #' # Again but six receivers and allow fish to pass to left and right of line #' dp <- receiver_line_det_sim( #' rngFun = pdrf, recSpc = rep(1000, 5), -#' outerLim = c(1000, 1000), nsim = 10, showPlot = T +#' outerLim = c(1000, 1000), nsim = 10, showPlot = TRUE #' ) #' dp #' #' # Again but four receivers with irregular spacing #' dp <- receiver_line_det_sim( #' rngFun = pdrf, recSpc = c(2000, 4000, 2000), -#' outerLim = c(1000, 1000), nsim = 10, showPlot = T +#' outerLim = c(1000, 1000), nsim = 10, showPlot = TRUE #' ) #' dp #' @@ -173,7 +173,7 @@ #' ) #' #' # use empirical curve (edrf) in simulation -#' dp <- receiver_line_det_sim(rngFun = edrf, nsim = 10, showPlot = T) # w/ optional plot +#' dp <- receiver_line_det_sim(rngFun = edrf, nsim = 10, showPlot = TRUE) # w/ optional plot #' dp #' #' @export diff --git a/R/summ-receiver_efficiency.r b/R/summ-receiver_efficiency.r index 9a4f3036..aafd20df 100644 --- a/R/summ-receiver_efficiency.r +++ b/R/summ-receiver_efficiency.r @@ -35,6 +35,7 @@ #' @author Alex Nunes \email{anunes@dal.ca} #' #' @examples +#' \dontrun{ #' det_file <- system.file("extdata", "hfx_detections.csv", #' package = "glatos" #' ) @@ -47,7 +48,7 @@ #' dets <- glatos::read_otn_detections(det_file) #' #' hfx_receiver_efficiency_index <- glatos::REI(dets, hfx_deployments) -#' +#' } #' @importFrom dplyr group_by mutate coalesce filter summarise #' @importFrom magrittr "%>%" #' diff --git a/R/summ-residence_index.r b/R/summ-residence_index.r index 0085fa1a..2b5959a5 100644 --- a/R/summ-residence_index.r +++ b/R/summ-residence_index.r @@ -437,15 +437,15 @@ get_days <- function(dets, calculation_method = "kessel", time_interval_size = "1 day") { days <- 0 if (calculation_method == "aggregate_with_overlap") { - days <- glatos:::aggregate_total_with_overlap(dets) + days <- aggregate_total_with_overlap(dets) } else if (calculation_method == "aggregate_no_overlap") { - days <- glatos:::aggregate_total_no_overlap(dets) + days <- aggregate_total_no_overlap(dets) } else if (calculation_method == "timedelta") { - days <- glatos:::total_diff_days(dets) + days <- total_diff_days(dets) } else if (calculation_method == "kessel") { - days <- glatos:::interval_count(dets, time_interval_size = "1 day") + days <- interval_count(dets, time_interval_size = "1 day") } else if (calculation_method == "time_interval") { - days <- glatos:::interval_count(dets, time_interval_size) + days <- interval_count(dets, time_interval_size) } else { stop("Unsupported 'calculated_method'.") } diff --git a/R/util-convert_otn_to_att.r b/R/util-convert_otn_to_att.r index c38b1233..e104ce15 100644 --- a/R/util-convert_otn_to_att.r +++ b/R/util-convert_otn_to_att.r @@ -38,7 +38,7 @@ #' and station metadata, to be ingested by VTrack/ATT #' #' @examples -#' +#' \dontrun{ #' #-------------------------------------------------- #' # EXAMPLE #1 - loading from Deployment Object #' @@ -59,7 +59,7 @@ #' deploy <- read_otn_deployments(deploy_path) #' #' ATTdata <- convert_otn_to_att(dets, tags, deploymentObj = deploy) -#' +#' } #' #-------------------------------------------------- #' # EXAMPLE #2 - loading from Deployment Sheet #' diff --git a/R/util-kml_to_csv.r b/R/util-kml_to_csv.r index f3b39dba..01971d40 100644 --- a/R/util-kml_to_csv.r +++ b/R/util-kml_to_csv.r @@ -26,7 +26,7 @@ #' @examples #' #' # Get example kml with two polygons -#' kml_file <- system.file("inst/extdata", "example_polygons.kml", +#' kml_file <- system.file("extdata", "example_polygons.kml", #' package = "glatos" #' ) #' diff --git a/R/util-vrl2csv.r b/R/util-vrl2csv.r index bd26d027..6c17872f 100644 --- a/R/util-vrl2csv.r +++ b/R/util-vrl2csv.r @@ -65,7 +65,7 @@ #' vrl2csv(myVRL) # file name input #' #' # setting 'overwrite=FALSE' will make new file with '_n'added to name -#' vrl2csv(myVRL, overwrite = F) +#' vrl2csv(myVRL, overwrite = FALSE) #' } #' #' @name vrl2csv-deprecated diff --git a/R/vis-make_transition3.r b/R/vis-make_transition3.r index 42108190..14f8cef7 100644 --- a/R/vis-make_transition3.r +++ b/R/vis-make_transition3.r @@ -1,154 +1,156 @@ -##' Create transition layer from polygon shapefile -##' -##' Create transition layer for [interpolate_path] from polygon shapefile. -##' -##' @param poly A spatial polygon object of class -##' [SpatialPolygonsDataFrame][SpatialPolygons] or a -##' [sf::sf()][sf::sf] object with a geometry column of polygon -##' and/or multipolygon objects. -##' -##' @param res two element vector that specifies the x and y dimension -##' of output raster cells. Units of res are same as input -##' shapefile. -##' -##' @param receiver_points A SpatialPointsDataFrame object that -##' contains coordinates of receivers dataset or a "glatos_receivers" object. -##' -##' @param epsg coordinate reference code that describes projection -##' used for map calculation and rasterization. Defaults to -##' NAD83/Great Lakes and St. Lawrence Albers. -##' -##' @details `make_transition` uses [fasterize][fasterize::fasterize] -##' to convert a polygon shapefile into a raster layer and -##' geo-corrected transition layer [interpolate_path]. Raster -##' cell values on land equal 1 cells in water equal 0. Output is a -##' two-object list containing the raster layer and transition -##' layer. Both objects have the same extents and geographic -##' projection as input shapefile. -##' -##' @details If receiver\_points is provided, any receiver not in water -##' is buffered by the distance from the receiver to the nearest -##' water. This allows all receivers to be coded as in water if the -##' receiver is on land. -##' -##' @details Poly object is transformed into planer map projection -##' specified by epsg argument for calculation of transition object -##' if receiver_points is provided. Output is projected to WGS84 -##' (epsg- 4326). -##' -##' @details output transition layer is corrected for projection -##' distortions using `gdistance::geoCorrection`. Adjacent -##' cells are connected by 16 directions and transition function -##' returns 0 (land) for movements between land and water and 1 for -##' all over-water movements. -##' -##' -##' @return A list with two elements: -##' \describe{ -##' \item{transition}{a geo-corrected transition raster layer where land = 0 -##' and water=1 -##' (see `gdistance`)} -##' \item{rast}{rasterized input layer of class `raster`}} -##' Additonally, rasterized version of input shapefile (*.tif extension) is written to computer -##' at `output_dir` -##' -##' -##' @author Todd Hayden, Tom Binder, Chris Holbrook -##' -##' @examples -##' -##' #Example 1 - read from SpatialPolygonsDataFrame -##' # use example polygon for Great lakes -##' -##' #get polygon of the Great Lakes -##' data(great_lakes_polygon) #glatos example data; a sf polygon object -##' -##' # make_transition layer -##' tst <- make_transition3(great_lakes_polygon, res = c(0.1, 0.1)) -##' -##' # plot raster layer -##' # notice land = 1, water = 0 -##' plot(terra::rast(tst$rast)) -##' -##' #compare to polygon -##' plot(st_geometry(great_lakes_polygon), add = TRUE, fill = NA) -##' -##' #Example 2 - read from ESRI Shapefile and include receiver file -##' # to account for any receivers outside of great lakes polygon -##' -##' # path to polygon shapefile -##' poly <- system.file("extdata", "shoreline.zip", package = "glatos") -##' poly <- unzip(poly, exdir = tempdir()) -##' poly <- sf::st_read(poly[grepl("*.shp", poly)]) -##' -##' # read in glatos receivers object -##' rec_file <- system.file("extdata", "sample_receivers.csv", package="glatos") -##' recs <- read_glatos_receivers(rec_file) -##' -##' # change a coordinate to on-land to show impact... -##' recs[1, "deploy_lat"] <- recs[1,"deploy_lat"]+4 -##' -##' # make_transition layer -##' tst <- make_transition3(poly, res = c(0.1, 0.1), receiver_points = recs) -##' -##' # plot raster layer -##' # notice the huge circle rasterized as "water" north of Lake Superior. -##' # This occurred because we had a "receiver" deployed at that locations -##' plot(terra::rast(tst$rast)) -##' points(recs$deploy_long, recs$deploy_lat, col = "red", pch = 20) -##' -##' # plot transition layer -##' plot(raster::raster(tst$transition)) -##' -##' Example 3- transition layer of Lake Huron only with receivers -##' -##' # read polygon layer of Great Lakes -##' data(great_lakes_polygon) -##' -##' # transform to great lakes projection -##' poly <- sf::st_transform(great_lakes_polygon, crs = 3175) -##' -##' # set attribute-geometry relationship to constant. -##' # this avoids error when cropping -##' sf::st_agr(poly) = "constant" -##' -##' # crop Great lakes polygon file -##' poly <- sf::st_crop(x = poly, xmin = 829242.55, ymin = 698928.27, -##' xmax = 1270000.97, ymax = 1097196.15) -##' -##' # read in glatos receivers object -##' rec_file <- system.file("extdata", "sample_receivers.csv", package="glatos") -##' recs <- read_glatos_receivers(rec_file) -##' -##' # extract receivers in "HECWL" project -##' # all receiver stations except one is in Lake Huron -##' recs <- recs[recs$glatos_project == "HECWL",] -##' -##' # remove two stations not in Lake Huron -##' recs <- recs[!recs$glatos_array %in% c("MAU","LVD"),] -##' -##' # convert recs to simple feature object (sf) -##' recs <- sf::st_as_sf(recs, coords = c("deploy_long", "deploy_lat"), crs = 4326 ) -##' -##' # transform receivers to same projection as great lakes polygon -##' recs <- sf::st_transform(recs, crs = 3175) -##' -##' # check by plotting -##' plot(sf::st_geometry(poly), col = NA) -##' plot(sf::st_geometry(recs), col = "red", add = TRUE) -##' -##' # create slightly higher resolution transition layer -##' tst1 <- make_transition3(poly, res = c(0.01, 0.01), receiver_points = recs) -##' -##' # plot raster layer -##' plot(terra::rast(tst1$rast)) -##' plot(sf::st_transform(sf::st_geometry(recs), crs = 4326), add = TRUE, col = "red", pch = 20) -##' -##' # plot transition layer -##' raster::plot(raster::raster(tst1$transition)) -##' -##' -##' @export +#' Create transition layer from polygon shapefile +#' +#' Create transition layer for [interpolate_path] from polygon shapefile. +#' +#' @param poly A spatial polygon object of class +#' [SpatialPolygonsDataFrame][SpatialPolygons] or a +#' [sf::sf()][sf::sf] object with a geometry column of polygon +#' and/or multipolygon objects. +#' +#' @param res two element vector that specifies the x and y dimension +#' of output raster cells. Units of res are same as input +#' shapefile. +#' +#' @param receiver_points A SpatialPointsDataFrame object that +#' contains coordinates of receivers dataset or a "glatos_receivers" object. +#' +#' @param epsg coordinate reference code that describes projection +#' used for map calculation and rasterization. Defaults to +#' NAD83/Great Lakes and St. Lawrence Albers. +#' +#' @details `make_transition` uses [fasterize][fasterize::fasterize] +#' to convert a polygon shapefile into a raster layer and +#' geo-corrected transition layer [interpolate_path]. Raster +#' cell values on land equal 1 cells in water equal 0. Output is a +#' two-object list containing the raster layer and transition +#' layer. Both objects have the same extents and geographic +#' projection as input shapefile. +#' +#' @details If receiver\_points is provided, any receiver not in water +#' is buffered by the distance from the receiver to the nearest +#' water. This allows all receivers to be coded as in water if the +#' receiver is on land. +#' +#' @details Poly object is transformed into planer map projection +#' specified by epsg argument for calculation of transition object +#' if receiver_points is provided. Output is projected to WGS84 +#' (epsg- 4326). +#' +#' @details output transition layer is corrected for projection +#' distortions using `gdistance::geoCorrection`. Adjacent +#' cells are connected by 16 directions and transition function +#' returns 0 (land) for movements between land and water and 1 for +#' all over-water movements. +#' +#' +#' @return A list with two elements: +#' \describe{ +#' \item{transition}{a geo-corrected transition raster layer where land = 0 +#' and water=1 +#' (see `gdistance`)} +#' \item{rast}{rasterized input layer of class `raster`}} +#' Additonally, rasterized version of input shapefile (*.tif extension) is written to computer +#' at `output_dir` +#' +#' +#' @author Todd Hayden, Tom Binder, Chris Holbrook +#' +#' @examples +#' +#' # Example 1 - read from SpatialPolygonsDataFrame +#' # use example polygon for Great lakes +#' +#' # get polygon of the Great Lakes +#' data(great_lakes_polygon) # glatos example data; a sf polygon object +#' +#' # make_transition layer +#' tst <- make_transition3(great_lakes_polygon, res = c(0.1, 0.1)) +#' +#' # plot raster layer +#' # notice land = 1, water = 0 +#' raster::plot(tst$rast) +#' +#' # compare to polygon +#' plot(sf::st_geometry(great_lakes_polygon), add = TRUE, fill = NA) +#' +#' # Example 2 - read from ESRI Shapefile and include receiver file +#' # to account for any receivers outside of great lakes polygon +#' +#' # path to polygon shapefile +#' poly <- system.file("extdata", "shoreline.zip", package = "glatos") +#' poly <- sf::st_read(paste0("/vsizip/", poly)) +#' +#' # read in glatos receivers object +#' rec_file <- system.file("extdata", "sample_receivers.csv", package = "glatos") +#' recs <- read_glatos_receivers(rec_file) +#' +#' # change a coordinate to on-land to show impact... +#' recs[1, "deploy_lat"] <- recs[1, "deploy_lat"] + 4 +#' +#' # make_transition layer +#' tst <- make_transition3(poly, res = c(0.1, 0.1), receiver_points = recs) +#' +#' # plot raster layer +#' # notice the huge circle rasterized as "water" north of Lake Superior. +#' # This occurred because we had a "receiver" deployed at that locations +#' raster::plot(tst$rast) +#' points(recs$deploy_long, recs$deploy_lat, col = "red", pch = 20) +#' +#' # plot transition layer +#' raster::plot(raster::raster(tst$transition)) +#' +#' # Example 3- transition layer of Lake Huron only with receivers +#' +#' # read polygon layer of Great Lakes +#' data(great_lakes_polygon) +#' +#' # transform to great lakes projection +#' poly <- sf::st_transform(great_lakes_polygon, crs = 3175) +#' +#' # set attribute-geometry relationship to constant. +#' # this avoids error when cropping +#' sf::st_agr(poly) <- "constant" +#' +#' # crop Great lakes polygon file +#' poly <- sf::st_crop( +#' x = poly, xmin = 829242.55, ymin = 698928.27, +#' xmax = 1270000.97, ymax = 1097196.15 +#' ) +#' +#' # read in glatos receivers object +#' rec_file <- system.file("extdata", "sample_receivers.csv", package = "glatos") +#' recs <- read_glatos_receivers(rec_file) +#' +#' # extract receivers in "HECWL" project +#' # all receiver stations except one is in Lake Huron +#' recs <- recs[recs$glatos_project == "HECWL", ] +#' +#' # remove two stations not in Lake Huron +#' recs <- recs[!recs$glatos_array %in% c("MAU", "LVD"), ] +#' +#' # convert recs to simple feature object (sf) +#' recs <- sf::st_as_sf(recs, coords = c("deploy_long", "deploy_lat"), crs = 4326) +#' +#' # transform receivers to same projection as great lakes polygon +#' recs <- sf::st_transform(recs, crs = 3175) +#' +#' # check by plotting +#' plot(sf::st_geometry(poly), col = NA) +#' plot(sf::st_geometry(recs), col = "red", add = TRUE) +#' +#' # create slightly higher resolution transition layer +#' tst1 <- make_transition3(poly, res = c(0.01, 0.01), receiver_points = recs) +#' +#' # plot raster layer +#' raster::plot(tst1$rast) +#' plot(sf::st_transform(sf::st_geometry(recs), crs = 4326), +#' add = TRUE, col = "red", pch = 20 +#' ) +#' +#' # plot transition layer +#' raster::plot(raster::raster(tst1$transition)) +#' +#' @export make_transition3 <- function(poly, res = c(0.1, 0.1), receiver_points = NULL, epsg = 3175) { message("Making transition layer...") diff --git a/man/REI.Rd b/man/REI.Rd index 77c5bd22..a4ff9312 100644 --- a/man/REI.Rd +++ b/man/REI.Rd @@ -41,6 +41,7 @@ REI = (Tr/Ta) x (Sr/Sa) x (DDr/DDa) x (Da/Dr) } } \examples{ +\dontrun{ det_file <- system.file("extdata", "hfx_detections.csv", package = "glatos" ) @@ -53,7 +54,7 @@ hfx_deployments <- glatos::read_otn_deployments(dep_file) dets <- glatos::read_otn_detections(det_file) hfx_receiver_efficiency_index <- glatos::REI(dets, hfx_deployments) - +} } \author{ Alex Nunes \email{anunes@dal.ca} diff --git a/man/calc_collision_prob.Rd b/man/calc_collision_prob.Rd index 75059668..9720a91a 100644 --- a/man/calc_collision_prob.Rd +++ b/man/calc_collision_prob.Rd @@ -55,17 +55,23 @@ no other variables influence detection probability) and assuming that all tags are co-located at a receiver for the duration of the simulation. } \examples{ -#parameters analagous to Vemco tag, global coding, 45 s nominal delay -foo <- calc_collision_prob(delayRng = c(45, 90), burstDur = 5.12, maxTags = 50, - nTrans = 10000) - -#plot probabilities of detection -plot(med~nTags, data=foo, type='p', pch=20, ylim=c(0,1), - b - -#plot probability of collision by subtracting detection probability from 1 -plot((1 - med)~nTags, data=foo, type='p', pch=20, ylim=c(0,1), - xlab="# of transmitters within range", ylab="Probability of collision") +# parameters analagous to Vemco tag, global coding, 45 s nominal delay +foo <- calc_collision_prob( + delayRng = c(45, 90), burstDur = 5.12, maxTags = 50, + nTrans = 10000 +) + +# plot probabilities of detection +plot(med ~ nTags, + data = foo, type = "p", pch = 20, ylim = c(0, 1), + xlab = "# of transmitters within range", ylab = "Probability of detection" +) + +# plot probability of collision by subtracting detection probability from 1 +plot((1 - med) ~ nTags, + data = foo, type = "p", pch = 20, ylim = c(0, 1), + xlab = "# of transmitters within range", ylab = "Probability of collision" +) } \references{ diff --git a/man/convert_otn_to_att.Rd b/man/convert_otn_to_att.Rd index 0d3a0bf8..f581bbf4 100644 --- a/man/convert_otn_to_att.Rd +++ b/man/convert_otn_to_att.Rd @@ -11,7 +11,7 @@ convert_otn_to_att( deploymentObj = NULL, deploymentSheet = NULL, timeFilter = TRUE, - crs = sf::st_crs(3426) + crs = sf::st_crs(4326) ) } \arguments{ @@ -52,7 +52,7 @@ are found here: https://github.com/ocean-tracking-network/glatos/issues/75#issue in a comment by Ryan Gosse. } \examples{ - +\dontrun{ #-------------------------------------------------- # EXAMPLE #1 - loading from Deployment Object @@ -73,7 +73,7 @@ tags <- prepare_tag_sheet(tag_path, 5, 2) deploy <- read_otn_deployments(deploy_path) ATTdata <- convert_otn_to_att(dets, tags, deploymentObj = deploy) - +} #-------------------------------------------------- # EXAMPLE #2 - loading from Deployment Sheet diff --git a/man/glatos_animals.Rd b/man/glatos_animals.Rd index 207f92eb..36401af8 100644 --- a/man/glatos_animals.Rd +++ b/man/glatos_animals.Rd @@ -108,6 +108,8 @@ x_tbl <- as_tibble(x) ga_tbl <- as_glatos_animals(x_tbl) +# All below will error as invalid + # data.frame input; missing column name library(dplyr) # for rename x2 <- rename(x, @@ -115,17 +117,19 @@ x2 <- rename(x, release_timestamp = utc_release_date_time ) -ga2 <- as_glatos_animals(x2) - +try( + ga2 <- as_glatos_animals(x2) +) -# data.grame input; wrong column class +# data.frame input; wrong column class x3 <- mutate(x, animal_id = as.integer(animal_id), utc_release_date_time = as.character(utc_release_date_time) ) -ga3 <- as_glatos_animals(x3) - +try( + ga3 <- as_glatos_animals(x3) +) # Validation and checking diff --git a/man/glatos_detections.Rd b/man/glatos_detections.Rd index edbf8d43..c389708a 100644 --- a/man/glatos_detections.Rd +++ b/man/glatos_detections.Rd @@ -110,6 +110,8 @@ x_tbl <- as_tibble(x) gd_tbl <- as_glatos_detections(x_tbl) +# All below will error as invalid + # data.frame input; missing column name library(dplyr) # for rename x2 <- rename(x, @@ -117,8 +119,9 @@ x2 <- rename(x, det_date_time = detection_timestamp_utc ) -gd2 <- as_glatos_detections(x2) - +try( + gd2 <- as_glatos_detections(x2) +) # data.frame input; wrong column class x3 <- mutate(x, @@ -126,8 +129,9 @@ x3 <- mutate(x, detection_timestamp_utc = as.character(detection_timestamp_utc) ) -gr3 <- as_glatos_detections(x3) - +try( + gr3 <- as_glatos_detections(x3) +) # Validation and checking diff --git a/man/glatos_receivers.Rd b/man/glatos_receivers.Rd index 70cbe91e..1d533a59 100644 --- a/man/glatos_receivers.Rd +++ b/man/glatos_receivers.Rd @@ -123,6 +123,7 @@ x_tbl <- as_tibble(x) gr_tbl <- as_glatos_receivers(x_tbl) +# All below will error as invalid # data.frame input; missing column name library(dplyr) # for rename @@ -131,8 +132,9 @@ x2 <- rename(x, deploy_timestamp = deploy_date_time ) -gr2 <- as_glatos_receivers(x2) - +try( + gr2 <- as_glatos_receivers(x2) +) # data.frame input; wrong column class x3 <- mutate(x, @@ -140,8 +142,9 @@ x3 <- mutate(x, deploy_date_time = as.character(deploy_date_time) ) -gr3 <- as_glatos_receivers(x3) - +try( + gr3 <- as_glatos_receivers(x3) +) # Validation and checking diff --git a/man/kml_to_csv.Rd b/man/kml_to_csv.Rd index b2f470aa..80c64206 100644 --- a/man/kml_to_csv.Rd +++ b/man/kml_to_csv.Rd @@ -35,7 +35,7 @@ saved as kml. Or extract (unzip) kml from kmz. \examples{ # Get example kml with two polygons -kml_file <- system.file("inst/extdata", "example_polygons.kml", +kml_file <- system.file("extdata", "example_polygons.kml", package = "glatos" ) diff --git a/man/make_transition3.Rd b/man/make_transition3.Rd index cd31ce4a..24d8dfbd 100644 --- a/man/make_transition3.Rd +++ b/man/make_transition3.Rd @@ -63,36 +63,35 @@ all over-water movements. } \examples{ -#Example 1 - read from SpatialPolygonsDataFrame +# Example 1 - read from SpatialPolygonsDataFrame # use example polygon for Great lakes -#get polygon of the Great Lakes -data(great_lakes_polygon) #glatos example data; a sf polygon object +# get polygon of the Great Lakes +data(great_lakes_polygon) # glatos example data; a sf polygon object # make_transition layer tst <- make_transition3(great_lakes_polygon, res = c(0.1, 0.1)) # plot raster layer # notice land = 1, water = 0 -plot(terra::rast(tst$rast)) +raster::plot(tst$rast) -#compare to polygon -plot(st_geometry(great_lakes_polygon), add = TRUE, fill = NA) +# compare to polygon +plot(sf::st_geometry(great_lakes_polygon), add = TRUE, fill = NA) -#Example 2 - read from ESRI Shapefile and include receiver file +# Example 2 - read from ESRI Shapefile and include receiver file # to account for any receivers outside of great lakes polygon # path to polygon shapefile poly <- system.file("extdata", "shoreline.zip", package = "glatos") -poly <- unzip(poly, exdir = tempdir()) -poly <- sf::st_read(poly[grepl("*.shp", poly)]) +poly <- sf::st_read(paste0("/vsizip/", poly)) # read in glatos receivers object -rec_file <- system.file("extdata", "sample_receivers.csv", package="glatos") +rec_file <- system.file("extdata", "sample_receivers.csv", package = "glatos") recs <- read_glatos_receivers(rec_file) # change a coordinate to on-land to show impact... -recs[1, "deploy_lat"] <- recs[1,"deploy_lat"]+4 +recs[1, "deploy_lat"] <- recs[1, "deploy_lat"] + 4 # make_transition layer tst <- make_transition3(poly, res = c(0.1, 0.1), receiver_points = recs) @@ -100,13 +99,13 @@ tst <- make_transition3(poly, res = c(0.1, 0.1), receiver_points = recs) # plot raster layer # notice the huge circle rasterized as "water" north of Lake Superior. # This occurred because we had a "receiver" deployed at that locations -plot(terra::rast(tst$rast)) +raster::plot(tst$rast) points(recs$deploy_long, recs$deploy_lat, col = "red", pch = 20) # plot transition layer -plot(raster::raster(tst$transition)) +raster::plot(raster::raster(tst$transition)) -Example 3- transition layer of Lake Huron only with receivers +# Example 3- transition layer of Lake Huron only with receivers # read polygon layer of Great Lakes data(great_lakes_polygon) @@ -116,25 +115,27 @@ poly <- sf::st_transform(great_lakes_polygon, crs = 3175) # set attribute-geometry relationship to constant. # this avoids error when cropping -sf::st_agr(poly) = "constant" +sf::st_agr(poly) <- "constant" # crop Great lakes polygon file -poly <- sf::st_crop(x = poly, xmin = 829242.55, ymin = 698928.27, - xmax = 1270000.97, ymax = 1097196.15) +poly <- sf::st_crop( + x = poly, xmin = 829242.55, ymin = 698928.27, + xmax = 1270000.97, ymax = 1097196.15 +) # read in glatos receivers object -rec_file <- system.file("extdata", "sample_receivers.csv", package="glatos") +rec_file <- system.file("extdata", "sample_receivers.csv", package = "glatos") recs <- read_glatos_receivers(rec_file) # extract receivers in "HECWL" project # all receiver stations except one is in Lake Huron -recs <- recs[recs$glatos_project == "HECWL",] +recs <- recs[recs$glatos_project == "HECWL", ] # remove two stations not in Lake Huron -recs <- recs[!recs$glatos_array \%in\% c("MAU","LVD"),] +recs <- recs[!recs$glatos_array \%in\% c("MAU", "LVD"), ] # convert recs to simple feature object (sf) -recs <- sf::st_as_sf(recs, coords = c("deploy_long", "deploy_lat"), crs = 4326 ) +recs <- sf::st_as_sf(recs, coords = c("deploy_long", "deploy_lat"), crs = 4326) # transform receivers to same projection as great lakes polygon recs <- sf::st_transform(recs, crs = 3175) @@ -147,13 +148,14 @@ plot(sf::st_geometry(recs), col = "red", add = TRUE) tst1 <- make_transition3(poly, res = c(0.01, 0.01), receiver_points = recs) # plot raster layer -plot(terra::rast(tst1$rast)) -plot(sf::st_transform(sf::st_geometry(recs), crs = 4326), add = TRUE, col = "red", pch = 20) +raster::plot(tst1$rast) +plot(sf::st_transform(sf::st_geometry(recs), crs = 4326), + add = TRUE, col = "red", pch = 20 +) # plot transition layer raster::plot(raster::raster(tst1$transition)) - } \author{ Todd Hayden, Tom Binder, Chris Holbrook diff --git a/man/read_otn_deployments.Rd b/man/read_otn_deployments.Rd index aa9c88b6..ead0dbfb 100644 --- a/man/read_otn_deployments.Rd +++ b/man/read_otn_deployments.Rd @@ -42,11 +42,13 @@ Column names are changed to match GLATOS standard columns when possible. Otherwise, OTN columns and column names are retained. } \examples{ +\dontrun{ # get path to example deployments file deployment_file <- system.file("extdata", "hfx_deployments.csv", package = "glatos" ) dep <- read_otn_deployments(deployment_file) +} } \author{ diff --git a/man/read_vdat_csv.Rd b/man/read_vdat_csv.Rd index 4b15428d..d8a681dd 100644 --- a/man/read_vdat_csv.Rd +++ b/man/read_vdat_csv.Rd @@ -40,32 +40,37 @@ rounded down) to the nearest second. To maintain the full resolution present in the input Fathom CSV file, set \code{options(digits.secs = 6)}. } \examples{ - +\dontrun{ # Example 1. Read a single file -vrl_file <- system.file("extdata", "detection_files_raw", - "VR2W_109924_20110718_1.vrl", package="glatos") +vrl_file <- system.file("extdata", "detection_files_raw", + "VR2W_109924_20110718_1.vrl", + package = "glatos" +) temp_dir <- tempdir() csv_file <- vdat_convert(vrl_file, out_dir = temp_dir) -#utils::browseURL(temp_dir) +# utils::browseURL(temp_dir) -#read all record types +# read all record types vdat <- read_vdat_csv(csv_file) -#read only one record type +# read only one record type vdat <- read_vdat_csv(csv_file, record_types = c("DET")) - + # Example 2. Read and combine detection records from multiple files # get two example files vrl_files <- system.file("extdata", "detection_files_raw", - c("VR2W_109924_20110718_1.vrl", - "HR2-180 461396 2021-04-20 173145.vdat"), - package="glatos") + c( + "VR2W_109924_20110718_1.vrl", + "HR2-180 461396 2021-04-20 173145.vdat" + ), + package = "glatos" +) csv_files <- vdat_convert(vrl_files, out_dir = temp_dir) @@ -74,35 +79,40 @@ csv_files <- vdat_convert(vrl_files, out_dir = temp_dir) library(dplyr) -# basic steps: import each to list element, subset DET records, - add column with source file name, combine. - -det2_tbl <- csv_files \%>\% - lapply( - function(x) { - read_vdat_csv(x, record_types = "DET")$DET \%>\% - as_tibble \%>\% - mutate(source_file = basename(x)) - }) \%>\% - bind_rows +# basic steps: import each to list element, subset DET records, +# add column with source file name, combine. + +det2_tbl <- csv_files \%>\% + lapply( + function(x) { + read_vdat_csv(x, record_types = "DET")$DET \%>\% + as_tibble() \%>\% + mutate(source_file = basename(x)) + } + ) \%>\% + bind_rows() -#using data.table +# using data.table library(data.table) det2_dt <- rbindlist( - lapply(csv_files, - function(x) { - read_vdat_csv(x, record_types = "DET")$DET[, - source_file := basename(x)] - })) - -\dontrun{ + lapply( + csv_files, + function(x) { + read_vdat_csv(x, record_types = "DET")$DET[ + , + source_file := basename(x) + ] + } + ) +) + # get current version of digits.secs op_digits.secs <- options()$digits.secs - + # set digits.secs = NULL (default, truncates to nearest second) options(digits.secs = NULL) @@ -121,7 +131,6 @@ options(digits.secs = op_digits.secs) # or specify via format \%OSn e.g., when writing to disk or external database # see ?strptime format(vdat$DET$Time[2], format = "\%Y-\%m-\%d \%H:\%M:\%OS6") - } } diff --git a/man/receiver_line_det_sim.Rd b/man/receiver_line_det_sim.Rd index 70a4811c..8df77c71 100644 --- a/man/receiver_line_det_sim.Rd +++ b/man/receiver_line_det_sim.Rd @@ -100,20 +100,20 @@ dp <- receiver_line_det_sim(rngFun = pdrf) dp # Again with only 10 virtual fish and optional plot to see simulated data -dp <- receiver_line_det_sim(rngFun = pdrf, nsim = 10, showPlot = T) # w/ optional plot +dp <- receiver_line_det_sim(rngFun = pdrf, nsim = 10, showPlot = TRUE) # w/ optional plot dp # Again but six receivers and allow fish to pass to left and right of line dp <- receiver_line_det_sim( rngFun = pdrf, recSpc = rep(1000, 5), - outerLim = c(1000, 1000), nsim = 10, showPlot = T + outerLim = c(1000, 1000), nsim = 10, showPlot = TRUE ) dp # Again but four receivers with irregular spacing dp <- receiver_line_det_sim( rngFun = pdrf, recSpc = c(2000, 4000, 2000), - outerLim = c(1000, 1000), nsim = 10, showPlot = T + outerLim = c(1000, 1000), nsim = 10, showPlot = TRUE ) dp @@ -180,7 +180,7 @@ plot(edrf(0:2000), ) # use empirical curve (edrf) in simulation -dp <- receiver_line_det_sim(rngFun = edrf, nsim = 10, showPlot = T) # w/ optional plot +dp <- receiver_line_det_sim(rngFun = edrf, nsim = 10, showPlot = TRUE) # w/ optional plot dp } diff --git a/man/vrl2csv-deprecated.Rd b/man/vrl2csv-deprecated.Rd index 28f5e77a..cf90cd60 100644 --- a/man/vrl2csv-deprecated.Rd +++ b/man/vrl2csv-deprecated.Rd @@ -64,7 +64,7 @@ vrl2csv(dirname(myVRL)) # directory input vrl2csv(myVRL) # file name input # setting 'overwrite=FALSE' will make new file with '_n'added to name -vrl2csv(myVRL, overwrite = F) +vrl2csv(myVRL, overwrite = FALSE) } } diff --git a/man/write_vdat_csv.Rd b/man/write_vdat_csv.Rd index fdf19361..c2b9080a 100644 --- a/man/write_vdat_csv.Rd +++ b/man/write_vdat_csv.Rd @@ -58,6 +58,7 @@ Write a vdat_list object to disk in Innovasea Fathom VDAT CSV format Writing is done via \code{\link[data.table]{fwrite}}. } \examples{ +\dontrun{ # Example 1. Read and write a single file @@ -80,7 +81,7 @@ write_vdat_csv(vdat) # write to multiple files write_vdat_csv(vdat, output_format = "csv.fathom.split") - +} } \author{ C. Holbrook (cholbrook@usgs.gov)