From 44cdc79593a8bd5730ecf00b6283555bc4d9afda Mon Sep 17 00:00:00 2001 From: Ethan Plunkett Date: Thu, 9 Oct 2025 16:10:12 -0400 Subject: [PATCH 1/6] fix: use clean local cache for testing --- DESCRIPTION | 3 ++- tests/testthat/setup.R | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 900ea82..9d42b35 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -18,7 +18,8 @@ Imports: Suggests: testthat (>= 3.0.0), callthat, - httr + httr, + withr Config/testthat/edition: 3 Remotes: birdflow-science/BirdFlowR, diff --git a/tests/testthat/setup.R b/tests/testthat/setup.R index f4be360..f1aad43 100644 --- a/tests/testthat/setup.R +++ b/tests/testthat/setup.R @@ -1,2 +1,13 @@ load_models() set_s3_config() + + +# Set the cache directory to a new tempdir for the duration of the tests. +# and delete it after tests complete. +# If running individual tests manually don't run this code. +original_local_temp <- get_s3_config()$local_temp +local_temp <- withr::local_tempdir("cache", .local_envir = teardown_env()) +s3_config$local_temp <- local_temp +withr::defer( + s3_config$local_temp <- original_local_temp, envir = teardown_env() + ) From 16b689a2379d23d52f19511626ae3e5dd20bac39 Mon Sep 17 00:00:00 2001 From: Ethan Plunkett Date: Thu, 9 Oct 2025 16:11:44 -0400 Subject: [PATCH 2/6] feat: test total (taxa) and NA extent in result --- tests/testthat/test-flow.R | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/testthat/test-flow.R b/tests/testthat/test-flow.R index c879951..31f8b1e 100644 --- a/tests/testthat/test-flow.R +++ b/tests/testthat/test-flow.R @@ -113,3 +113,29 @@ test_that("result contents are valid (inflow)", { expect_true(row$type == "inflow") } }) + + + +test_that("total is not constrained by indivual taxa NAs", { + params <- standard_flow_input() + + # Make a total projection + params$taxa <- "total" + expect_no_error(total_result <- do.call(flow, params)) + total <- terra::rast(total_result$geotiff) + + # Same start but for american black duck + params$taxa <- "ambduc" + expect_no_error(ambduc_result <- do.call(flow, params)) + ambduc <- terra::rast(ambduc_result$geotiff) + + # There should be more NA's in the American black duck result than in the total + ambduc_nas <- terra::values(ambduc) |> is.na() |> sum() + total_nas <- terra::values(total) |> is.na() |> sum() + expect_true(ambduc_nas > total_nas) + + # The total should not be NA anywhere that ambduc is not NA + n_wrong <- (is.na(total) & !is.na(ambduc)) |> terra::values() |> sum() + expect_equal(n_wrong, 0) + +}) From 8b616f07f9502e3cc84a18952d56e33d3d396d54 Mon Sep 17 00:00:00 2001 From: Ethan Plunkett Date: Thu, 9 Oct 2025 16:22:37 -0400 Subject: [PATCH 3/6] fix: stop constraining total extent where species output is NA --- R/flow.R | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/R/flow.R b/R/flow.R index b99a9d1..88d4a22 100644 --- a/R/flow.R +++ b/R/flow.R @@ -195,6 +195,7 @@ flow <- function(loc, week, taxa, n, direction = "forward", save_local = FALSE) combined <- NULL any_valid <- FALSE + for (i in seq_along(target_species)) { sp <- target_species[i] bf <- models[[sp]] @@ -215,6 +216,10 @@ flow <- function(loc, week, taxa, n, direction = "forward", save_local = FALSE) start_proportion <- sum(initial_population_distr[location_i]) / 1 abundance <- pred * species$population[species$species == sp] / prod(terra::res(bf) / 1000) * start_proportion this_raster <- BirdFlowR::rasterize_distr(abundance, bf = bf, format = "terra") + + # Make NA zero (for adding) + this_raster[is.na(this_raster)] <- 0 + if (is.null(combined)) { combined <- this_raster } else { @@ -222,6 +227,9 @@ flow <- function(loc, week, taxa, n, direction = "forward", save_local = FALSE) } } + # Make zeros transparent + combined[combined == 0] <- NA + if (!any_valid) { log_progress("No valid starting location. Returning error.") return(format_error("Invalid starting location", "outside mask")) From ec641c74bac778d522c5c4cdd07a99cee75ecbb6 Mon Sep 17 00:00:00 2001 From: Ethan Plunkett Date: Thu, 9 Oct 2025 17:00:55 -0400 Subject: [PATCH 4/6] cleanup notes in package check --- .Rbuildignore | 2 ++ LICENSE | 23 ++--------------------- R/data.R | 3 +++ R/flow.R | 1 + 4 files changed, 8 insertions(+), 21 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index 5f6442b..f447d53 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -4,3 +4,5 @@ ^LICENSE\.md$ ^data-raw$ ^data_pipeline$ +^localtmp$ +^flow_debug.log diff --git a/LICENSE b/LICENSE index cc9ad5d..8e1e275 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,2 @@ -MIT License - -Copyright (c) 2025 UMass Amherst Center for Data Science & AI - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +YEAR: 2025 +COPYRIGHT HOLDER: UMassCDS diff --git a/R/data.R b/R/data.R index c21abe1..98b608d 100644 --- a/R/data.R +++ b/R/data.R @@ -56,3 +56,6 @@ #' \item{"jitter_radius"}{Jitter radius in meters} #' } "counties_json" + +# Declare these as global variables so package check doesn't flag them +utils::globalVariables(c("species", "flow_colors")) diff --git a/R/flow.R b/R/flow.R index 88d4a22..20e4bf4 100644 --- a/R/flow.R +++ b/R/flow.R @@ -62,6 +62,7 @@ save_local_path <- "config/save_local.flag" #' `legend` #' `type` #' @export +#' @importFrom stats predict flow <- function(loc, week, taxa, n, direction = "forward", save_local = FALSE) { s3_cfg <- get_s3_config() s3_enabled <- !is.na(s3_cfg$bucket) && nzchar(s3_cfg$bucket) From ee42239a2c467ef04a8acebb61283b1f4bcf6c43 Mon Sep 17 00:00:00 2001 From: Ethan Plunkett Date: Thu, 9 Oct 2025 17:01:38 -0400 Subject: [PATCH 5/6] rebuild documenation --- NAMESPACE | 3 +++ man/get_s3_config.Rd | 14 ++++++++++++++ man/set_s3_config.Rd | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 man/get_s3_config.Rd create mode 100644 man/set_s3_config.Rd diff --git a/NAMESPACE b/NAMESPACE index fc4818b..5574c52 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,7 +1,10 @@ # Generated by roxygen2: do not edit by hand export(flow) +export(get_s3_config) export(load_models) export(range_rescale) export(save_json_palette) +export(set_s3_config) export(symbolize_raster_data) +importFrom(stats,predict) diff --git a/man/get_s3_config.Rd b/man/get_s3_config.Rd new file mode 100644 index 0000000..07497d3 --- /dev/null +++ b/man/get_s3_config.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/s3_config.R +\name{get_s3_config} +\alias{get_s3_config} +\title{Get S3 Configuration} +\usage{ +get_s3_config() +} +\value{ +List of S3 configuration values +} +\description{ +Get S3 Configuration +} diff --git a/man/set_s3_config.Rd b/man/set_s3_config.Rd new file mode 100644 index 0000000..6fa6c91 --- /dev/null +++ b/man/set_s3_config.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/s3_config.R +\name{set_s3_config} +\alias{set_s3_config} +\title{Set S3 Configuration} +\usage{ +set_s3_config( + access_key = NULL, + secret_key = NULL, + region = NULL, + bucket = NULL, + log = TRUE, + log_file_path = "./flow_debug.log", + local_temp_path = "localtmp" +) +} +\arguments{ +\item{access_key}{AWS access key (default: NULL)} + +\item{secret_key}{AWS secret key (default: NULL)} + +\item{region}{AWS region (default: NULL)} + +\item{bucket}{S3 bucket name (default: NULL)} + +\item{log}{Enable logging (default: TRUE)} + +\item{log_file_path}{Path for log file (default: "./flow_debug.log")} + +\item{local_temp_path}{Path for local temp files (default: "localtmp")} +} +\description{ +Set S3 Configuration +} From 11f65cf01f1da36023b2c3c1624e8ce632585f2b Mon Sep 17 00:00:00 2001 From: Atharva Shahane Date: Fri, 10 Oct 2025 11:55:36 -0400 Subject: [PATCH 6/6] style: spelling --- tests/testthat/test-flow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-flow.R b/tests/testthat/test-flow.R index 31f8b1e..d79ff9b 100644 --- a/tests/testthat/test-flow.R +++ b/tests/testthat/test-flow.R @@ -116,7 +116,7 @@ test_that("result contents are valid (inflow)", { -test_that("total is not constrained by indivual taxa NAs", { +test_that("total is not constrained by individual taxa NAs", { params <- standard_flow_input() # Make a total projection