diff --git a/Dockerfile b/Dockerfile index 93f57421..84ff27fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # start with the ropensci image including debian:testing, r-base, rocker/rstudio, rocker/hadleyverse # https://hub.docker.com/r/rocker/ropensci/ -FROM quay.io/battelleecology/rstudio:4.0.5 +FROM ghcr.io/rocker-org/geospatial:4.2.2 WORKDIR /home/eddy/eddy4R diff --git a/flow/tool/flow.aop.slp.towr.R b/flow/tool/flow.aop.slp.towr.R new file mode 100644 index 00000000..81775866 --- /dev/null +++ b/flow/tool/flow.aop.slp.towr.R @@ -0,0 +1,477 @@ +# install.packages(c("neonUtilities","terra","sf","dplyr","stringr","plotly", "openxlsx")) +library(neonUtilities) +library(terra) +library(sf) +library(dplyr) +library(stringr) +library(plotly) + +library(remotes) +#install_github('NEONScience/NEON-geolocation/geoNEON', dependencies=TRUE) +library(geoNEON) +library(openxlsx) + + +############################################################# +#Workflow parameters +############################################################# + +# ----------------------------- +# 1) SITE SETTINGS +# ----------------------------- +#Which NEON site are we grabbing data from (4-letter ID) +setSite <- c("BARR","CLBJ","MLBS","DSNY","NIWO","ORNL","OSBS", + "SCBI","LENO","TALL","CPER","BART","HARV","BLAN", + "SERC","JERC","GUAN","LAJA","STEI","TREE","UNDE", + "KONA","KONZ","UKFS","GRSM","DELA","DCFS","NOGP", + "WOOD","RMNP","OAES","YELL","MOAB","STER","JORN", + "SRER","ONAQ","ABBY","WREF","SJER","SOAP","TEAK", + "TOOL","BONA","DEJU","HEAL","PUUM") [3:47] + + + +setSite <- "SCBI" # NEON site if just running a single site (comment out if running all sites) +#AngZaxsSoniInst <- NULL #Azimuth angle of sonic anemometer deployment + +#Loop around setSite +for(site in setSite){ + +AngZaxsSoniInst <- 210 #Azimuth angle of sonic anemometer deployment + +#Get site level geolocation metadata +locSite <- geoNEON::getLocBySite(site = site, type = "site") +if(is.null(AngZaxsSoniInst)){ + locSens <- geoNEON::getLocBySite(site = site, type = "TIS", history = F,token = Sys.getenv("NEON_API_TOKEN")) + AngZaxsSoniInst <- as.numeric(locSens[grep("3D Wind L",locSens$locationDescription),]$gammaOrientation) +} + +tower_lat <- as.numeric(locSite$decimalLatitude) # tower latitude (WGS84) +tower_lon <- as.numeric(locSite$decimalLongitude) # tower longitude (WGS84) +utm_easting <- as.numeric(locSite$easting) +utm_northing <- as.numeric(locSite$northing) +utm_zone <- as.numeric(locSite$utmZoneNumber) + +dpID <- "DP3.30025.001" # Slope & Aspect – LiDAR (1‑km tiles) +years <- 2013:as.integer(format(Sys.Date(), "%Y")) + +#dirBase <- paste0("/home/root/eddy/data/neon_slope_aspect") +dirBase <- paste0("/home/root/eddy/data/neon_slope_aspect/reorientation") +dirDnld <- paste0(dirBase,"/dnld") +dirOut <- paste0(dirBase,"/out") +dirPlot <- paste0(dirBase,"/plot") +dir.create(dirBase, showWarnings = FALSE, recursive = TRUE) +dir.create(dirDnld, showWarnings = FALSE, recursive = TRUE) +dir.create(dirOut, showWarnings = FALSE, recursive = TRUE) +dir.create(dirPlot, showWarnings = FALSE, recursive = TRUE) +#api_token <- Sys.getenv("NEON_TOKEN") # optional but recommended, now using internal API + +#Load excel workbook +wb <- loadWorkbook("/home/root/eddy/data/neon_slope_aspect/revisit pitch and roll_2026.xlsx") + + +#Name of worksheet +sheet_name <- "Analysis" +#Add worksheet if needed +if (!(sheet_name %in% names(wb))) { + addWorksheet(wb, sheet_name) + # Read existing data + dfAng <- read.xlsx(wb, sheet = 1) +}else{ + # Read existing data + dfAng <- read.xlsx(wb, sheet = sheet_name)} + +#Check if data exists and angles match from worksheet and database +stopifnot( + nrow(dfAng) > 0, + site %in% dfAng$SITE, + dfAng[which(dfAng$SITE == site),]$AngNedZaxs == AngZaxsSoniInst|dfAng[which(dfAng$SITE == site),]$Reorientation.AngNedZaxs == AngZaxsSoniInst + ) + +# 1‑km AOI centered on tower (±500 m) +box_half_m <- 500 +check_size <- FALSE + +# ----------------------------- +# 2) Lat/Lon -> UTM for HARV +# ----------------------------- +# utm_zone <- floor((tower_lon + 180) / 6) + 1 +epsg <- if (tower_lat >= 0) 32600 + utm_zone else 32700 + utm_zone +# +# pt_ll <- st_as_sf(data.frame(lon=tower_lon, lat=tower_lat), coords=c("lon","lat"), crs=4326) +# pt_utm <- st_transform(pt_ll, crs = sf::st_crs(paste0("EPSG:", epsg))) +# coords <- st_coordinates(pt_utm)[1, ] +# utm_easting <- coords["X"] +# utm_northing <- coords["Y"] + +# Build 1‑km AOI polygon in UTM +aoi_ext <- ext(utm_easting - box_half_m, utm_easting + box_half_m, + utm_northing - box_half_m, utm_northing + box_half_m) +aoi_poly <- as.polygons(aoi_ext, crs = paste0("EPSG:", epsg)) + +# ----------------------------- +# 3) Download Slope/Aspect tiles overlapping the AOI (per year) +# ----------------------------- + + +for (yr in years) { + message(sprintf("Querying %s %s for %s ...", dpID, site, yr)) + try({ + byTileAOP(dpID = dpID, + site = site, + year = yr, + easting = utm_easting, + northing = utm_northing, + buffer = box_half_m, # 500 m -> 1‑km square + include.provisional = FALSE, + check.size = check_size, + savepath = dirDnld, + # token = if (nzchar(api_token)) api_token else NA_character_, + progress = TRUE) + }, silent = TRUE) +} + +# ----------------------------- +# 4) Locate slope & aspect GeoTIFFs +# ----------------------------- +tif_files <- list.files(dirDnld, pattern = "\\.tif(f)?$", recursive = TRUE, full.names = TRUE) +tif_files <- tif_files[grepl("DP3\\.30025", tif_files, ignore.case = TRUE)] + +if (length(tif_files) == 0) stop("No DP3.30025 GeoTIFFs found. Check years and availability.") + +# Identify slope vs aspect by filename (NEON uses consistent naming) +is_slope <- grepl("slope", basename(tif_files), ignore.case = TRUE) +is_aspect <- grepl("aspect", basename(tif_files), ignore.case = TRUE) + +files_slope <- tif_files[is_slope] +files_aspect <- tif_files[is_aspect] + +# Extract acquisition year from folder path (/YYYY/) +extract_year <- function(path) { + y <- str_extract(path, "/(20[0-9]{2})/") + as.integer(gsub("/", "", y)) +} +years_slope <- sapply(files_slope, extract_year) +years_aspect <- sapply(files_aspect, extract_year) + +# ----------------------------- +# 5) Helper functions +# ----------------------------- +# Mosaic list of rasters (only those intersecting the AOI), align CRS, crop to AOI +mosaic_crop <- function(flist, aoi_poly, aoi_ext) { + rlist <- lapply(flist, function(f) { + r <- try(rast(f), silent = TRUE) + # if (inherits(r, "try-error")) return(NULL) + # quick intersect test + # if (!relate(r, vect(aoi_poly), "intersects")[1]) return(NULL) + r + }) + rlist <- Filter(Negate(is.null), rlist) + if (length(rlist) == 0) return(NULL) + rmos <- if (length(rlist) > 1) do.call(mosaic, c(rlist, list(fun = "mean"))) else rlist[[1]] + # if (!compareGeom(rmos, vect(aoi_poly), stopOnError = FALSE)) { + # rmos <- project(rmos, crs(vect(aoi_poly))) + #} + crop(rmos, aoi_ext) +} + +# Circular mean of aspect (degrees 0–360); returns mean aspect (deg) and mean resultant length R (0–1) +circ_mean_aspect <- function(aspect_vals_deg) { + rad <- aspect_vals_deg * pi / 180 + # Remove NA + rad <- rad[is.finite(rad)] + if (length(rad) == 0) return(c(mean_aspect_deg = NA_real_, R = NA_real_)) + C <- mean(cos(rad)) + S <- mean(sin(rad)) + R <- sqrt(C^2 + S^2) + mean_rad <- atan2(S, C) # -pi .. pi + mean_deg <- (mean_rad * 180 / pi) %% 360 + c(mean_aspect_deg = mean_deg, R = R) +} + + +#Function to calculate the sonic pitch and roll +compute_sonic_pitch_roll <- function(slope_deg, aspect_deg, sonic_azimuth_deg) { + + # Convert degrees to radians + deg2rad <- function(d) d * pi / 180 + rad2deg <- function(r) r * 180 / pi + + slope <- deg2rad(slope_deg) + aspect <- deg2rad(aspect_deg) + az <- deg2rad(sonic_azimuth_deg) + + # --- 1. Terrain normal vector (GIS convention: aspect is downslope direction) --- + nx <- sin(slope) * sin(aspect) + ny <- sin(slope) * cos(aspect) + nz <- cos(slope) + + n <- c(nx, ny, nz) + + # --- 2. Sonic coordinate system --- + # Sonic x-axis points toward azimuth (sin = east component, cos = north component) + x0 <- c(sin(az), cos(az), 0) + y0 <- c(cos(az), -sin(az), 0) # Orthogonal horizontal axis + z0 <- c(0, 0, 1) + + # --- 3. Project terrain normal into sonic coordinates --- + nxp <- sum(n * x0) + nyp <- sum(n * y0) + nzp <- sum(n * z0) + + # --- 4. Compute pitch (φ) and roll (ρ) --- + # pitch: rotation about sonic y-axis, positive when pointing up + pitch_rad <- atan2(-nxp, nzp) + + # roll: rotation about sonic x-axis, positive when tilted right (when looking from behind) + roll_rad <- atan2(nyp, nzp) + + # Return degrees + list( + pitch_deg = rad2deg(pitch_rad), + roll_deg = rad2deg(roll_rad), + sonic_azimuth_deg = sonic_azimuth_deg + ) +} + +# Plot terrain plane vs. deployed/rotated sonic plane in 3-D (ENU, x=East y=North z=Up) +plot_sonic_terrain <- function(slope_deg, aspect_deg, sonic_azimuth_deg, fileOut = NULL) { + if (!requireNamespace("plotly", quietly = TRUE)) + stop("Install plotly: install.packages('plotly')") + + deg2rad <- function(d) d * pi / 180 + rad2deg <- function(r) r * 180 / pi + + slope <- deg2rad(slope_deg) + aspect <- deg2rad(aspect_deg) + az <- deg2rad(sonic_azimuth_deg) + + # Terrain normal (ENU) + n <- c( sin(slope)*sin(aspect), sin(slope)*cos(aspect), cos(slope)) + + # Sonic axes as deployed (horizontal, x toward azimuth) + x0 <- c(sin(az), cos(az), 0) + y0 <- c(cos(az), -sin(az), 0) + z0 <- c(0, 0, 1) + + # Sonic axes terrain-aligned: z -> terrain normal, x -> project x0 onto terrain plane + z1 <- n + x1 <- x0 - sum(x0 * n) * n; x1 <- x1 / sqrt(sum(x1^2)) + y1 <- y0 - sum(y0 * n) * n; y1 <- y1 / sqrt(sum(y1^2)) + + # Pitch and roll (matches compute_sonic_pitch_roll) + nxp <- sum(n * x0); nyp <- sum(n * y0); nzp <- sum(n * z0) + pitch_rad <- atan2(-nxp, nzp) + roll_rad <- atan2(nyp, nzp) + pitch_deg <- rad2deg(pitch_rad) + roll_deg <- rad2deg(roll_rad) + + # Build a square patch in the plane of a given normal vector + plane_patch <- function(normal, size = 1.2) { + u <- if (abs(normal[1]) < 0.9) c(1,0,0) else c(0,1,0) + u <- u - sum(u * normal) * normal; u <- u / sqrt(sum(u^2)) + v <- c(normal[2]*u[3]-normal[3]*u[2], + normal[3]*u[1]-normal[1]*u[3], + normal[1]*u[2]-normal[2]*u[1]) + corners <- rbind(-size*u - size*v, + size*u - size*v, + size*u + size*v, + -size*u + size*v, + -size*u - size*v) # closed loop + corners + } + + tp <- plane_patch(n) # terrain plane + sp <- plane_patch(z0) # sonic plane (deployed horizontal) + + # Arc sweeping clockwise from North to azimuth in the horizontal plane + arc_r <- 0.45 + arc_t <- seq(0, az, length.out = max(60L, abs(round(sonic_azimuth_deg)))) + arc_x <- arc_r * sin(arc_t) + arc_y <- arc_r * cos(arc_t) + arc_z <- rep(0, length(arc_t)) + mid <- ceiling(length(arc_t) / 2) + + # Pitch arc: rotation about y0 from z0, sweeping by pitch_rad (positive = z toward -x0) + arc_ang <- 60L + arc_rs <- 0.65 + pt <- seq(0, pitch_rad, length.out = arc_ang) + p_arc <- arc_rs * (outer(cos(pt), z0) - outer(sin(pt), x0)) + p_tang <- -sin(pitch_rad)*z0 - cos(pitch_rad)*x0 # tangent at arc endpoint + p_tang <- p_tang / sqrt(sum(p_tang^2)) + + # Roll arc: rotation about x0 from z0, sweeping by roll_rad (positive = z toward +y0) + rt <- seq(0, roll_rad, length.out = arc_ang) + r_arc <- arc_rs * (outer(cos(rt), z0) + outer(sin(rt), y0)) + r_tang <- -sin(roll_rad)*z0 + cos(roll_rad)*y0 # tangent at arc endpoint + r_tang <- r_tang / sqrt(sum(r_tang^2)) + + fig <- plotly::plot_ly() |> + # --- planes --- + plotly::add_trace(x=tp[,1], y=tp[,2], z=tp[,3], type="scatter3d", mode="lines", + line=list(color="saddlebrown", width=3), name="Terrain plane") |> + plotly::add_trace(x=sp[,1], y=sp[,2], z=sp[,3], type="scatter3d", mode="lines", + line=list(color="steelblue", width=3), name="Sonic plane (deployed)") |> + # --- terrain normal --- + plotly::add_trace(x=c(0,n[1]), y=c(0,n[2]), z=c(0,n[3]), type="scatter3d", mode="lines+markers", + line=list(color="saddlebrown", width=5), + marker=list(color="saddlebrown", size=c(0,7)), name="Terrain normal") |> + # --- deployed sonic axes --- + plotly::add_trace(x=c(0,x0[1]), y=c(0,x0[2]), z=c(0,x0[3]), type="scatter3d", mode="lines+markers", + line=list(color="red", width=4), + marker=list(color="red", size=c(0,6)), name="Sonic x (azimuth, deployed)") |> + plotly::add_trace(x=c(0,y0[1]), y=c(0,y0[2]), z=c(0,y0[3]), type="scatter3d", mode="lines+markers", + line=list(color="steelblue", width=4), + marker=list(color="steelblue", size=c(0,6)), name="Sonic y (deployed)") |> + plotly::add_trace(x=c(0,z0[1]), y=c(0,z0[2]), z=c(0,z0[3]), type="scatter3d", mode="lines+markers", + line=list(color="royalblue", width=4), + marker=list(color="royalblue", size=c(0,6)), name="Sonic z (deployed, vertical)") |> + # --- azimuth arc --- + plotly::add_trace(x=c(0,0), y=c(0,0.6), z=c(0,0), type="scatter3d", mode="lines", + line=list(color="gray50", width=2, dash="dot"), name="North") |> + plotly::add_trace(x=arc_x, y=arc_y, z=arc_z, type="scatter3d", mode="lines", + line=list(color="orange", width=3), + name=sprintf("Azimuth %.1f\u00b0", sonic_azimuth_deg)) |> + plotly::add_trace(x=arc_x[mid], y=arc_y[mid], z=0.05, type="scatter3d", mode="text", + text=sprintf("%.1f\u00b0", sonic_azimuth_deg), + textfont=list(color="orange", size=13), + showlegend=FALSE, name="az label") |> + # --- terrain-aligned sonic axes --- + plotly::add_trace(x=c(0,x1[1]), y=c(0,x1[2]), z=c(0,x1[3]), type="scatter3d", mode="lines+markers", + line=list(color="darkred", width=4, dash="dash"), + marker=list(color="darkred", size=c(0,6)), name="Sonic x (terrain-aligned)") |> + plotly::add_trace(x=c(0,y1[1]), y=c(0,y1[2]), z=c(0,y1[3]), type="scatter3d", mode="lines+markers", + line=list(color="darkgreen", width=4, dash="dash"), + marker=list(color="darkgreen", size=c(0,6)), name="Sonic y (terrain-aligned)") |> + plotly::add_trace(x=c(0,z1[1]), y=c(0,z1[2]), z=c(0,z1[3]), type="scatter3d", mode="lines+markers", + line=list(color="forestgreen",width=4, dash="dash"), + marker=list(color="forestgreen",size=c(0,6)), name="Sonic z (terrain-aligned)") |> + # --- pitch rotation arc --- + plotly::add_trace(x=p_arc[,1], y=p_arc[,2], z=p_arc[,3], type="scatter3d", mode="lines", + line=list(color="tomato", width=4), + name=sprintf("Pitch %.2f\u00b0", pitch_deg)) |> + plotly::add_trace(x=p_arc[arc_ang,1], y=p_arc[arc_ang,2], z=p_arc[arc_ang,3], + u=-p_tang[1]*0.07, v=-p_tang[2]*0.07, w=-p_tang[3]*0.07, + type="cone", anchor="tail", sizemode="absolute", sizeref=0.07, + colorscale=list(list(0,"tomato"),list(1,"tomato")), + showscale=FALSE, showlegend=FALSE, name="pitch arrow") |> + plotly::add_trace(x=p_arc[ceiling(arc_ang/2),1], y=p_arc[ceiling(arc_ang/2),2], + z=p_arc[ceiling(arc_ang/2),3]+0.05, type="scatter3d", mode="text", + text=sprintf("P=%.2f\u00b0", pitch_deg), + textfont=list(color="tomato", size=12), + showlegend=FALSE, name="pitch label") |> + # --- roll rotation arc --- + plotly::add_trace(x=r_arc[,1], y=r_arc[,2], z=r_arc[,3], type="scatter3d", mode="lines", + line=list(color="mediumvioletred", width=4), + name=sprintf("Roll %.2f\u00b0", roll_deg)) |> + plotly::add_trace(x=r_arc[arc_ang,1], y=r_arc[arc_ang,2], z=r_arc[arc_ang,3], + u=-r_tang[1]*0.07, v=-r_tang[2]*0.07, w=-r_tang[3]*0.07, + type="cone", anchor="tail", sizemode="absolute", sizeref=0.07, + colorscale=list(list(0,"mediumvioletred"),list(1,"mediumvioletred")), + showscale=FALSE, showlegend=FALSE, name="roll arrow") |> + plotly::add_trace(x=r_arc[ceiling(arc_ang/2),1], y=r_arc[ceiling(arc_ang/2),2], + z=r_arc[ceiling(arc_ang/2),3]+0.05, type="scatter3d", mode="text", + text=sprintf("R=%.2f\u00b0", roll_deg), + textfont=list(color="mediumvioletred", size=12), + showlegend=FALSE, name="roll label") |> + plotly::layout( + title = sprintf("Slope %.1f\u00b0 | Aspect %.1f\u00b0 | Azimuth %.1f\u00b0 || Pitch %.2f\u00b0 | Roll %.2f\u00b0", + slope_deg, aspect_deg, sonic_azimuth_deg, pitch_deg, roll_deg), + scene = list( + xaxis = list(title="East", range=c(-1.5,1.5)), + yaxis = list(title="North", range=c(-1.5,1.5)), + zaxis = list(title="Up", range=c(-1.5,1.5)), + aspectmode = "cube", + camera = list(eye = list(x=1.5, y=-1.5, z=1.0)) + ) + ) + + print(fig) + if (!is.null(fileOut)) { + htmlwidgets::saveWidget(fig, file = fileOut, selfcontained = TRUE) + message("Plot saved to: ", fileOut) + } + invisible(fig) +} + +# ----------------------------- +# 6) Summaries by year +# ----------------------------- +summaries <- list() + +for (yr in sort(unique(na.omit(c(years_slope, years_aspect))))) { + + # Slope + slope_files_y <- files_slope[years_slope == yr] + slope_crop <- mosaic_crop(flist = slope_files_y, aoi_poly, aoi_ext) + + # Aspect + aspect_files_y <- files_aspect[years_aspect == yr] + aspect_crop <- mosaic_crop(aspect_files_y, aoi_poly, aoi_ext) + + plot(aspect_crop) + if (is.null(slope_crop) & is.null(aspect_crop)) next + + # Mean slope (degrees) + mean_slope <- if (!is.null(slope_crop)) { + as.numeric(global(slope_crop, fun = "mean", na.rm = TRUE)[1,1]) + } else NA_real_ + + # Circular mean aspect (degrees) & R + aspect_stats <- if (!is.null(aspect_crop)) { + vals <- values(aspect_crop, na.rm = TRUE) + # terra::values returns a matrix for multi-layer; ensure vector + vals <- as.numeric(vals) + circ_mean_aspect(vals) + } else c(mean_aspect_deg = NA_real_, R = NA_real_) + + summaries[[as.character(yr)]] <- data.frame( + site = site, + year = yr, + mean_slope_deg = mean_slope, + mean_aspect_deg = aspect_stats["mean_aspect_deg"], + aspect_resultant_R = aspect_stats["R"] + ) +} + +slope_aspect_summary <- bind_rows(summaries) %>% arrange(year) +print(slope_aspect_summary) + +#Calculate the deployment angles for pitch and roll based on new azimuth +outAng <- compute_sonic_pitch_roll(slope_deg = mean(slope_aspect_summary$mean_slope_deg, na.rm = T),aspect_deg = mean(slope_aspect_summary$mean_aspect_deg, na.rm = T),sonic_azimuth_deg = AngZaxsSoniInst) + +# Plot terrain plane vs. deployed/rotated sonic plane +plot_sonic_terrain(slope_deg = mean(slope_aspect_summary$mean_slope_deg, na.rm = T), + aspect_deg = mean(slope_aspect_summary$mean_aspect_deg, na.rm = T), + sonic_azimuth_deg = AngZaxsSoniInst, + fileOut = file.path(dirPlot, paste0(site, "_soni_terrain_orientation.html"))) + +# Optional: save CSV +write.csv(slope_aspect_summary, + file.path(dirOut, paste0(site,"_slope_aspect_mean_by_year_1km_box.csv")), + row.names = FALSE) +write.csv(outAng, + file.path(dirOut, paste0(site,"_soni_pitch_roll_azimuth.csv")), + row.names = FALSE) + +ifelse(grepl("reorientation", dirOut),dfAng[which(dfAng$SITE == site),]$Derived.Pitch.from.AOP.after.reorientation <- outAng$pitch_deg, dfAng[which(dfAng$SITE == site),]$Derived.Pitch.from.AOP <- outAng$pitch_deg) +ifelse(grepl("reorientation", dirOut),dfAng[which(dfAng$SITE == site),]$Derived.roll.from.AOP.after.reorientation <- outAng$roll_deg, dfAng[which(dfAng$SITE == site),]$Derived.roll.from.AOP <- outAng$roll_deg) + +#Write output data +writeData( + wb, sheet = sheet_name, x = dfAng +) + +#Save output +saveWorkbook(wb,"/home/root/eddy/data/neon_slope_aspect/revisit pitch and roll_2026.xlsx",overwrite = TRUE) + +# Optional: quick plot of mean slope +# if (nrow(slope_aspect_summary) > 0) { +# plot(as.Date(paste0(slope_aspect_summary$year,"-01-01")), slope_aspect_summary$mean_slope_deg, +# xlab = "Year", ylab = "Mean slope (degrees)", +# main = "NEON AOP Slope at ",site," — 1-km box around tower") +# } + +#Clean up files +unlink(list.files(dirDnld, full.names = TRUE), recursive = TRUE) + +} #End for loop around site set \ No newline at end of file diff --git a/flow/tool/flow.meta.loc.turb.R b/flow/tool/flow.meta.loc.turb.R new file mode 100644 index 00000000..af645e5c --- /dev/null +++ b/flow/tool/flow.meta.loc.turb.R @@ -0,0 +1,70 @@ +############################################################################################## +#' @title Workflow for to grab ECTE sensor locations and calculate UTM coordinates + +#' @author +#' David Durden \email{eddy4R.info@gmail.com} + +#' @description +#' Workflow. Downloading dp0p data from S3 and converting to ICOS format. + +#' @param Currently none + +#' @return Currently none + +#' @references + +#' @keywords eddy-covariance, NEON + +#' @examples Currently none + +#' @seealso Currently none + +# changelog and author contributions / copyrights +# David (2024-09-12) +# original creation +############################################################################################## + + +#Install and load libraries +library(devtools) +install_github('NEONScience/NEON-geolocation/geoNEON', dependencies=TRUE) +library(geoNEON) + +#Set the NEON site code +Site <- "KONZ" + +#Angle of local tower coordinate reference system (x aligned with C face from CD corner) +angRefeTowr <- c("BARR" = 255,"CLBJ" = 270,"MLBS" = 180,"DSNY" = 270,"NIWO" = 225,"ORNL" = 270,"OSBS" = 225, + "SCBI" = 300,"LENO" = 315,"TALL" = 270,"CPER" = 270,"BART" = 270,"HARV" = 270,"BLAN" = 240, + "SERC" = 230,"JERC" = 135,"GUAN" = 270,"LAJA" = 270,"STEI" = 225,"TREE" = 225,"UNDE" = 200, + "KONA" = 290,"KONZ" = 290,"UKFS" = 230,"GRSM" = 230,"DELA" = 280,"DCFS" = 245,"NOGP" = 220, + "WOOD" = 245,"RMNP" = 303,"OAES" = 270,"YELL" = 180,"MOAB" = 270,"STER" = 270,"JORN" = 220, + "SRER" = 290,"ONAQ" = 180,"ABBY" = 270,"WREF" = 225,"SJER" = 270,"SOAP" = 180,"TEAK" = 270, + "TOOL" = 270,"BONA" = 270,"DEJU" = 290,"HEAL" = 270,"PUUM" = 295)[Site] + +#Grab site location metadata for all configure locations for the current time with history = F +locSite <- geoNEON::getLocBySite(Site, type="TIS", history=F) + + +#Grab tower location metadata +locTowr <- locSite[grep(pattern = "TOWER", x = locSite$namedLocation),] + +#Grab a subset of Tower sensor location metadata +locSensTowr <- locSite[grep(pattern = "BOOM|LEVEL", x = locSite$locationParent),] +locSensTowr <- locSensTowr[grep(pattern = "CFGLOC[0-9]{6}$", x = locSensTowr$namedLocation),] + + +#perform actual rotation +xOfst <- as.numeric(locSensTowr$xOffset)*cos(angRefeTowr) - as.numeric(locSensTowr$yOffset) * sin(angRefeTowr) +yOfst <- as.numeric(locSensTowr$xOffset) * sin(angRefeTowr) + as.numeric(locSensTowr$yOffset) * cos(angRefeTowr) + +#Apply offsets to get UTM coordinates for sensors +locSensTowr$easting <- as.numeric(locTowr$easting) + xOfst +locSensTowr$northing <- as.numeric(locTowr$northing) + yOfst +locSensTowr$utmZone <- locTowr$utmZone + +#Grab a subset of ECTE sensor location metadata +locEcte <- locSensTowr[grep(pattern = "ECTE IRGA L|3D Wind L", x = locSensTowr$locationDescription),] + +#Calculate Lat and Lon from UTM coordinates (needs terra installed) +#latLon <- geoNEON::calcLatLong(locSens$easting, locSens$northing, utmZone = locSens$utmZone) diff --git a/pack/eddy4R.base/R/def.bin.R b/pack/eddy4R.base/R/def.bin.R index 5e12748a..d71a51c0 100644 --- a/pack/eddy4R.base/R/def.bin.R +++ b/pack/eddy4R.base/R/def.bin.R @@ -11,10 +11,10 @@ #' @param depe Either a vector or matrix of class numeric or integer containing the dependent variable and of the same length as \code{idep}. [] #' @param RngMinMax An object of class numeric or integer containing the minimum and maximum values of the independent variable. Defaults to NULL. [] #' @param NumBin An object of class numeric or integer containing the number of bins. [] -#' @param widtBin An object of class string containing the functions ("lin", "log10", "exp10", "logExp", "expLog") to determine bin width distribution of the independent variable. [] -#' @param meanFunc An object of class string containing the arithmetic "mean" and "median". [] +#' @param WidtBin An object of class string containing the functions ("lin", "log10", "exp10", "logExp", "expLog") to determine bin width distribution of the independent variable. [] +#' @param Func An object of class string containing the arithmetic "mean", "median", or "sd". [] -#' @return \code{idep} A list object of class "numeric" containing the resulted binning of independent variable and of the same length as {widtBin} and \code{depe} a matrix containing the the resulted binning of dependent variable and of the same length as {widtBin}. \cr +#' @return \code{idep} A list object of class "numeric" containing the resulted binning of independent variable and of the same length as {WidtBin} and \code{depe} a matrix containing the the resulted binning of dependent variable and of the same length as {WidtBin}. \cr #' @references #' License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 @@ -22,8 +22,8 @@ #' @keywords bin #' @examples -#' def.bin(idep = rnorm(5000), depe = rnorm(5000), RngMinMax = NULL, NumBin = 23, widtBin = "log10", meanFunc = "mean" ) -#' def.bin(idep = rnorm(500), depe = rnorm(500), RngMinMax = c(0.1, 0.4), NumBin = 12, widtBin = "lin", meanFunc = "median" ) +#' def.bin(idep = rnorm(5000), depe = rnorm(5000), RngMinMax = NULL, NumBin = 23, WidtBin = "log10", Func = "mean" ) +#' def.bin(idep = rnorm(500), depe = rnorm(500), RngMinMax = c(0.1, 0.4), NumBin = 12, WidtBin = "lin", Func = "median" ) #' @seealso Currently none @@ -38,6 +38,8 @@ # Initail naming convention for eddy4R # Natchaya P-Durden (2018-04-03) # update @param format +# Stefan Metzger (2024-02-02) +# add functionality for binned standard deviation ############################################################################################## #BIN DATA @@ -46,15 +48,15 @@ def.bin <- function( depe, RngMinMax = NULL, NumBin, - widtBin = c("lin", "log10", "exp10", "logExp", "expLog"), - meanFunc = c("mean", "median") + WidtBin = c("lin", "log10", "exp10", "logExp", "expLog"), + Func = c("mean", "median", "sd") ) { #aggregation with binning # idep: independent variable, frequency, wavenumber etc. # depe: dependent variable, vector or matrix of same length as idep # RngMinMax: min and max range # NumBin: number of bins - # widtBin: c("lin", "log10", "exp10", "logExp", "expLog") bin width distribution as function of idep + # WidtBin: c("lin", "log10", "exp10", "logExp", "expLog") bin width distribution as function of idep #prepare variables idep <- idep @@ -63,23 +65,28 @@ def.bin <- function( #define boundary if(is.null(RngMinMax)) minMax <- base::range(idep) - if(widtBin == "lin") rng <- base::seq(minMax[1], minMax[2], length.out=(NumBin + 1)) - if(widtBin == "log10") rng <- base::log10(base::seq(10^(minMax[1]), 10^(minMax[2]), length.out=(NumBin + 1))) - if(widtBin == "exp10") rng <- 10^(base::seq(base::log10(minMax[1]), base::log10(minMax[2]), length.out=(NumBin + 1))) - if(widtBin == "logExp") rng <- base::log(base::seq(base::exp(minMax[1]), base::exp(minMax[2]), length.out=(NumBin + 1))) - if(widtBin == "expLog") rng <- base::exp(base::seq(base::log(minMax[1]), base::log(minMax[2]), length.out=(NumBin + 1))) + if(WidtBin == "lin") rng <- base::seq(minMax[1], minMax[2], length.out=(NumBin + 1)) + if(WidtBin == "log10") rng <- base::log10(base::seq(10^(minMax[1]), 10^(minMax[2]), length.out=(NumBin + 1))) + if(WidtBin == "exp10") rng <- 10^(base::seq(base::log10(minMax[1]), base::log10(minMax[2]), length.out=(NumBin + 1))) + if(WidtBin == "logExp") rng <- base::log(base::seq(base::exp(minMax[1]), base::exp(minMax[2]), length.out=(NumBin + 1))) + if(WidtBin == "expLog") rng <- base::exp(base::seq(base::log(minMax[1]), base::log(minMax[2]), length.out=(NumBin + 1))) if(is.null(RngMinMax)) rng[c(1,length(rng))] <- c(0,Inf) #actual binning for(i in 1:(length(rng)-1)) { whrBin <- which(idep > rng[i] & idep <= rng[i+1]) - if(meanFunc == "median") { + if(Func == "median") { idepTmp <- stats::median(idep[whrBin], na.rm=T) depeTmp <- sapply(1:ncol(depe), function(x) stats::median(depe[whrBin,x], na.rm=T)) - } else { + } + if(Func == "mean") { idepTmp <- base::mean(idep[whrBin], na.rm=T) depeTmp <- sapply(1:ncol(depe), function(x) base::mean(depe[whrBin,x], na.rm=T)) } + if(Func == "sd") { + idepTmp <- base::mean(idep[whrBin], na.rm=T) + depeTmp <- sapply(1:ncol(depe), function(x) stats::sd(depe[whrBin,x], na.rm=T)) + } if(i == 1) { idepBin <- idepTmp depeBin <- depeTmp diff --git a/pack/eddy4R.base/man/def.bin.Rd b/pack/eddy4R.base/man/def.bin.Rd index 03064f7f..70527ef3 100644 --- a/pack/eddy4R.base/man/def.bin.Rd +++ b/pack/eddy4R.base/man/def.bin.Rd @@ -9,8 +9,8 @@ def.bin( depe, RngMinMax = NULL, NumBin, - widtBin = c("lin", "log10", "exp10", "logExp", "expLog"), - meanFunc = c("mean", "median") + WidtBin = c("lin", "log10", "exp10", "logExp", "expLog"), + Func = c("mean", "median", "sd") ) } \arguments{ @@ -22,19 +22,19 @@ def.bin( \item{NumBin}{An object of class numeric or integer containing the number of bins. []} -\item{widtBin}{An object of class string containing the functions ("lin", "log10", "exp10", "logExp", "expLog") to determine bin width distribution of the independent variable. []} +\item{WidtBin}{An object of class string containing the functions ("lin", "log10", "exp10", "logExp", "expLog") to determine bin width distribution of the independent variable. []} -\item{meanFunc}{An object of class string containing the arithmetic "mean" and "median". []} +\item{Func}{An object of class string containing the arithmetic "mean", "median", or "sd". []} } \value{ -\code{idep} A list object of class "numeric" containing the resulted binning of independent variable and of the same length as {widtBin} and \code{depe} a matrix containing the the resulted binning of dependent variable and of the same length as {widtBin}. \cr +\code{idep} A list object of class "numeric" containing the resulted binning of independent variable and of the same length as {WidtBin} and \code{depe} a matrix containing the the resulted binning of dependent variable and of the same length as {WidtBin}. \cr } \description{ Function definition. Smooth data using Binning method. } \examples{ -def.bin(idep = rnorm(5000), depe = rnorm(5000), RngMinMax = NULL, NumBin = 23, widtBin = "log10", meanFunc = "mean" ) -def.bin(idep = rnorm(500), depe = rnorm(500), RngMinMax = c(0.1, 0.4), NumBin = 12, widtBin = "lin", meanFunc = "median" ) +def.bin(idep = rnorm(5000), depe = rnorm(5000), RngMinMax = NULL, NumBin = 23, WidtBin = "log10", Func = "mean" ) +def.bin(idep = rnorm(500), depe = rnorm(500), RngMinMax = c(0.1, 0.4), NumBin = 12, WidtBin = "lin", Func = "median" ) } \references{ License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 diff --git a/pack/eddy4R.maps/.Rbuildignore b/pack/eddy4R.maps/.Rbuildignore new file mode 100644 index 00000000..6c038333 --- /dev/null +++ b/pack/eddy4R.maps/.Rbuildignore @@ -0,0 +1,3 @@ +^eddy4R\.maps\.Rproj$ +^\.Rproj\.user$ +^data-raw$ diff --git a/pack/eddy4R.maps/DESCRIPTION b/pack/eddy4R.maps/DESCRIPTION new file mode 100644 index 00000000..d34a760f --- /dev/null +++ b/pack/eddy4R.maps/DESCRIPTION @@ -0,0 +1,45 @@ +Package: eddy4R.maps +Title: Eddy-covariance calculation for R: Flux Mapper™ source codes (basic) +Version: 0.0.1 +Authors@R: c( person(given = "Stefan", + family = "Metzger", + role = c("aut", "cre"), + email = "smetzger@atmofacts.com", + comment = c(ORCID = "0000-0002-4201-852X")), + person(given = "Samuel", + family = "Bower", + role = c("aut"), + email = "sbower@atmofacts.com"), + person(given = "David", + family = "Durden", + role = c("aut"), + email = "ddurden@battelleecology.org") + ) +Description: Basic commonalities and tools for working with Flux Maps™ in R. +Depends: + R (>= 4.0.5) +Imports: + assertthat, + mapview, + gdalcubes (>= 0.3.1), + gifski (>= 1.4.3-1), + here (>= 1.0.1), + htmlwidgets (>= 1.5.3), + leaflet (>= 2.0.4.1), + lubridate (>= 1.9.2), + matlab (>= 1.0.2), + raster (>= 3.4-10), + RColorBrewer (>= 1.1-2), + rstac (>= 0.9.1), + sf (>= 0.9-8), + sp (>= 1.4-5), + stars (>= 0.5-2), + tmap (>= 3.3-1), + tmaptools (>= 3.1-1), + tools (>= 4.0.5) +Comments: Dependency package(s) 'OpenStreetMap (>= 0.3.4)' not available. +License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +Encoding: UTF-8 +LazyData: true +Roxygen: list(markdown = TRUE) +RoxygenNote: 7.2.3 diff --git a/pack/eddy4R.maps/NAMESPACE b/pack/eddy4R.maps/NAMESPACE new file mode 100644 index 00000000..f1e14836 --- /dev/null +++ b/pack/eddy4R.maps/NAMESPACE @@ -0,0 +1,11 @@ +# Generated by roxygen2: do not edit by hand + +export(def.algn.foot.rng) +export(def.bbox) +export(def.plot.flux.animate) +export(def.plot.flux.interactive) +export(def.plot.flux.static) +export(def.spat.data.cube) +export(def.spatialize.flux.foot) +export(wrap.spat.data.grab) +importFrom(matlab,padarray) diff --git a/pack/eddy4R.maps/R/def.algn.foot.rng.R b/pack/eddy4R.maps/R/def.algn.foot.rng.R new file mode 100644 index 00000000..023d99f2 --- /dev/null +++ b/pack/eddy4R.maps/R/def.algn.foot.rng.R @@ -0,0 +1,103 @@ +#' @title Align Footprint Map with Remote Sensing Data +#' +#' @author +#' Stefan Metzger \email{smetzger@atmofacts.com} +#' Andrei Serafimovich +#' +#' @description Function definition. This function adjusts the dimensions of a footprint map +#' (PHIcr_pad) to match and align with the dimensions of remote sensing (RS) data. It handles both cases +#' where the footprint map is smaller or larger than the RS data extent in all directions. +#' +#' @param PHIcr_pad Matrix representing the footprint map. +#' @param nortF Numeric vector representing the north extent of the footprint. +#' @param eastF Numeric vector representing the east extent of the footprint. +#' @param RS List containing 'nort' and 'east' vectors for remote sensing data extents. +#' +#' @return List containing the adjusted footprint map matrix and the updated extents (nortF and eastF). +#' +#' @references +#' License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +#' +#' @keywords visualization, flux mapping +#' +#' @importFrom matlab padarray +#' +#' @examples +#' # Example usage: +#' # result <- alignFootprintMap(PHIcr_pad, nortF, eastF, RS) +#' # aligned_PHIcr_pad <- result$PHIcr_pad +#' # updated_nortF <- result$nortF +#' # updated_eastF <- result$eastF +#' +#' @seealso Currently none. +#' +#' @export +# +# changelog and author contributions / copyrights +# Stefan Metzger (2013-01-01) original creation +# Andrei Serafimovich (2015-06-15) fixed padding for footprint matrices +# Stefan Metzger (2023-01-31) add Roxygen header, AGPL3 publication +# +############################################################################################### + +def.algn.foot.rng <- function( + PHIcr_pad, + nortF, + eastF, + RS) { + + # Pad or trim the footprint matrix to get same dimension as and alignment with RS data + + # Extent in south + if(min(nortF, na.rm=TRUE) > 1) { + #case1: footprint matrix smaller than RS extent + PHIcr_pad <- matlab::padarray(PHIcr_pad, range(nortF)[1]-1,0,"post") + nortF <- c(1:(range(nortF)[1]-1), nortF) + } else if (min(nortF, na.rm=TRUE) < 1) { + #case2: footprint matrix larger than RS extent + # PHIcr_pad <- PHIcr[-which(nortF < 0),] + PHIcr_pad <- PHIcr_pad[-which(nortF <= 0),] + # nortF <- nortF[-which(nortF < 0)] + nortF <- nortF[-which(nortF <= 0)] + } + + # Extent in north + if( max(nortF, na.rm=TRUE) < length(RS$nort) ) { + #case1: footprint matrix smaller than RS extent + PHIcr_pad <- matlab::padarray(PHIcr_pad,length(RS$nort)-range(nortF)[2],0,"pre") + nortF <- c(nortF, (range(nortF)[2]+1):length(RS$nort)) + } else if ( max(nortF, na.rm=TRUE) > length(RS$nort) ) { + #case2: footprint matrix larger than RS extent + PHIcr_pad <- PHIcr_pad[-which(nortF > length(RS$nort)),] + nortF <- nortF[-which(nortF > length(RS$nort))] + } + + # Extent in west + if(min(eastF, na.rm=TRUE) > 1) { + #case1: footprint matrix smaller than RS extent + PHIcr_pad <- cbind(matrix(nrow=nrow(PHIcr_pad), ncol=range(eastF)[1]-1, 0), PHIcr_pad) + eastF <- c(1:(range(eastF)[1]-1), eastF) + } else if (min(eastF, na.rm=TRUE) < 1) { + #case2: footprint matrix larger than RS extent + # PHIcr_pad <- PHIcr_pad[,-which(eastF < 0)] + PHIcr_pad <- PHIcr_pad[,-which(eastF <= 0)] + # eastF <- eastF[-which(eastF < 0)] + eastF <- eastF[-which(eastF <= 0)] + } + + # Extent in east + if( max(eastF, na.rm=TRUE) < length(RS$east) ) { + #case1: footprint matrix smaller than RS extent + PHIcr_pad <- cbind(PHIcr_pad, matrix(nrow=nrow(PHIcr_pad), + ncol=length(RS$east)-range(eastF)[2], 0)) + eastF <- c(eastF, (range(eastF)[2]+1):length(RS$east)) + } else if (max(eastF, na.rm=TRUE) > length(RS$east)) { + #case2: footprint matrix larger than RS extent + PHIcr_pad <- PHIcr_pad[,-which(eastF > length(RS$east))] + # eastF <- eastF[-which(nortF > length(RS$east))] + eastF <- eastF[-which(eastF > length(RS$east))] + } + + # Return the adjusted matrix and extents + return(list(PHIcr_pad = PHIcr_pad, nortF = nortF, eastF = eastF)) +} diff --git a/pack/eddy4R.maps/R/def.bbox.R b/pack/eddy4R.maps/R/def.bbox.R new file mode 100644 index 00000000..24b297a0 --- /dev/null +++ b/pack/eddy4R.maps/R/def.bbox.R @@ -0,0 +1,98 @@ +############################################################################################## +#' @title definition function to create bounding box + +#' @author +#' David Durden +#' Stefan Metzger \email{smetzger@atmofacts.com} + +#' @description Function definition. Read in shapefile or create a bounding box +#' by adding an extent to Lat/Lon for grabbing STAC data with a padding option. + +#' @param site the site to use to grab the bounding box +#' @param crs coordinate reference system (Defaults to "EPSG:4326") +#' @param pad_box logical to determine if padding should be applied to bounding box (defaults to FALSE) +#' @param pad_degree decimal degree of latitude and longitude to pad the bounding box (defaults to 0.1) + +#' @return list containing shapefile data and bbox + +#' @references +#' License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#' @keywords Currently none + +#' @examples Currently none + +#' @seealso Currently none + +#' @export +#' +# changelog and author contributions +# David Durden (2024-01-23) +# original creation +# Stefan Metzger (2024-03-01) +# workaround for native pipe operator to support both R < 4.1 and R >= 4.1 +############################################################################################## +def.bbox <- function( + site = c("CPER", "CHEESEHEAD")[2], + crs = "EPSG:4326", + pad_box = FALSE, + pad_degree = 0.5, + lat = NULL, + lon = NULL + ){ + + #Initialize list + out <- list() + + ## read shape file + if(!is.null(site)) { + if(site == "CHEESEHEAD"){ + + out$shp <-eddy4R.maps::CHEESEHEAD + }else{ + + out$shp <- dplyr::filter(eddy4R.maps::NEON$siteID == site) + } + #sf::read_sf(dsn = DirInp, "mask") + #generate bounding box + # native pipe operator |>; supported from R >= 4.1 + # out$bbox <- out$shp |> sf::st_transform(crs=crs) |> sf::st_bbox() + # workaround: sequentially chain functions to support both R < 4.1 and R >= 4.1 + tmp01 <- sf::st_transform(out$shp, crs=crs) + out$bbox <- sf::st_bbox(tmp01) + base::rm(tmp01) + + #pad bounding box + if(pad_box == TRUE){ + out$bbox[1] <- out$bbox$xmin - pad_degree #Padding in degrees + out$bbox[2] <- out$bbox$ymin - pad_degree + out$bbox[3] <- out$bbox$xmax + pad_degree + out$bbox[4] <- out$bbox$ymax + pad_degree + } + + #Create a mask layer + # with pipe operator (R >= 4.1 only) + # out$maskLayer <- sf::st_geometry(out$shp) |> sf::st_transform(crs=crs) + # w/o pipe operator + + # First, extract the geometry from out$shp + tmp01 <- sf::st_geometry(out$shp) + + # Then, transform the geometry with the specified CRS + out$maskLayer <- sf::st_transform(tmp01, crs=crs) + + # clean up + base::rm(tmp01) + + + } else + { + out$bbox <- as(raster::extent(lon - pad_degree, lon + pad_degree, lat - pad_degree, lat + pad_degree), "SpatialPolygons") + proj4string(out$bbox) <- crs + } + + + + #Return output list with shp and bbox + return(out) +} diff --git a/pack/eddy4R.maps/R/def.plot.flux.animate.R b/pack/eddy4R.maps/R/def.plot.flux.animate.R new file mode 100644 index 00000000..94a5f606 --- /dev/null +++ b/pack/eddy4R.maps/R/def.plot.flux.animate.R @@ -0,0 +1,113 @@ +############################################################################################## +#' @title Definition function: Plot fluxes on an animated gif. + +#' @author +#' Sam Bower \email{sbower@atmofacts.com} + +#' @description Function definition. This function creates an animated flux map visualization for temporal flux map data contained in a folder. +#' +#' @param input_folder A folder of geotiff files. +#' @param output_file The path of the output file (.gif) +#' @param nodata_value Nodata value from flux data +#' @param alpha Raster opacity +#' @param colormap palette_explorer() for palette options +#' @param palette_style quantile, equal, cont, cat +#' @param legend Boolean. If legend plots on the map +#' @param delay The delay time in the animation. +#' + +#' @return +#' +#' + +#' @references +#' License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#' @keywords visualization, flux mapping, animation +#' +#' @examples +#' +#' def.plot.flux.animation( +#' input_folder = "/path/to/input/folder", # Replace with your input folder path +#' output_file = "/path/to/output/animation.gif", # Replace with your desired output GIF path +#' nodata_value = 0, +#' colormap = 'YlOrRd', +#' basemap_style = 'osm', +#' palette_style = 'equal', +#' alpha = 0.4, +#' legend = TRUE +#' ) + + +#' @seealso Currently none. + +#' @export + +# changelog and author contributions / copyrights +# Sam Bower (2023-02-02) +# original creation +# +# +############################################################################################### + +def.plot.flux.animate <- function( + input_folder, + output_file, + nodata_value = 0, + colormap = 'YlOrRd', + basemap_style = 'osm', + palette_style = 'equal', + alpha = 0.4, + legend = TRUE, + delay = 1 +) { + + # Load necessary libraries + library(raster) + library(tmap) + library(tmaptools) + library(gifski) + + # Ensure tmap is in plot mode + tmap_mode("plot") + + # Create a temporary directory for storing map images + temp_dir <- tempfile() + dir.create(temp_dir) + + # List all raster files in the directory + raster_files <- list.files(input_folder, pattern = "\\.tif$", full.names = TRUE) + + # Initialize a list to store file paths of individual map images + temp_files <- vector("character", length(raster_files)) + + # Loop through each raster file to create a static map + for (i in seq_along(raster_files)) { + flux <- raster::raster(raster_files[i]) + flux[flux == nodata_value] <- NA # Apply nodata value + + osm_map <- tmaptools::read_osm(flux, type = basemap_style) + + map <- tm_shape(osm_map) + + tm_rgb() + + tm_shape(flux) + + tm_raster(style = palette_style, alpha = alpha, palette = colormap) + + tm_layout(legend.outside = legend) + + # Generate a temporary file path for the static map image + temp_file <- file.path(temp_dir, paste0("map_", i, ".png")) + temp_files[i] <- temp_file # Store the file path + + # Save the map as an image + tmap_save(map, filename = temp_file, width = 800, height = 600, units = "px") + } + + # Use gifski to create the GIF from the PNG files + gifski(png_files = temp_files, gif_file = output_file, width = 800, height = 600, delay = delay, progress = TRUE) + + # After creating the GIF, clean up the temporary directory and its contents + unlink(temp_dir, recursive = TRUE) + + cat("Animation created at:", output_file, "\n") + +} \ No newline at end of file diff --git a/pack/eddy4R.maps/R/def.plot.flux.interactive.R b/pack/eddy4R.maps/R/def.plot.flux.interactive.R new file mode 100644 index 00000000..7aad5781 --- /dev/null +++ b/pack/eddy4R.maps/R/def.plot.flux.interactive.R @@ -0,0 +1,113 @@ +############################################################################################## +#' @title Definition function: Plot fluxes on an interactive map. + +#' @author +#' Sam Bower \email{sbower@atmofacts.com} + +#' @description Function definition. This function creates an interactive flux map visualization that can be used in R viewer or in a web browser. +#' +#' @param input_path A geotiff file or folder of geotiff files to plot on the basemap. +#' @param nodata_value Nodata value from flux data +#' @param alpha Raster opacity +#' @param colormap palette_explorer() for palette options + +#' @return +#' +#' + +#' @references +#' License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#' @keywords visualization, flux mapping +#' + + +#' @seealso Currently none. + +#' @export + +# changelog and author contributions / copyrights +# Sam Bower (2023-02-02) +# original creation +# +# +############################################################################################### + + +def.plot.flux.interactive <- function( + input_path, + nodata_value = 0, + alpha = 0.7, + colormap = 'YlOrRd', + save_path = NULL +) { + + library(leaflet) + library(raster) + library(RColorBrewer) + + # Initialize Leaflet map + map <- leaflet() %>% + addProviderTiles("OpenStreetMap", group = "Street") %>% + addProviderTiles("Esri.WorldImagery", group = "Imagery") %>% + addProviderTiles("CartoDB.DarkMatter", group = "Dark") + + # Function to process and add a raster object to the map + processAndAddRaster <- function(flux, map, layerName) { + # Replace nodata_value with NA + flux[flux == nodata_value] <- NA + + # Extract values from the raster while maintaining NA for nodata + rasterValues <- getValues(flux) # This will return a vector of all raster values + validValues <- rasterValues[!is.na(rasterValues)] # Filter out NA values + + if (length(validValues) == 0) { + validValues <- c(0) # Fallback to avoid issues with empty data + } + + # Define the color palette function + colorPal <- colorNumeric(palette = colormap, domain = range(validValues, na.rm = TRUE), na.color = "transparent") + + # Add raster to the map with the correct color mapping + map <- map %>% addRasterImage(flux, group = layerName, colors = colorPal, opacity = alpha, layerId = layerName) + return(map) + } + + # Check if input_path is a raster object + if (inherits(input_path, "RasterLayer") || inherits(input_path, "RasterStack") || inherits(input_path, "RasterBrick")) { + layerName <- "CustomRasterLayer" # Modify as needed or generate dynamically + map <- processAndAddRaster(input_path, map, layerName) + rasterGroups <- c(layerName) + } else { + # Determine if input_path is a directory or a single file + if (dir.exists(input_path)) { + rasterFiles <- list.files(input_path, pattern = "\\.tif$", full.names = TRUE) + if (length(rasterFiles) == 0) { # Check if no TIFF files found + stop("No TIFF files found in the directory.") + } + } else if (file.exists(input_path) && grepl("\\.tif$", input_path)) { + rasterFiles <- list(input_path) # Ensure rasterFiles is a list + } else { + stop("Input path is neither a valid raster object, folder, nor a TIFF file.") + } + + # Apply the function to each raster file + rasterGroups <- NULL + for(filePath in rasterFiles) { + layerName <- base::basename(filePath) + flux <- raster(filePath) + map <- processAndAddRaster(flux, map, layerName) + rasterGroups <- c(rasterGroups, layerName) + } + } + + # Add layers control to the map + map <- map %>% addLayersControl(overlayGroups = rasterGroups, baseGroups = c("Street", "Imagery", "Dark")) + + if (!is.null(save_path)) { + htmlwidgets::saveWidget(map, file = save_path, selfcontained = TRUE) + } else { + # Print the map to display it interactively + print(map) + } +} diff --git a/pack/eddy4R.maps/R/def.plot.flux.static.R b/pack/eddy4R.maps/R/def.plot.flux.static.R new file mode 100644 index 00000000..a13d2b06 --- /dev/null +++ b/pack/eddy4R.maps/R/def.plot.flux.static.R @@ -0,0 +1,110 @@ +############################################################################################## +#' @title Definition function: Plot fluxes on a static basemap + +#' @author +#' Sam Bower \email{sbower@atmofacts.com} + +#' @description Function definition. This function creates a flux map visualization on a user defined basemap. +#' +#' @param inputPath A spatial file or folder of spatial files to plot on the basemap. +#' @param outputPath A string for the folder location to save output maps. +#' @param nodata_value The nodata value specified from the flux data. +#' @param basemap_style Basemap styles in OpenStreetMap (more in openmap()) +#' @param alpha Raster opacity +#' @param colormap palette_explorer() for palette options +#' @param style quantile, equal, cont, cat +#' @param color_n color categories in palette + +#' @return +#' +#' + +#' @references +#' License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#' @keywords visualization, flux mapping +#' + + +#' @seealso Currently none. + +#' @export + +# changelog and author contributions / copyrights +# Sam Bower (2023-02-01) +# original creation +# +# +############################################################################################### +def.plot.flux.static <- function( + inputPath, + outputPath, + basemap_style = 'bing', + alpha = 0.5, + nodata_value = 0, + colormap = 'YlOrRd', + style = 'equal', + color_n = 7, + use_basemap = FALSE, + background_color = "white", + units = "Units", + legend_bg_alpha = 1 +) { + + options(java.parameters = "-Djava.awt.headless=true") + library(tmap) + library(tmaptools) + library(OpenStreetMap) + library(RColorBrewer) + + plotRaster <- function(rasterFile, outputPath) { + + rasterFile[rasterFile == nodata_value] <- NA + map <- NULL + + if (use_basemap && basemap_style != 'none') { + osm_map <- tmaptools::read_osm(rasterFile, type = basemap_style) + map <- tm_shape(osm_map) + + tm_rgb() + + tm_shape(rasterFile) + + tm_raster(style = style, alpha = alpha, palette = brewer.pal(n = color_n, name = colormap), title = units) + + tm_layout( + legend.bg.alpha = legend_bg_alpha, + legend.bg.color = 'white', + legend.outside = FALSE + ) + } else { + map <- tm_shape(rasterFile) + + tm_raster(style = style, alpha = alpha, palette = brewer.pal(n = color_n, name = colormap), title = units) + + tm_layout( + bg.color = background_color, + legend.bg.alpha = legend_bg_alpha, + legend.bg.color = 'white', + frame = FALSE + ) + } + + tmap_save(map, file = outputPath) + } + + if (inherits(inputPath, "RasterLayer") || inherits(inputPath, "RasterStack") || inherits(inputPath, "RasterBrick")) { + rasterLayer <- inputPath + fileOutputPath <- paste0(outputPath) + plotRaster(rasterLayer, fileOutputPath) + } else if (dir.exists(inputPath)) { + rasterFiles <- list.files(inputPath, pattern = "\\.tif$", full.names = TRUE) + if (length(rasterFiles) == 0) { + stop("No raster files found in the directory.") + } + for (rasterFile in rasterFiles) { + fileName <- basename(rasterFile) + fileOutputPath <- paste0(outputPath, "/", sub("\\.tif$", ".png", fileName)) + plotRaster(rasterFile, fileOutputPath) + } + } else if (file.exists(inputPath) && grepl("\\.tif$", inputPath)) { + fileOutputPath <- paste0(outputPath, "/", tools::file_path_sans_ext(basename(inputPath)), ".png") + plotRaster(inputPath, fileOutputPath) + } else { + stop("Input path is neither a valid raster object, file, nor a directory containing raster files.") + } +} diff --git a/pack/eddy4R.maps/R/def.spat.data.cube.R b/pack/eddy4R.maps/R/def.spat.data.cube.R new file mode 100644 index 00000000..586b6d61 --- /dev/null +++ b/pack/eddy4R.maps/R/def.spat.data.cube.R @@ -0,0 +1,106 @@ +############################################################################################## +#' @title definition function to download data from Microsoft planetary computer + +#' @author +#' David Durden +#' Stefan Metzger \email{smetzger@atmofacts.com} + +#' @description Function definition. Download data from Microsoft planetary computer + +#' @param start_date start date as character format yyyy-mm-dd +#' @param end_date end date as character format yyyy-mm-dd +#' @param box numberic vector in the format of (xmin, ymin, xmax, ymax) +#' @param collection name of planetary collection +#' @param asset_name mame of asset +#' @param srs target spatial reference system as a string; can be a proj4 definition, WKT, or in the form "EPSG:XXXX" +#' @param dx size of pixels in x-direction (longitude / easting) +#' @param dy size of pixels in y-direction (latitude / northing) +#' @param dt size of pixels in time-direction, expressed as ISO8601 period string (only 1 number and unit is allowed) such as "P16D" +#' @param aggregation aggregation method as string, defining how to deal with pixels containing data from multiple images, can be "min", "max", "mean", "median", or "first" +#' @param resampling resampling method used in gdalwarp when images are read, can be "near", "bilinear", "bicubic" or others as supported by gdalwarp (see https://gdal.org/programs/gdalwarp.html) + +#' @return A data cube proxy object + +#' @references +#' License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#' @keywords Currently none + +#' @examples +#' ingest_planetary_data(start_date = "2022-01-01", end_date = "2023-07-01", box = c("xmin" = -123, "ymin" = 39, "xmax" = -122, "ymax" = 40)) + +#' @seealso Currently none + +#' @export +#' +# changelog and author contributions +# David Durden (2024-01-23) +# original creation +# Stefan Metzger (2024-03-01) +# complete Roxygen header +# workaround for native pipe operator to support both R < 4.1 and R >= 4.1 +############################################################################################## +def.spat.data.cube <- function(start_date, + end_date, + box, + collection = c("modis-15A2H-061", "sentinel-3-slstr-lst-l2-netcdf")[2], + asset_name = c("Lai_500m", "lst-in")[2], + srs = "EPSG:4326", + dx = 0.1, + dy = 0.1, + dt = "P1M", + aggregation = "mean", + resampling = "near"){ + + # check box + assertthat::are_equal(length(box), 4) + + # get STACItemCollection + # Original pipe-based code (R > 4.1 only) + # matches <- + # rstac::stac("https://planetarycomputer.microsoft.com/api/stac/v1") |> + # rstac::stac_search(collections = collection, + # datetime = paste(start_date, end_date, sep = "/"), + # bbox = c(box)) |> + # get_request() |> + # items_fetch() |> + # items_sign(sign_fn = sign_planetary_computer()) + + # workaround without pipe statements and using temporary objects: + # Step 1: Initialize STAC client + tmp01 <- rstac::stac("https://planetarycomputer.microsoft.com/api/stac/v1") + + # Step 2: Search STAC + tmp02 <- stac_search(tmp01, collections = collection, + datetime = paste(start_date, end_date, sep = "/"), + bbox = c(box)) + + # Step 3: Send request + tmp03 <- get_request(tmp02) + + # Step 4: Fetch items + tmp04 <- items_fetch(tmp03) + + # Step 5: Sign items + matches <- items_sign(tmp04, sign_fn = sign_planetary_computer()) + + # Cleanup of temporary objects at the end: + base::rm(tmp01, tmp02, tmp03, tmp04) + + # get image collection object + cube <- gdalcubes::stac_image_collection(matches$features, + asset_names = asset_name, + duration = "start") + + # set dimensions of the cube + v <- gdalcubes::cube_view(srs = srs, #lat/lon + extent = list(t0 = as.character(start_date), t1 = as.character(end_date), + left = box[1], right = box[3], + top = box[4], bottom = box[2]), + dx = dx, dy = dy, dt= dt, + aggregation = aggregation, resampling = resampling) + + # create proxy data cube + proxy_cube <- gdalcubes::raster_cube(cube, v) + return(proxy_cube) +} diff --git a/pack/eddy4R.maps/R/def.spatialize.flux.foot.R b/pack/eddy4R.maps/R/def.spatialize.flux.foot.R new file mode 100644 index 00000000..4947f18c --- /dev/null +++ b/pack/eddy4R.maps/R/def.spatialize.flux.foot.R @@ -0,0 +1,112 @@ +############################################################################################## +#' Spatialize Flux Footprint Data into Raster Format +#' +#' @description This function processes flux footprint data, spatializing it into a raster format +#' suitable for GIS analysis. It supports reading flux data from various formats, setting the +#' spatial extent, and defining the coordinate reference system (CRS). The output can optionally +#' be written to a file in GeoTiff format. +#' +#' @param flux_input The input flux data, which can be a path to an ASCII grid or CSV file, a matrix, +#' or a data frame. +#' @param lower_left_X The X coordinate of the lower left corner of the output raster. +#' @param lower_left_Y The Y coordinate of the lower left corner of the output raster. +#' @param nodata_value The value to be considered as 'no data' in the input flux data. Defaults to 0. +#' @param cell_size The size of each cell in the output raster, assumed to be square. Defaults to 10. +#' @param crs The coordinate reference system for the output raster, specified in PROJ.4 format. +#' Defaults to "+proj=utm +zone=13 +datum=WGS84 +units=m +no_defs". +#' @param write Logical, whether to write the output raster to a file. Defaults to FALSE. +#' @param output_filename The filename (including path) for the output file if write is TRUE. +#' If NULL and write is TRUE, an error is thrown. +#' @param file_format The format of the output file, defaults to 'GTiff'. +#' +#' @return A raster object representing the spatialized flux data. +#' +#' @examples +#' # Example usage: +#' raster <- def.spatialize.flux.foot(flux_input = "path/to/data.csv", +#' lower_left_X = 100000, +#' lower_left_Y = 400000, +#' cell_size = 10, +#' crs = "+proj=utm +zone=13 +datum=WGS84 +units=m +no_defs", +#' write = TRUE, +#' output_filename = "output.tif", +#' file_format = 'GTiff') +#' +#' @references +#' License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +#' +#' @author Sam Bower \email{sbower@atmofacts.com} +#' @keywords spatial, GIS, raster, flux +#' +#' @seealso \code{\link[raster]{writeRaster}}, \code{\link[raster]{raster}}, \code{\link[sp]{CRS}} +#' +#' @export +#' +#' @changelog +#' - Sam Bower (2023-02-02): Original creation. +############################################################################################### + +# Define the function with an additional CRS argument +def.spatialize.flux.foot <- function( + flux_input, + lower_left_X, + lower_left_Y, + nodata_value = 0, + cell_size = 10, + crs = "+proj=utm +zone=13 +datum=WGS84 +units=m +no_defs", + write = FALSE, + output_filename = NULL, + file_format = 'GTiff' +) { + + # Check if input is a path to a file, a data frame, or a matrix + if (is.character(flux_input)) { + # Assuming flux_input is a filepath to either a .asc or .csv file + file_extension <- tools::file_ext(flux_input) + if (file_extension == "asc") { + flux_matrix <- as.matrix(read.table(flux_input, header = FALSE)) + } else if (file_extension == "csv") { + flux_matrix <- as.matrix(read.csv(flux_input, header = TRUE)) + } else { + stop("Unsupported file format. Please provide a .asc or .csv file.") + } + } else if (is.data.frame(flux_input)) { + flux_matrix <- as.matrix(flux_input) + } else if (is.matrix(flux_input)) { + flux_matrix <- flux_input + } else { + stop("The data input must be a file path, matrix, or a data frame.") + } + + #initialize raster object from flux data input + flux_raster <- raster::raster(flux_matrix) + flux_raster[flux_raster==nodata_value] <- NA + + # Calculate and set the extent based on lower left corner and cell size + cellSizeX <- cell_size + cellSizeY <- cell_size + ncols <- ncol(flux_matrix) + nrows <- nrow(flux_matrix) + extentXmin <- lower_left_X + extentXmax <- lower_left_X + (ncols * cellSizeX) + extentYmin <- lower_left_Y + extentYmax <- lower_left_Y + (nrows * cellSizeY) + raster::extent(flux_raster) <- c(extentXmin, extentXmax, extentYmin, extentYmax) + + + # Set the CRS of the raster object + raster::crs(flux_raster) <- sp::CRS(crs) + + #Write raster to file if write is true. The default file format is a GeoTiff + if (write == TRUE){ + writeRaster( + flux_raster, + filename = output_filename, + format = file_format, + overwrite = TRUE + ) + } + + return(flux_raster) + +} \ No newline at end of file diff --git a/pack/eddy4R.maps/R/wrap.spat.data.R b/pack/eddy4R.maps/R/wrap.spat.data.R new file mode 100644 index 00000000..55d58af5 --- /dev/null +++ b/pack/eddy4R.maps/R/wrap.spat.data.R @@ -0,0 +1,90 @@ +############################################################################################## +#' @title wrapper function to generate spatial targets + +#' @author +#' David Durden +#' Stefan Metzger \email{smetzger@atmofacts.com} + +#' @description Wrapper definition. Generate spatial targets + +#' @param dir A directory of .tif files for scoring +#' @param site_id The side ID of the area being forecasted. Currently "august_complex" is the only option. + +#' @return message from minio submission + +#' @references +#' License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#' @keywords Currently none + +#' @examples spat4cast_submit(dir = "targets", site_id = "august_complex") + +#' @seealso Currently none + +#' @export +#' +# changelog and author contributions +# David Durden (2024-01-23) +# original creation +# Stefan Metzger (2024-03-01) +# complete Roxygen header +# fix attributes list in function call +############################################################################################## +wrap.spat.data.grab <- function( + dir = tempdir(), + dateBgn = "2019-05-01", + dateEnd = "2019-11-30", + site = c("CPER", "CHEESEHEAD")[2], + dt = "P1M", + dx = 0.1, + dy = 0.1 +) +{ + + print(paste0("Grabbing spatial data at ", Sys.time(), " for ", site)) + + library(sf) + library(lubridate) + library(gdalcubes) + library(rstac) + library(stars) + library(dplyr) + + + + #Source functions + # for (f in list.files(here::here("R"), full.names = TRUE)) source (f) + + #Create fire bounding box + bbox <- eddy4R.maps::def.bbox(site = site, pad_box = TRUE) + + #Target date + dateBgn <- lubridate::floor_date(as.Date(dateBgn), "month") #first day of the month + dateEnd <- lubridate::ceiling_date(as.Date(dateEnd), "month") + + # Ingest data ------------------------------------------------------------ + gdalcubes::gdalcubes_options(parallel=TRUE) + + # use ingest_planetary_data function to extract raster cube for fire bounding box between Jan 1 2002 and July 1 2023. + raster_cube <- eddy4R.maps::def.spat.data.cube(start_date = dateBgn, + end_date = dateEnd, + box = bbox$bbox, + srs = "EPSG:4326", + dx = dx, + dy = dy, + dt = dt) + + + + # create target file + # target <- create_target_file(cuberast = raster_cube, + # site_id = site_id, + # date = as.character(date), + # dir = tempdir(), + # bucket = "efi/spat4cast-targets", + # mask = fire_box$maskLayer) + # + + return(raster_cube) + +} #End of function \ No newline at end of file diff --git a/pack/eddy4R.maps/data/CHEESEHEAD.rda b/pack/eddy4R.maps/data/CHEESEHEAD.rda new file mode 100644 index 00000000..bbd63c96 Binary files /dev/null and b/pack/eddy4R.maps/data/CHEESEHEAD.rda differ diff --git a/pack/eddy4R.maps/data/NEON.rda b/pack/eddy4R.maps/data/NEON.rda new file mode 100644 index 00000000..31232586 Binary files /dev/null and b/pack/eddy4R.maps/data/NEON.rda differ diff --git a/pack/eddy4R.maps/man/def.algn.foot.rng.Rd b/pack/eddy4R.maps/man/def.algn.foot.rng.Rd new file mode 100644 index 00000000..e6c1cd79 --- /dev/null +++ b/pack/eddy4R.maps/man/def.algn.foot.rng.Rd @@ -0,0 +1,46 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/def.algn.foot.rng.R +\name{def.algn.foot.rng} +\alias{def.algn.foot.rng} +\title{Align Footprint Map with Remote Sensing Data} +\usage{ +def.algn.foot.rng(PHIcr_pad, nortF, eastF, RS) +} +\arguments{ +\item{PHIcr_pad}{Matrix representing the footprint map.} + +\item{nortF}{Numeric vector representing the north extent of the footprint.} + +\item{eastF}{Numeric vector representing the east extent of the footprint.} + +\item{RS}{List containing 'nort' and 'east' vectors for remote sensing data extents.} +} +\value{ +List containing the adjusted footprint map matrix and the updated extents (nortF and eastF). +} +\description{ +Function definition. This function adjusts the dimensions of a footprint map +(PHIcr_pad) to match and align with the dimensions of remote sensing (RS) data. It handles both cases +where the footprint map is smaller or larger than the RS data extent in all directions. +} +\examples{ +# Example usage: +# result <- alignFootprintMap(PHIcr_pad, nortF, eastF, RS) +# aligned_PHIcr_pad <- result$PHIcr_pad +# updated_nortF <- result$nortF +# updated_eastF <- result$eastF + +} +\references{ +License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +} +\seealso{ +Currently none. +} +\author{ +Stefan Metzger \email{smetzger@atmofacts.com} +Andrei Serafimovich +} +\keyword{flux} +\keyword{mapping} +\keyword{visualization,} diff --git a/pack/eddy4R.maps/man/def.bbox.Rd b/pack/eddy4R.maps/man/def.bbox.Rd new file mode 100644 index 00000000..33f0ba89 --- /dev/null +++ b/pack/eddy4R.maps/man/def.bbox.Rd @@ -0,0 +1,46 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/def.bbox.R +\name{def.bbox} +\alias{def.bbox} +\title{definition function to create bounding box} +\usage{ +def.bbox( + site = c("CPER", "CHEESEHEAD")[2], + crs = "EPSG:4326", + pad_box = FALSE, + pad_degree = 0.5, + lat = NULL, + lon = NULL +) +} +\arguments{ +\item{site}{the site to use to grab the bounding box} + +\item{crs}{coordinate reference system (Defaults to "EPSG:4326")} + +\item{pad_box}{logical to determine if padding should be applied to bounding box (defaults to FALSE)} + +\item{pad_degree}{decimal degree of latitude and longitude to pad the bounding box (defaults to 0.1)} +} +\value{ +list containing shapefile data and bbox +} +\description{ +Function definition. Read in shapefile or create a bounding box +by adding an extent to Lat/Lon for grabbing STAC data with a padding option. +} +\examples{ +Currently none +} +\references{ +License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +} +\seealso{ +Currently none +} +\author{ +David Durden +Stefan Metzger \email{smetzger@atmofacts.com} +} +\keyword{Currently} +\keyword{none} diff --git a/pack/eddy4R.maps/man/def.plot.flux.animate.Rd b/pack/eddy4R.maps/man/def.plot.flux.animate.Rd new file mode 100644 index 00000000..1939c3fb --- /dev/null +++ b/pack/eddy4R.maps/man/def.plot.flux.animate.Rd @@ -0,0 +1,64 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/def.plot.flux.animate.R +\name{def.plot.flux.animate} +\alias{def.plot.flux.animate} +\title{Definition function: Plot fluxes on an animated gif.} +\usage{ +def.plot.flux.animate( + input_folder, + output_file, + nodata_value = 0, + colormap = "YlOrRd", + basemap_style = "osm", + palette_style = "equal", + alpha = 0.4, + legend = TRUE, + delay = 1 +) +} +\arguments{ +\item{input_folder}{A folder of geotiff files.} + +\item{output_file}{The path of the output file (.gif)} + +\item{nodata_value}{Nodata value from flux data} + +\item{colormap}{palette_explorer() for palette options} + +\item{palette_style}{quantile, equal, cont, cat} + +\item{alpha}{Raster opacity} + +\item{legend}{Boolean. If legend plots on the map} + +\item{delay}{The delay time in the animation.} +} +\description{ +Function definition. This function creates an animated flux map visualization for temporal flux map data contained in a folder. +} +\examples{ + +def.plot.flux.animation( +input_folder = "/path/to/input/folder", # Replace with your input folder path +output_file = "/path/to/output/animation.gif", # Replace with your desired output GIF path +nodata_value = 0, +colormap = 'YlOrRd', +basemap_style = 'osm', +palette_style = 'equal', +alpha = 0.4, +legend = TRUE +) +} +\references{ +License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +} +\seealso{ +Currently none. +} +\author{ +Sam Bower \email{sbower@atmofacts.com} +} +\keyword{animation} +\keyword{flux} +\keyword{mapping,} +\keyword{visualization,} diff --git a/pack/eddy4R.maps/man/def.plot.flux.interactive.Rd b/pack/eddy4R.maps/man/def.plot.flux.interactive.Rd new file mode 100644 index 00000000..b4029cbf --- /dev/null +++ b/pack/eddy4R.maps/man/def.plot.flux.interactive.Rd @@ -0,0 +1,38 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/def.plot.flux.interactive.R +\name{def.plot.flux.interactive} +\alias{def.plot.flux.interactive} +\title{Definition function: Plot fluxes on an interactive map.} +\usage{ +def.plot.flux.interactive( + input_path, + nodata_value = 0, + alpha = 0.7, + colormap = "YlOrRd", + save_path = NULL +) +} +\arguments{ +\item{input_path}{A geotiff file or folder of geotiff files to plot on the basemap.} + +\item{nodata_value}{Nodata value from flux data} + +\item{alpha}{Raster opacity} + +\item{colormap}{palette_explorer() for palette options} +} +\description{ +Function definition. This function creates an interactive flux map visualization that can be used in R viewer or in a web browser. +} +\references{ +License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +} +\seealso{ +Currently none. +} +\author{ +Sam Bower \email{sbower@atmofacts.com} +} +\keyword{flux} +\keyword{mapping} +\keyword{visualization,} diff --git a/pack/eddy4R.maps/man/def.plot.flux.static.Rd b/pack/eddy4R.maps/man/def.plot.flux.static.Rd new file mode 100644 index 00000000..bd036f41 --- /dev/null +++ b/pack/eddy4R.maps/man/def.plot.flux.static.Rd @@ -0,0 +1,53 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/def.plot.flux.static.R +\name{def.plot.flux.static} +\alias{def.plot.flux.static} +\title{Definition function: Plot fluxes on a static basemap} +\usage{ +def.plot.flux.static( + inputPath, + outputPath, + basemap_style = "bing", + alpha = 0.5, + nodata_value = 0, + colormap = "YlOrRd", + style = "equal", + color_n = 7, + use_basemap = FALSE, + background_color = "white", + units = "Units", + legend_bg_alpha = 1 +) +} +\arguments{ +\item{inputPath}{A spatial file or folder of spatial files to plot on the basemap.} + +\item{outputPath}{A string for the folder location to save output maps.} + +\item{basemap_style}{Basemap styles in OpenStreetMap (more in openmap())} + +\item{alpha}{Raster opacity} + +\item{nodata_value}{The nodata value specified from the flux data.} + +\item{colormap}{palette_explorer() for palette options} + +\item{style}{quantile, equal, cont, cat} + +\item{color_n}{color categories in palette} +} +\description{ +Function definition. This function creates a flux map visualization on a user defined basemap. +} +\references{ +License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +} +\seealso{ +Currently none. +} +\author{ +Sam Bower \email{sbower@atmofacts.com} +} +\keyword{flux} +\keyword{mapping} +\keyword{visualization,} diff --git a/pack/eddy4R.maps/man/def.spat.data.cube.Rd b/pack/eddy4R.maps/man/def.spat.data.cube.Rd new file mode 100644 index 00000000..4cbbfa1a --- /dev/null +++ b/pack/eddy4R.maps/man/def.spat.data.cube.Rd @@ -0,0 +1,64 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/def.spat.data.cube.R +\name{def.spat.data.cube} +\alias{def.spat.data.cube} +\title{definition function to download data from Microsoft planetary computer} +\usage{ +def.spat.data.cube( + start_date, + end_date, + box, + collection = c("modis-15A2H-061", "sentinel-3-slstr-lst-l2-netcdf")[2], + asset_name = c("Lai_500m", "lst-in")[2], + srs = "EPSG:4326", + dx = 0.1, + dy = 0.1, + dt = "P1M", + aggregation = "mean", + resampling = "near" +) +} +\arguments{ +\item{start_date}{start date as character format yyyy-mm-dd} + +\item{end_date}{end date as character format yyyy-mm-dd} + +\item{box}{numberic vector in the format of (xmin, ymin, xmax, ymax)} + +\item{collection}{name of planetary collection} + +\item{asset_name}{mame of asset} + +\item{srs}{target spatial reference system as a string; can be a proj4 definition, WKT, or in the form "EPSG:XXXX"} + +\item{dx}{size of pixels in x-direction (longitude / easting)} + +\item{dy}{size of pixels in y-direction (latitude / northing)} + +\item{dt}{size of pixels in time-direction, expressed as ISO8601 period string (only 1 number and unit is allowed) such as "P16D"} + +\item{aggregation}{aggregation method as string, defining how to deal with pixels containing data from multiple images, can be "min", "max", "mean", "median", or "first"} + +\item{resampling}{resampling method used in gdalwarp when images are read, can be "near", "bilinear", "bicubic" or others as supported by gdalwarp (see https://gdal.org/programs/gdalwarp.html)} +} +\value{ +A data cube proxy object +} +\description{ +Function definition. Download data from Microsoft planetary computer +} +\examples{ +ingest_planetary_data(start_date = "2022-01-01", end_date = "2023-07-01", box = c("xmin" = -123, "ymin" = 39, "xmax" = -122, "ymax" = 40)) +} +\references{ +License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +} +\seealso{ +Currently none +} +\author{ +David Durden +Stefan Metzger \email{smetzger@atmofacts.com} +} +\keyword{Currently} +\keyword{none} diff --git a/pack/eddy4R.maps/man/def.spatialize.flux.foot.Rd b/pack/eddy4R.maps/man/def.spatialize.flux.foot.Rd new file mode 100644 index 00000000..7fb60938 --- /dev/null +++ b/pack/eddy4R.maps/man/def.spatialize.flux.foot.Rd @@ -0,0 +1,74 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/def.spatialize.flux.foot.R +\name{def.spatialize.flux.foot} +\alias{def.spatialize.flux.foot} +\title{Spatialize Flux Footprint Data into Raster Format} +\usage{ +def.spatialize.flux.foot( + flux_input, + lower_left_X, + lower_left_Y, + nodata_value = 0, + cell_size = 10, + crs = "+proj=utm +zone=13 +datum=WGS84 +units=m +no_defs", + write = FALSE, + output_filename = NULL, + file_format = "GTiff" +) +} +\arguments{ +\item{flux_input}{The input flux data, which can be a path to an ASCII grid or CSV file, a matrix, +or a data frame.} + +\item{lower_left_X}{The X coordinate of the lower left corner of the output raster.} + +\item{lower_left_Y}{The Y coordinate of the lower left corner of the output raster.} + +\item{nodata_value}{The value to be considered as 'no data' in the input flux data. Defaults to 0.} + +\item{cell_size}{The size of each cell in the output raster, assumed to be square. Defaults to 10.} + +\item{crs}{The coordinate reference system for the output raster, specified in PROJ.4 format. +Defaults to "+proj=utm +zone=13 +datum=WGS84 +units=m +no_defs".} + +\item{write}{Logical, whether to write the output raster to a file. Defaults to FALSE.} + +\item{output_filename}{The filename (including path) for the output file if write is TRUE. +If NULL and write is TRUE, an error is thrown.} + +\item{file_format}{The format of the output file, defaults to 'GTiff'.} +} +\value{ +A raster object representing the spatialized flux data. +} +\description{ +This function processes flux footprint data, spatializing it into a raster format +suitable for GIS analysis. It supports reading flux data from various formats, setting the +spatial extent, and defining the coordinate reference system (CRS). The output can optionally +be written to a file in GeoTiff format. +} +\examples{ +# Example usage: +raster <- def.spatialize.flux.foot(flux_input = "path/to/data.csv", + lower_left_X = 100000, + lower_left_Y = 400000, + cell_size = 10, + crs = "+proj=utm +zone=13 +datum=WGS84 +units=m +no_defs", + write = TRUE, + output_filename = "output.tif", + file_format = 'GTiff') + +} +\references{ +License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +} +\seealso{ +\code{\link[raster]{writeRaster}}, \code{\link[raster]{raster}}, \code{\link[sp]{CRS}} +} +\author{ +Sam Bower \email{sbower@atmofacts.com} +} +\keyword{GIS,} +\keyword{flux} +\keyword{raster,} +\keyword{spatial,} diff --git a/pack/eddy4R.maps/man/wrap.spat.data.grab.Rd b/pack/eddy4R.maps/man/wrap.spat.data.grab.Rd new file mode 100644 index 00000000..978ab30c --- /dev/null +++ b/pack/eddy4R.maps/man/wrap.spat.data.grab.Rd @@ -0,0 +1,42 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/wrap.spat.data.R +\name{wrap.spat.data.grab} +\alias{wrap.spat.data.grab} +\title{wrapper function to generate spatial targets} +\usage{ +wrap.spat.data.grab( + dir = tempdir(), + dateBgn = "2019-05-01", + dateEnd = "2019-11-30", + site = c("CPER", "CHEESEHEAD")[2], + dt = "P1M", + dx = 0.1, + dy = 0.1 +) +} +\arguments{ +\item{dir}{A directory of .tif files for scoring} + +\item{site_id}{The side ID of the area being forecasted. Currently "august_complex" is the only option.} +} +\value{ +message from minio submission +} +\description{ +Wrapper definition. Generate spatial targets +} +\examples{ +spat4cast_submit(dir = "targets", site_id = "august_complex") +} +\references{ +License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +} +\seealso{ +Currently none +} +\author{ +David Durden +Stefan Metzger \email{smetzger@atmofacts.com} +} +\keyword{Currently} +\keyword{none} diff --git a/pack/eddy4R.qaqc/man/def.plau.Rd b/pack/eddy4R.qaqc/man/def.plau.Rd index 65d402c7..35fded23 100644 --- a/pack/eddy4R.qaqc/man/def.plau.Rd +++ b/pack/eddy4R.qaqc/man/def.plau.Rd @@ -56,7 +56,6 @@ data <- data.frame(x=rnorm(1000,mean=0,sd=1)) # Start off with a vector of 1000 data$x[c(20,50,500,90)] <- 50 # insert some spikes data$x[600:699] <- rnorm(100,mean=0,sd=0.001) # Add some "stuck" data data$x[800:810] <- NA -data$x[400:450] <- Inf # Results in Error RngMin <- -4 RngMax <- 4 DiffStepMax <- 6 diff --git a/pack/renv/settings.json b/pack/renv/settings.json new file mode 100644 index 00000000..d2f7e2b8 --- /dev/null +++ b/pack/renv/settings.json @@ -0,0 +1,30 @@ +{ + "bioconductor.version": null, + "external.libraries": [], + "ignored.packages": [ + "eddy4R.base", + "eddy4R.turb", + "eddy4R.erf", + "eddy4R.stor", + "eddy4R.qaqc", + "eddy4R.maps", + "som", + "Noble", + "eddy4R.ucrt", + "Waves", + "accs", + "NEONprocIS.base" + ], + "package.dependency.fields": [ + "Imports", + "Depends", + "LinkingTo" + ], + "r.version": null, + "snapshot.type": "implicit", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} diff --git a/renv.lock b/renv.lock index 195a8def..080750dd 100644 --- a/renv.lock +++ b/renv.lock @@ -1,7 +1,27 @@ { "R": { - "Version": "4.0.5", + "Version": "4.2.2", "Repositories": [ + { + "Name": "BioCsoft", + "URL": "https://bioconductor.org/packages/3.16/bioc" + }, + { + "Name": "BioCann", + "URL": "https://bioconductor.org/packages/3.16/data/annotation" + }, + { + "Name": "BioCexp", + "URL": "https://bioconductor.org/packages/3.16/data/experiment" + }, + { + "Name": "BioCworkflows", + "URL": "https://bioconductor.org/packages/3.16/workflows" + }, + { + "Name": "BioCbooks", + "URL": "https://bioconductor.org/packages/3.16/books" + }, { "Name": "CRANNew", "URL": "https://packagemanager.rstudio.com/cran/2023-09-22" @@ -21,41 +41,53 @@ ] }, "Bioconductor": { - "Version": "3.12" + "Version": "3.16" }, "Packages": { + "BH": { + "Package": "BH", + "Version": "1.81.0-1", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "68122010f01c4dcfbe58ce7112f2433d" + }, "BiocGenerics": { "Package": "BiocGenerics", - "Version": "0.36.1", + "Version": "0.44.0", "Source": "Bioconductor", + "git_url": "https://git.bioconductor.org/packages/BiocGenerics", + "git_branch": "RELEASE_3_16", + "git_last_commit": "d7cd9c1", + "git_last_commit_date": "2022-11-01", "Requirements": [ "R", "graphics", "methods", - "parallel", "stats", "utils" ], - "Hash": "f628c51eadc74ffd838b801cd22d589a" + "Hash": "0de19224c2cd94f48fbc0d0bc663ce3b" }, "BiocManager": { "Package": "BiocManager", - "Version": "1.30.22", + "Version": "1.30.20", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "utils" ], - "Hash": "d57e43105a1aa9cb54fdb4629725acb1" + "Hash": "a7fca16a50b6ef7771b49d636dd54b57" }, - "BiocVersion": { - "Package": "BiocVersion", - "Version": "3.12.0", - "Source": "Bioconductor", + "DBI": { + "Package": "DBI", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "RSPM", "Requirements": [ - "R" + "R", + "methods" ], - "Hash": "ee4d027afb8f52fec1f46b9f0a8660e9" + "Hash": "b2866e62bab9378c3cc9476a1954226b" }, "DEoptimR": { "Package": "DEoptimR", @@ -81,8 +113,12 @@ }, "EBImage": { "Package": "EBImage", - "Version": "4.32.0", + "Version": "4.40.1", "Source": "Bioconductor", + "git_url": "https://git.bioconductor.org/packages/EBImage", + "git_branch": "RELEASE_3_16", + "git_last_commit": "f2b0b41", + "git_last_commit_date": "2023-04-09", "Requirements": [ "BiocGenerics", "RCurl", @@ -100,7 +136,7 @@ "tiff", "utils" ], - "Hash": "c7e9e12a627de495c8531bfee0f5af4f" + "Hash": "846bb2e1bfdd6b605c729c409d1fc8b5" }, "EMD": { "Package": "EMD", @@ -127,18 +163,18 @@ }, "KernSmooth": { "Package": "KernSmooth", - "Version": "2.23-18", + "Version": "2.23-20", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "stats" ], - "Hash": "9e703ad8bf0e99f3691f05da32dfe68b" + "Hash": "8dcfa99b14c296bc9f1fd64d52fd3ce7" }, "MASS": { "Package": "MASS", - "Version": "7.3-53.1", + "Version": "7.3-58.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -149,11 +185,11 @@ "stats", "utils" ], - "Hash": "4ef21dd0348b9abb7f8bd1d77e4cd0c3" + "Hash": "762e1804143a332333c054759f89a706" }, "Matrix": { "Package": "Matrix", - "Version": "1.3-2", + "Version": "1.5-1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -165,7 +201,24 @@ "stats", "utils" ], - "Hash": "ff280503079ad8623d3c4b1519b24ea2" + "Hash": "539dc0c0c05636812f1080f473d2c177" + }, + "OpenStreetMap": { + "Package": "OpenStreetMap", + "Version": "0.3.4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "ggplot2", + "grDevices", + "methods", + "rJava", + "raster", + "rgdal", + "sp" + ], + "Hash": "01411659918d6e4d5b3eda0e9e7c0bf1" }, "R.methodsS3": { "Package": "R.methodsS3", @@ -245,7 +298,7 @@ }, "RCurl": { "Package": "RCurl", - "Version": "1.98-1.12", + "Version": "1.98-1.10", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -253,18 +306,18 @@ "bitops", "methods" ], - "Hash": "1d6ed2d006d483f31c6d5531f3a39923" + "Hash": "35136c52e39f2679ebbe7bf448e3bd5a" }, "Rcpp": { "Package": "Rcpp", - "Version": "1.0.11", + "Version": "1.0.10", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "methods", "utils" ], - "Hash": "ae6cbbe1492f4de79c45fce06f967ce8" + "Hash": "e749cae40fa9ef469b6050959517453c" }, "RcppRoll": { "Package": "RcppRoll", @@ -279,12 +332,16 @@ }, "Rhdf5lib": { "Package": "Rhdf5lib", - "Version": "1.12.1", + "Version": "1.20.0", "Source": "Bioconductor", + "git_url": "https://git.bioconductor.org/packages/Rhdf5lib", + "git_branch": "RELEASE_3_16", + "git_last_commit": "7606799", + "git_last_commit_date": "2022-11-01", "Requirements": [ "R" ], - "Hash": "7dc9be3558a910226d64a2040520dc7f" + "Hash": "66fbe0c49a27fe0a17182554f14f7fbc" }, "Rmisc": { "Package": "Rmisc", @@ -297,6 +354,18 @@ ], "Hash": "c3c3d6c3abc276bc7849835d5d54c44d" }, + "XML": { + "Package": "XML", + "Version": "3.99-0.14", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "methods", + "utils" + ], + "Hash": "e5c8af79df616c135b21eaeb1dc6bc5c" + }, "abind": { "Package": "abind", "Version": "1.4-5", @@ -311,13 +380,23 @@ }, "askpass": { "Package": "askpass", - "Version": "1.2.0", + "Version": "1.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "sys" ], - "Hash": "cad6cf7f1d5f6e906700b9d3e718c796" + "Hash": "e8a22846fff485f0be3770c2da758713" + }, + "assertthat": { + "Package": "assertthat", + "Version": "0.2.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "tools" + ], + "Hash": "50c838a310445e954bc13f26f26a6ecf" }, "base64enc": { "Package": "base64enc", @@ -348,7 +427,7 @@ }, "boot": { "Package": "boot", - "Version": "1.3-27", + "Version": "1.3-28", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -356,7 +435,7 @@ "graphics", "stats" ], - "Hash": "d9778c960792721e8433daaf3db8f16a" + "Hash": "0baa960e3b49c6176a4f42addcbacc59" }, "brew": { "Package": "brew", @@ -374,7 +453,7 @@ }, "bslib": { "Package": "bslib", - "Version": "0.5.1", + "Version": "0.4.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -390,18 +469,18 @@ "rlang", "sass" ], - "Hash": "283015ddfbb9d7bf15ea9f0b5698f0d9" + "Hash": "a7fbf03946ad741129dc81098722fca1" }, "cachem": { "Package": "cachem", - "Version": "1.0.8", + "Version": "1.0.7", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "fastmap", "rlang" ], - "Hash": "c35768291560ce302c0a6589f92e837d" + "Hash": "cda74447c42f529de601fe4d4050daef" }, "callr": { "Package": "callr", @@ -416,16 +495,45 @@ ], "Hash": "9b2191ede20fa29828139b9900922e51" }, + "class": { + "Package": "class", + "Version": "7.3-20", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "MASS", + "R", + "stats", + "utils" + ], + "Hash": "da09d82223e669d270e47ed24ac8686e" + }, + "classInt": { + "Package": "classInt", + "Version": "0.4-9", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "KernSmooth", + "R", + "class", + "e1071", + "grDevices", + "graphics", + "stats" + ], + "Hash": "bee651a42a89633eccb36dca9d9ab413" + }, "cli": { "Package": "cli", - "Version": "3.6.1", + "Version": "3.6.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "utils" ], - "Hash": "89e6d8219950eac806ae0c489052048a" + "Hash": "3177a5a16c243adc199ba33117bd9657" }, "clipr": { "Package": "clipr", @@ -460,20 +568,17 @@ }, "commonmark": { "Package": "commonmark", - "Version": "1.9.0", + "Version": "1.8.1", "Source": "Repository", "Repository": "RSPM", - "Hash": "d691c61bff84bd63c383874d2d0c3307" + "Hash": "b6e3e947d1d7ebf3d2bdcea1bde63fe7" }, "cpp11": { "Package": "cpp11", - "Version": "0.4.6", + "Version": "0.4.3", "Source": "Repository", "Repository": "RSPM", - "Requirements": [ - "R" - ], - "Hash": "707fae4bbf73697ec8d85f9d7076c061" + "Hash": "ed588261931ee3be2c700d22e94a29ab" }, "crayon": { "Package": "crayon", @@ -489,7 +594,7 @@ }, "credentials": { "Package": "credentials", - "Version": "2.0.1", + "Version": "1.3.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -499,17 +604,30 @@ "openssl", "sys" ], - "Hash": "c7844b32098dcbd1c59cbd8dddb4ecc6" + "Hash": "93762d0a34d78e6a025efdbfb5c6bb41" + }, + "crosstalk": { + "Package": "crosstalk", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R6", + "htmltools", + "jsonlite", + "lazyeval" + ], + "Hash": "6aa54f69598c32177e920eb3402e8293" }, "curl": { "Package": "curl", - "Version": "5.0.2", + "Version": "5.0.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R" ], - "Hash": "511bacbfa153a15251166b463b4da4f9" + "Hash": "e4f97056611e8e6b8b852d13b7400cf1" }, "data.table": { "Package": "data.table", @@ -580,6 +698,17 @@ ], "Hash": "ea5bc8b4a6a01e4f12d98b58329930bb" }, + "dichromat": { + "Package": "dichromat", + "Version": "2.0-0.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "stats" + ], + "Hash": "16e66f2a483e124af5fc6582d26005f7" + }, "diffobj": { "Package": "diffobj", "Version": "0.3.5", @@ -597,14 +726,14 @@ }, "digest": { "Package": "digest", - "Version": "0.6.33", + "Version": "0.6.31", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "utils" ], - "Hash": "b18a9cf3c003977b0cc49d5e76ebe48d" + "Hash": "8b708f296afd9ae69f450f9640be8990" }, "dotCall64": { "Package": "dotCall64", @@ -618,7 +747,7 @@ }, "downlit": { "Package": "downlit", - "Version": "0.4.3", + "Version": "0.4.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -634,7 +763,7 @@ "withr", "yaml" ], - "Hash": "14fa1f248b60ed67e1f5418391a17b14" + "Hash": "79bf3f66590752ffbba20f8d2da94c7c" }, "downloader": { "Package": "downloader", @@ -649,7 +778,7 @@ }, "dplyr": { "Package": "dplyr", - "Version": "1.1.3", + "Version": "1.1.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -668,7 +797,23 @@ "utils", "vctrs" ], - "Hash": "e85ffbebaad5f70e1a2e2ef4302b4949" + "Hash": "d3c34618017e7ae252d46d79a1b9ec32" + }, + "e1071": { + "Package": "e1071", + "Version": "1.7-13", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "class", + "grDevices", + "graphics", + "methods", + "proxy", + "stats", + "utils" + ], + "Hash": "1046cb48d06cb40c2900d8878f03a0fe" }, "ellipsis": { "Package": "ellipsis", @@ -683,14 +828,14 @@ }, "evaluate": { "Package": "evaluate", - "Version": "0.21", + "Version": "0.20", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "methods" ], - "Hash": "d59f3b464e8da1aef82dc04b588b8dfb" + "Hash": "4b68aa51edd89a0e044a66e75ae3cc6c" }, "fansi": { "Package": "fansi", @@ -790,7 +935,7 @@ }, "fontawesome": { "Package": "fontawesome", - "Version": "0.5.2", + "Version": "0.5.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -798,18 +943,32 @@ "htmltools", "rlang" ], - "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d" + "Hash": "e80750aec5717dedc019ad7ee40e4a7c" }, "fs": { "Package": "fs", - "Version": "1.6.3", + "Version": "1.6.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "methods" ], - "Hash": "47b5f30c720c23999b913a1a635cf0bb" + "Hash": "f4dcd23b67e33d851d2079f703e8b985" + }, + "gdalcubes": { + "Package": "gdalcubes", + "Version": "0.6.4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "BH", + "R", + "Rcpp", + "jsonlite", + "ncdf4" + ], + "Hash": "78c2ae3c1caeeb19635eb2ff932c4252" }, "generics": { "Package": "generics", @@ -822,9 +981,34 @@ ], "Hash": "15e9634c0fcd294799e9b2e929ed1b86" }, + "geojsonsf": { + "Package": "geojsonsf", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "Rcpp", + "geometries", + "jsonify", + "rapidjsonr", + "sfheaders" + ], + "Hash": "8d077646c6713838233e8710910ef92e" + }, + "geometries": { + "Package": "geometries", + "Version": "0.2.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "Rcpp" + ], + "Hash": "09604531daa57d9c3884b7a15488bab9" + }, "gert": { "Package": "gert", - "Version": "1.9.3", + "Version": "1.9.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -835,11 +1019,11 @@ "sys", "zip" ], - "Hash": "b544c397820e05a97d391b2d614a921a" + "Hash": "9122b3958e749badb5c939f498038b57" }, "ggplot2": { "Package": "ggplot2", - "Version": "3.4.3", + "Version": "3.4.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -860,7 +1044,7 @@ "vctrs", "withr" ], - "Hash": "85846544c596e71f8f46483ab165da33" + "Hash": "d494daf77c4aa7f084dbbe6ca5dcaca7" }, "gh": { "Package": "gh", @@ -878,6 +1062,13 @@ ], "Hash": "03533b1c875028233598f848fda44c4c" }, + "gifski": { + "Package": "gifski", + "Version": "1.12.0-2", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "94ea43ec9e47684c20810e9272605425" + }, "gitcreds": { "Package": "gitcreds", "Version": "0.1.2", @@ -915,18 +1106,14 @@ }, "gtable": { "Package": "gtable", - "Version": "0.3.4", + "Version": "0.3.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", - "cli", - "glue", - "grid", - "lifecycle", - "rlang" + "grid" ], - "Hash": "b29cf3031f49b04ab9c852c912547eef" + "Hash": "36b4265fb818f6a342bed217549cd896" }, "highr": { "Package": "highr", @@ -941,7 +1128,7 @@ }, "htmltools": { "Package": "htmltools", - "Version": "0.5.6", + "Version": "0.5.4", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -954,11 +1141,11 @@ "rlang", "utils" ], - "Hash": "a2326a66919a3311f7fbb1e3bf568283" + "Hash": "9d27e99cc90bd701c0a7a63e5923f9b7" }, "htmlwidgets": { "Package": "htmlwidgets", - "Version": "1.6.2", + "Version": "1.6.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -969,11 +1156,11 @@ "rmarkdown", "yaml" ], - "Hash": "a865aa85bcb2697f47505bfd70422471" + "Hash": "b677ee5954471eaa974c0d099a343a1a" }, "httpuv": { "Package": "httpuv", - "Version": "1.6.11", + "Version": "1.6.9", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -984,11 +1171,11 @@ "promises", "utils" ], - "Hash": "838602f54e32c1a0f8cc80708cefcefa" + "Hash": "1046aa31a57eae8b357267a56a0b6d8b" }, "httr": { "Package": "httr", - "Version": "1.4.7", + "Version": "1.4.5", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -999,11 +1186,11 @@ "mime", "openssl" ], - "Hash": "ac107251d9d9fd72f0ca8049988f1d7f" + "Hash": "f6844033201269bec3ca0097bc6c97b3" }, "httr2": { "Package": "httr2", - "Version": "0.2.3", + "Version": "0.2.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1018,7 +1205,7 @@ "rlang", "withr" ], - "Hash": "193bb297368afbbb42dc85784a46b36e" + "Hash": "5c09fe33064978ede54de42309c8b532" }, "ini": { "Package": "ini", @@ -1058,19 +1245,31 @@ ], "Hash": "5aab57a3bd297eee1c1d862735972182" }, + "jsonify": { + "Package": "jsonify", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "Rcpp", + "rapidjsonr" + ], + "Hash": "49a9775e4f8c96c654b6018739067055" + }, "jsonlite": { "Package": "jsonlite", - "Version": "1.8.7", + "Version": "1.8.4", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "methods" ], - "Hash": "266a20443ca13c65688b2116d5220f76" + "Hash": "a4269a09a9b865579b2635c77e572374" }, "knitr": { "Package": "knitr", - "Version": "1.44", + "Version": "1.42", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1082,33 +1281,33 @@ "xfun", "yaml" ], - "Hash": "60885b9f746c9dfaef110d070b5f7dc0" + "Hash": "8329a9bcc82943c8069104d4be3ee22d" }, "labeling": { "Package": "labeling", - "Version": "0.4.3", + "Version": "0.4.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "graphics", "stats" ], - "Hash": "b64ec208ac5bc1852b285f665d6368b3" + "Hash": "3d5108641f47470611a32d0bdf357a72" }, "later": { "Package": "later", - "Version": "1.3.1", + "Version": "1.3.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "Rcpp", "rlang" ], - "Hash": "40401c9cf2bc2259dfe83311c9384710" + "Hash": "7e7b457d7766bc47f2a5f21cc2984f8e" }, "lattice": { "Package": "lattice", - "Version": "0.20-41", + "Version": "0.20-45", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1119,7 +1318,85 @@ "stats", "utils" ], - "Hash": "fbd9285028b0263d76d18c95ae51a53d" + "Hash": "b64cdbb2b340437c4ee047a1f4c4377b" + }, + "lazyeval": { + "Package": "lazyeval", + "Version": "0.2.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "d908914ae53b04d4c0c0fd72ecc35370" + }, + "leafem": { + "Package": "leafem", + "Version": "0.2.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "base64enc", + "geojsonsf", + "htmltools", + "htmlwidgets", + "leaflet", + "methods", + "png", + "raster", + "sf" + ], + "Hash": "db6e565a81ce81f137660467644e6fcd" + }, + "leaflet": { + "Package": "leaflet", + "Version": "2.1.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "RColorBrewer", + "base64enc", + "crosstalk", + "htmltools", + "htmlwidgets", + "leaflet.providers", + "magrittr", + "markdown", + "methods", + "png", + "raster", + "scales", + "sp", + "stats", + "viridis" + ], + "Hash": "ac2c7f21c2a6d2579eed8aaae4c42610" + }, + "leaflet.providers": { + "Package": "leaflet.providers", + "Version": "1.9.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "d3082a7beac4a1aeb96100ff06265d7e" + }, + "leafsync": { + "Package": "leafsync", + "Version": "0.1.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "htmltools", + "htmlwidgets", + "leaflet", + "methods" + ], + "Hash": "819d7169c7d39f0f952473e943375da1" }, "lgr": { "Package": "lgr", @@ -1147,14 +1424,14 @@ }, "locfit": { "Package": "locfit", - "Version": "1.5-9.4", + "Version": "1.5-9.7", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "lattice" ], - "Hash": "760b5b542e8435237d1b3c253bfe18e7" + "Hash": "08c4156abea85c9b6d4e7798427a887d" }, "lubridate": { "Package": "lubridate", @@ -1169,6 +1446,19 @@ ], "Hash": "e25f18436e3efd42c7c590a1c4c15390" }, + "lwgeom": { + "Package": "lwgeom", + "Version": "0.2-13", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "Rcpp", + "sf", + "units" + ], + "Hash": "9804362cc0267990ac61a85edeca73ed" + }, "magrittr": { "Package": "magrittr", "Version": "2.0.3", @@ -1191,6 +1481,19 @@ ], "Hash": "644a88fb036ab50cee0b715394eefa1a" }, + "markdown": { + "Package": "markdown", + "Version": "1.5", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "commonmark", + "utils", + "xfun" + ], + "Hash": "d209cfd1f4ff7260eae5a7f07da3aa4f" + }, "matlab": { "Package": "matlab", "Version": "1.0.4", @@ -1215,7 +1518,7 @@ }, "mgcv": { "Package": "mgcv", - "Version": "1.8-34", + "Version": "1.8-41", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1228,7 +1531,7 @@ "stats", "utils" ], - "Hash": "bd4a6c4b600f58651d60d381b0e9a397" + "Hash": "6b3904f13346742caa3e82dd0303d4ad" }, "mime": { "Package": "mime", @@ -1274,6 +1577,13 @@ ], "Hash": "463b268710930f7bffef33147400966a" }, + "ncdf4": { + "Package": "ncdf4", + "Version": "1.21", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "a7b262641ef4659767d415c6bb78413f" + }, "neonUtilities": { "Package": "neonUtilities", "Version": "2.3.0", @@ -1298,7 +1608,7 @@ }, "nlme": { "Package": "nlme", - "Version": "3.1-152", + "Version": "3.1-160", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1308,17 +1618,17 @@ "stats", "utils" ], - "Hash": "35de1ce639f20b5e10f7f46260730c65" + "Hash": "02e3c6e7df163aafa8477225e6827bc5" }, "openssl": { "Package": "openssl", - "Version": "2.1.0", + "Version": "2.0.6", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "askpass" ], - "Hash": "273a6bb4a9844c296a459d2176673270" + "Hash": "0f7cd2962e3044bb940cca4f4b5cecbe" }, "pbapply": { "Package": "pbapply", @@ -1344,7 +1654,7 @@ }, "pillar": { "Package": "pillar", - "Version": "1.9.0", + "Version": "1.8.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1357,11 +1667,11 @@ "utils", "vctrs" ], - "Hash": "15da5a8412f317beeee6175fbc76f4bb" + "Hash": "f2316df30902c81729ae9de95ad5a608" }, "pkgbuild": { "Package": "pkgbuild", - "Version": "1.4.2", + "Version": "1.4.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1373,9 +1683,10 @@ "desc", "prettyunits", "processx", - "rprojroot" + "rprojroot", + "withr" ], - "Hash": "beb25b32a957a22a5c301a9e441190b3" + "Hash": "d6c3008d79653a0f267703288230105e" }, "pkgconfig": { "Package": "pkgconfig", @@ -1419,7 +1730,7 @@ }, "pkgload": { "Package": "pkgload", - "Version": "1.3.2.1", + "Version": "1.3.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1435,7 +1746,7 @@ "utils", "withr" ], - "Hash": "a7f498a1b2a4a6816148e498509f6e1d" + "Hash": "6b0c222c5071efe0f3baf3dae9aa40e2" }, "plyr": { "Package": "plyr", @@ -1485,7 +1796,7 @@ }, "processx": { "Package": "processx", - "Version": "3.8.2", + "Version": "3.8.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1494,53 +1805,61 @@ "ps", "utils" ], - "Hash": "3efbd8ac1be0296a46c55387aeace0f3" + "Hash": "a33ee2d9bf07564efb888ad98410da84" }, "profvis": { "Package": "profvis", - "Version": "0.3.8", + "Version": "0.3.7", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "htmlwidgets", - "purrr", - "rlang", - "stringr", - "vctrs" + "stringr" ], - "Hash": "aa5a3864397ce6ae03458f98618395a1" + "Hash": "e9d21e79848e02e524bea6f5bd53e7e4" }, "promises": { "Package": "promises", - "Version": "1.2.1", + "Version": "1.2.0.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R6", "Rcpp", - "fastmap", "later", "magrittr", "rlang", "stats" ], - "Hash": "0d8a15c9d000970ada1ab21405387dee" + "Hash": "4ab2c43adb4d4699cf3690acd378d75d" + }, + "proxy": { + "Package": "proxy", + "Version": "0.4-27", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "stats", + "utils" + ], + "Hash": "e0ef355c12942cf7a6b91a6cfaea8b3e" }, "ps": { "Package": "ps", - "Version": "1.7.5", + "Version": "1.7.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "utils" ], - "Hash": "709d852d33178db54b17c722e5b1e594" + "Hash": "68dd03d98a5efd1eb3012436de45ba83" }, "purrr": { "Package": "purrr", - "Version": "1.0.2", + "Version": "1.0.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1551,7 +1870,18 @@ "rlang", "vctrs" ], - "Hash": "1cba04a4e9414bdefc9dcaa99649a8dc" + "Hash": "d71c815267c640f17ddbf7f16144b4bb" + }, + "rJava": { + "Package": "rJava", + "Version": "1.0-6", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "methods" + ], + "Hash": "0415819f6baa75d86d52483f7292b623" }, "ragg": { "Package": "ragg", @@ -1564,6 +1894,13 @@ ], "Hash": "690bc058ea2b1b8a407d3cfe3dce3ef9" }, + "rapidjsonr": { + "Package": "rapidjsonr", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "88b9f48c93d17cdb811b54079a6a414f" + }, "rappdirs": { "Package": "rappdirs", "Version": "0.3.3", @@ -1574,6 +1911,20 @@ ], "Hash": "5e3c5dc0b071b21fa128676560dbe94d" }, + "raster": { + "Package": "raster", + "Version": "3.6-20", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "Rcpp", + "methods", + "sp", + "terra" + ], + "Hash": "ebebd9f0f203a129eb2da96470191b82" + }, "rcmdcheck": { "Package": "rcmdcheck", "Version": "1.4.0", @@ -1608,7 +1959,7 @@ }, "remotes": { "Package": "remotes", - "Version": "2.4.2.1", + "Version": "2.4.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1618,17 +1969,17 @@ "tools", "utils" ], - "Hash": "63d15047eb239f95160112bcadc4fcb9" + "Hash": "227045be9aee47e6dda9bb38ac870d67" }, "renv": { "Package": "renv", - "Version": "1.0.3", + "Version": "0.17.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "utils" ], - "Hash": "41b847654f567341725473431dd0d5ab" + "Hash": "4543b8cd233ae25c6aba8548be9e747e" }, "reshape2": { "Package": "reshape2", @@ -1643,48 +1994,71 @@ ], "Hash": "bb5996d0bd962d214a11140d77589917" }, + "rgdal": { + "Package": "rgdal", + "Version": "1.6-7", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "grDevices", + "graphics", + "methods", + "sp", + "stats", + "utils" + ], + "Hash": "10b777236c9e7855bc9dea8e347e30b7" + }, "rhdf5": { "Package": "rhdf5", - "Version": "2.34.0", + "Version": "2.42.1", "Source": "Bioconductor", + "git_url": "https://git.bioconductor.org/packages/rhdf5", + "git_branch": "RELEASE_3_16", + "git_last_commit": "8df5fc7", + "git_last_commit_date": "2023-04-07", "Requirements": [ "R", "Rhdf5lib", "methods", "rhdf5filters" ], - "Hash": "bf25b880f72c8b6dcbd8719b5ac9113b" + "Hash": "5c03978672acd1d85ce56f9d12f5fe5b" }, "rhdf5filters": { "Package": "rhdf5filters", - "Version": "1.2.1", + "Version": "1.10.1", "Source": "Bioconductor", + "git_url": "https://git.bioconductor.org/packages/rhdf5filters", + "git_branch": "RELEASE_3_16", + "git_last_commit": "ccf950c", + "git_last_commit_date": "2023-03-24", "Requirements": [ "Rhdf5lib" ], - "Hash": "4e9258b05bbcbc1093eda53aa8051264" + "Hash": "63806aa966d50f02b18aba6d0d34e3c8" }, "rlang": { "Package": "rlang", - "Version": "1.1.1", + "Version": "1.0.6", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "utils" ], - "Hash": "a85c767b55f0bf9b7ad16c6d7baee5bb" + "Hash": "4ed1f8336c8d52c3e750adcdc57228a7" }, "rmarkdown": { "Package": "rmarkdown", - "Version": "2.25", + "Version": "2.20", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "bslib", "evaluate", - "fontawesome", "htmltools", "jquerylib", "jsonlite", @@ -1697,7 +2071,7 @@ "xfun", "yaml" ], - "Hash": "d65e35823c817f09f4de424fcdfa812a" + "Hash": "716fde5382293cc94a71f68c85b78d19" }, "robfilter": { "Package": "robfilter", @@ -1800,12 +2174,28 @@ ], "Hash": "5f22863b417e1178980a3105fe66bd51" }, + "rstac": { + "Package": "rstac", + "Version": "0.9.2-4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "crayon", + "httr", + "jsonlite", + "lifecycle", + "magrittr", + "utils" + ], + "Hash": "1d4eec2c2df01ea9f524bd713c8e9349" + }, "rstudioapi": { "Package": "rstudioapi", - "Version": "0.15.0", + "Version": "0.14", "Source": "Repository", "Repository": "RSPM", - "Hash": "5564500e25cffad9e22244ced1379887" + "Hash": "690bd2acc42a9166ce34845884459320" }, "rversions": { "Package": "rversions", @@ -1819,9 +2209,21 @@ ], "Hash": "a9881dfed103e83f9de151dc17002cd1" }, + "s2": { + "Package": "s2", + "Version": "1.1.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "Rcpp", + "wk" + ], + "Hash": "5cca323babe990f99d5bc3402f64b905" + }, "sass": { "Package": "sass", - "Version": "0.4.7", + "Version": "0.4.5", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1831,7 +2233,7 @@ "rappdirs", "rlang" ], - "Hash": "6bd4d33b50ff927191ec9acbf52fd056" + "Hash": "2bb4371a4c80115518261866eab6ab11" }, "scales": { "Package": "scales", @@ -1864,6 +2266,41 @@ ], "Hash": "3f9796a8d0a0e8c6eb49a4b029359d1f" }, + "sf": { + "Package": "sf", + "Version": "1.0-10", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "DBI", + "R", + "Rcpp", + "classInt", + "grDevices", + "graphics", + "grid", + "magrittr", + "methods", + "s2", + "stats", + "tools", + "units", + "utils" + ], + "Hash": "63879bf5f4900e021a660a48716278fc" + }, + "sfheaders": { + "Package": "sfheaders", + "Version": "0.4.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "Rcpp", + "geometries" + ], + "Hash": "0b835f43939178a3cac6712fbe8cc2e8" + }, "sfsmisc": { "Package": "sfsmisc", "Version": "1.1-16", @@ -1880,7 +2317,7 @@ }, "shiny": { "Package": "shiny", - "Version": "1.7.5", + "Version": "1.7.4", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1910,7 +2347,7 @@ "withr", "xtable" ], - "Hash": "438b99792adbe82a8329ad8697d45afe" + "Hash": "c2eae3d8c670fa9dfa35a12066f4a1d5" }, "signal": { "Package": "signal", @@ -1937,6 +2374,23 @@ ], "Hash": "5f5a7629f956619d519205ec475fe647" }, + "sp": { + "Package": "sp", + "Version": "1.6-0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "grDevices", + "graphics", + "grid", + "lattice", + "methods", + "stats", + "utils" + ], + "Hash": "6674e075a078d9c3bde8ba800367347c" + }, "spam": { "Package": "spam", "Version": "2.9-1", @@ -1961,6 +2415,23 @@ ], "Hash": "55cafdb25f64a02bcbbe0467e5611a76" }, + "stars": { + "Package": "stars", + "Version": "0.6-4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "abind", + "classInt", + "methods", + "parallel", + "rlang", + "sf", + "units" + ], + "Hash": "8b4284bf9fddfb481d516877a2045023" + }, "stringi": { "Package": "stringi", "Version": "1.7.12", @@ -1993,10 +2464,10 @@ }, "sys": { "Package": "sys", - "Version": "3.4.2", + "Version": "3.4.1", "Source": "Repository", "Repository": "RSPM", - "Hash": "3a1be13d68d47a8cd0bfd74739ca1555" + "Hash": "34c16f1ef796057bfa06d3f4ff818a5d" }, "systemfonts": { "Package": "systemfonts", @@ -2009,9 +2480,21 @@ ], "Hash": "90b28393209827327de889f49935140a" }, + "terra": { + "Package": "terra", + "Version": "1.7-18", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "Rcpp", + "methods" + ], + "Hash": "5db3d690ad42a1828d3bf9e063c98587" + }, "testthat": { "Package": "testthat", - "Version": "3.1.10", + "Version": "3.1.7", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2037,7 +2520,7 @@ "waldo", "withr" ], - "Hash": "6f403dc49295610a3a67ea1a9ca64346" + "Hash": "7eb5fd202a61d2fb78af5869b6c08998" }, "textshaping": { "Package": "textshaping", @@ -2053,7 +2536,7 @@ }, "tibble": { "Package": "tibble", - "Version": "3.2.1", + "Version": "3.2.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2068,7 +2551,7 @@ "utils", "vctrs" ], - "Hash": "a84e2cc86d07289b3b6f5069df7a004c" + "Hash": "37695ff125982007d42a59ad10982ff2" }, "tidyr": { "Package": "tidyr", @@ -2132,13 +2615,75 @@ }, "tinytex": { "Package": "tinytex", - "Version": "0.46", + "Version": "0.44", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "xfun" ], - "Hash": "0c41a73214d982f539c56a7773c7afa5" + "Hash": "c0f007e2eeed7722ce13d42b84a22e07" + }, + "tmap": { + "Package": "tmap", + "Version": "3.3-4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "RColorBrewer", + "abind", + "classInt", + "grid", + "htmltools", + "htmlwidgets", + "leafem", + "leaflet", + "leafsync", + "methods", + "rlang", + "sf", + "stars", + "stats", + "tmaptools", + "units", + "utils", + "viridisLite", + "widgetframe" + ], + "Hash": "c65363bc002492caf754352499ce2386" + }, + "tmaptools": { + "Package": "tmaptools", + "Version": "3.1-1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "RColorBrewer", + "XML", + "dichromat", + "grid", + "lwgeom", + "magrittr", + "methods", + "sf", + "stars", + "stats", + "units", + "viridisLite" + ], + "Hash": "dfcb77371df343b663d6668d2d63ac35" + }, + "units": { + "Package": "units", + "Version": "0.8-1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "Rcpp" + ], + "Hash": "81433967f9b34a120a4f5a5a016cd5ed" }, "urlchecker": { "Package": "urlchecker", @@ -2156,7 +2701,7 @@ }, "usethis": { "Package": "usethis", - "Version": "2.2.2", + "Version": "2.1.6", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2183,7 +2728,7 @@ "withr", "yaml" ], - "Hash": "60e51f0b94d0324dc19e44110098fa9f" + "Hash": "a67a22c201832b12c036cc059f1d137d" }, "utf8": { "Package": "utf8", @@ -2197,7 +2742,7 @@ }, "vctrs": { "Package": "vctrs", - "Version": "0.6.3", + "Version": "0.5.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2207,21 +2752,35 @@ "lifecycle", "rlang" ], - "Hash": "d0ef2856b83dc33ea6e255caf6229ee2" + "Hash": "e4ffa94ceed5f124d429a5a5f0f5b378" + }, + "viridis": { + "Package": "viridis", + "Version": "0.6.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "ggplot2", + "gridExtra", + "stats", + "viridisLite" + ], + "Hash": "ee96aee95a7a563e5496f8991e9fde4b" }, "viridisLite": { "Package": "viridisLite", - "Version": "0.4.2", + "Version": "0.4.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R" ], - "Hash": "c826c7c4241b6fc89ff55aaea3fa7491" + "Hash": "62f4b5da3e08d8e5bcba6cac15603f70" }, "waldo": { "Package": "waldo", - "Version": "0.5.1", + "Version": "0.4.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2234,7 +2793,7 @@ "rlang", "tibble" ], - "Hash": "2c993415154cdb94649d99ae138ff5e5" + "Hash": "035fba89d0c86e2113120f93301b98ad" }, "whisker": { "Package": "whisker", @@ -2243,6 +2802,22 @@ "Repository": "RSPM", "Hash": "c6abfa47a46d281a7d5159d0a8891e88" }, + "widgetframe": { + "Package": "widgetframe", + "Version": "0.3.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "htmltools", + "htmlwidgets", + "magrittr", + "purrr", + "tools", + "utils" + ], + "Hash": "0ee89e6cb58182d39b30a5b506e04808" + }, "withr": { "Package": "withr", "Version": "2.5.0", @@ -2256,27 +2831,37 @@ ], "Hash": "c0e49a9760983e81e55cdd9be92e7182" }, + "wk": { + "Package": "wk", + "Version": "0.7.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "141385279f2cd7faa6a3eccd8d1279dd" + }, "xfun": { "Package": "xfun", - "Version": "0.40", + "Version": "0.37", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "stats", "tools" ], - "Hash": "be07d23211245fc7d4209f54c4e4ffc8" + "Hash": "a6860e1400a8fd1ddb6d9b4230cc34ab" }, "xml2": { "Package": "xml2", - "Version": "1.3.5", + "Version": "1.3.3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "methods" ], - "Hash": "6c40e5cfcc6aefd88110666e18c31f40" + "Hash": "40682ed6a969ea5abfd351eb67833adc" }, "xopen": { "Package": "xopen", @@ -2310,14 +2895,14 @@ }, "zip": { "Package": "zip", - "Version": "2.3.0", + "Version": "2.2.2", "Source": "Repository", "Repository": "RSPM", - "Hash": "d98c94dacb7e0efcf83b0a133a705504" + "Hash": "c42bfcec3fa6a0cce17ce1f8bc684f88" }, "zoo": { "Package": "zoo", - "Version": "1.8-12", + "Version": "1.8-11", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2328,7 +2913,7 @@ "stats", "utils" ], - "Hash": "5c715954112b45499fb1dadc6ee6ee3e" + "Hash": "874a5b77fe0cfacf2a3450069ae70926" } } } diff --git a/renv/activate.R b/renv/activate.R index cb5401f9..a8fdc320 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,27 +2,11 @@ local({ # the requested version of renv - version <- "1.0.3" - attr(version, "sha") <- NULL + version <- "0.17.3" # the project directory project <- getwd() - # use start-up diagnostics if enabled - diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE") - if (diagnostics) { - start <- Sys.time() - profile <- tempfile("renv-startup-", fileext = ".Rprof") - utils::Rprof(profile) - on.exit({ - utils::Rprof(NULL) - elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L) - writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed))) - writeLines(sprintf("- Profile: %s", profile)) - print(utils::summaryRprof(profile)) - }, add = TRUE) - } - # figure out whether the autoloader is enabled enabled <- local({ @@ -76,75 +60,25 @@ local({ # load bootstrap tools `%||%` <- function(x, y) { - if (is.null(x)) y else x - } - - catf <- function(fmt, ..., appendLF = TRUE) { - - quiet <- getOption("renv.bootstrap.quiet", default = FALSE) - if (quiet) - return(invisible()) - - msg <- sprintf(fmt, ...) - cat(msg, file = stdout(), sep = if (appendLF) "\n" else "") - - invisible(msg) - - } - - header <- function(label, - ..., - prefix = "#", - suffix = "-", - n = min(getOption("width"), 78)) - { - label <- sprintf(label, ...) - n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L) - if (n <= 0) - return(paste(prefix, label)) - - tail <- paste(rep.int(suffix, n), collapse = "") - paste0(prefix, " ", label, " ", tail) - + if (is.environment(x) || length(x)) x else y } - startswith <- function(string, prefix) { - substring(string, 1, nchar(prefix)) == prefix + `%??%` <- function(x, y) { + if (is.null(x)) y else x } bootstrap <- function(version, library) { - friendly <- renv_bootstrap_version_friendly(version) - section <- header(sprintf("Bootstrapping renv %s", friendly)) - catf(section) - # attempt to download renv - catf("- Downloading renv ... ", appendLF = FALSE) - withCallingHandlers( - tarball <- renv_bootstrap_download(version), - error = function(err) { - catf("FAILED") - stop("failed to download:\n", conditionMessage(err)) - } - ) - catf("OK") - on.exit(unlink(tarball), add = TRUE) + tarball <- tryCatch(renv_bootstrap_download(version), error = identity) + if (inherits(tarball, "error")) + stop("failed to download renv ", version) # now attempt to install - catf("- Installing renv ... ", appendLF = FALSE) - withCallingHandlers( - status <- renv_bootstrap_install(version, tarball, library), - error = function(err) { - catf("FAILED") - stop("failed to install:\n", conditionMessage(err)) - } - ) - catf("OK") - - # add empty line to break up bootstrapping from normal output - catf("") + status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity) + if (inherits(status, "error")) + stop("failed to install renv ", version) - return(invisible()) } renv_bootstrap_tests_running <- function() { @@ -174,6 +108,13 @@ local({ if (!inherits(repos, "error") && length(repos)) return(repos) + # if we're testing, re-use the test repositories + if (renv_bootstrap_tests_running()) { + repos <- getOption("renv.tests.repos") + if (!is.null(repos)) + return(repos) + } + # retrieve current repos repos <- getOption("repos") @@ -217,34 +158,33 @@ local({ renv_bootstrap_download <- function(version) { - sha <- attr(version, "sha", exact = TRUE) - - methods <- if (!is.null(sha)) { - - # attempting to bootstrap a development version of renv - c( - function() renv_bootstrap_download_tarball(sha), - function() renv_bootstrap_download_github(sha) + # if the renv version number has 4 components, assume it must + # be retrieved via github + nv <- numeric_version(version) + components <- unclass(nv)[[1]] + + # if this appears to be a development version of 'renv', we'll + # try to restore from github + dev <- length(components) == 4L + + # begin collecting different methods for finding renv + methods <- c( + renv_bootstrap_download_tarball, + if (dev) + renv_bootstrap_download_github + else c( + renv_bootstrap_download_cran_latest, + renv_bootstrap_download_cran_archive ) - - } else { - - # attempting to bootstrap a release version of renv - c( - function() renv_bootstrap_download_tarball(version), - function() renv_bootstrap_download_cran_latest(version), - function() renv_bootstrap_download_cran_archive(version) - ) - - } + ) for (method in methods) { - path <- tryCatch(method(), error = identity) + path <- tryCatch(method(version), error = identity) if (is.character(path) && file.exists(path)) return(path) } - stop("All download methods failed") + stop("failed to download renv ", version) } @@ -308,6 +248,8 @@ local({ type <- spec$type repos <- spec$repos + message("* Downloading renv ", version, " ... ", appendLF = FALSE) + baseurl <- utils::contrib.url(repos = repos, type = type) ext <- if (identical(type, "source")) ".tar.gz" @@ -324,10 +266,13 @@ local({ condition = identity ) - if (inherits(status, "condition")) + if (inherits(status, "condition")) { + message("FAILED") return(FALSE) + } # report success and return + message("OK (downloaded ", type, ")") destfile } @@ -384,6 +329,8 @@ local({ urls <- file.path(repos, "src/contrib/Archive/renv", name) destfile <- file.path(tempdir(), name) + message("* Downloading renv ", version, " ... ", appendLF = FALSE) + for (url in urls) { status <- tryCatch( @@ -391,11 +338,14 @@ local({ condition = identity ) - if (identical(status, 0L)) + if (identical(status, 0L)) { + message("OK") return(destfile) + } } + message("FAILED") return(FALSE) } @@ -418,7 +368,7 @@ local({ if (!file.exists(tarball)) { # let the user know we weren't able to honour their request - fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." + fmt <- "* RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." msg <- sprintf(fmt, tarball) warning(msg) @@ -427,7 +377,10 @@ local({ } - catf("- Using local tarball '%s'.", tarball) + fmt <- "* Bootstrapping with tarball at path '%s'." + msg <- sprintf(fmt, tarball) + message(msg) + tarball } @@ -454,6 +407,8 @@ local({ on.exit(do.call(base::options, saved), add = TRUE) } + message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE) + url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) name <- sprintf("renv_%s.tar.gz", version) destfile <- file.path(tempdir(), name) @@ -463,105 +418,26 @@ local({ condition = identity ) - if (!identical(status, 0L)) + if (!identical(status, 0L)) { + message("FAILED") return(FALSE) - - renv_bootstrap_download_augment(destfile) - - return(destfile) - - } - - # Add Sha to DESCRIPTION. This is stop gap until #890, after which we - # can use renv::install() to fully capture metadata. - renv_bootstrap_download_augment <- function(destfile) { - sha <- renv_bootstrap_git_extract_sha1_tar(destfile) - if (is.null(sha)) { - return() } - # Untar - tempdir <- tempfile("renv-github-") - on.exit(unlink(tempdir, recursive = TRUE), add = TRUE) - untar(destfile, exdir = tempdir) - pkgdir <- dir(tempdir, full.names = TRUE)[[1]] - - # Modify description - desc_path <- file.path(pkgdir, "DESCRIPTION") - desc_lines <- readLines(desc_path) - remotes_fields <- c( - "RemoteType: github", - "RemoteHost: api.github.com", - "RemoteRepo: renv", - "RemoteUsername: rstudio", - "RemotePkgRef: rstudio/renv", - paste("RemoteRef: ", sha), - paste("RemoteSha: ", sha) - ) - writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path) - - # Re-tar - local({ - old <- setwd(tempdir) - on.exit(setwd(old), add = TRUE) - - tar(destfile, compression = "gzip") - }) - invisible() - } + message("OK") + return(destfile) - # Extract the commit hash from a git archive. Git archives include the SHA1 - # hash as the comment field of the tarball pax extended header - # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html) - # For GitHub archives this should be the first header after the default one - # (512 byte) header. - renv_bootstrap_git_extract_sha1_tar <- function(bundle) { - - # open the bundle for reading - # We use gzcon for everything because (from ?gzcon) - # > Reading from a connection which does not supply a 'gzip' magic - # > header is equivalent to reading from the original connection - conn <- gzcon(file(bundle, open = "rb", raw = TRUE)) - on.exit(close(conn)) - - # The default pax header is 512 bytes long and the first pax extended header - # with the comment should be 51 bytes long - # `52 comment=` (11 chars) + 40 byte SHA1 hash - len <- 0x200 + 0x33 - res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len]) - - if (grepl("^52 comment=", res)) { - sub("52 comment=", "", res) - } else { - NULL - } } renv_bootstrap_install <- function(version, tarball, library) { # attempt to install it into project library + message("* Installing renv ", version, " ... ", appendLF = FALSE) dir.create(library, showWarnings = FALSE, recursive = TRUE) - output <- renv_bootstrap_install_impl(library, tarball) - - # check for successful install - status <- attr(output, "status") - if (is.null(status) || identical(status, 0L)) - return(status) - - # an error occurred; report it - header <- "installation of renv failed" - lines <- paste(rep.int("=", nchar(header)), collapse = "") - text <- paste(c(header, lines, output), collapse = "\n") - stop(text) - - } - - renv_bootstrap_install_impl <- function(library, tarball) { # invoke using system2 so we can capture and report output bin <- R.home("bin") exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" - R <- file.path(bin, exe) + r <- file.path(bin, exe) args <- c( "--vanilla", "CMD", "INSTALL", "--no-multiarch", @@ -569,7 +445,19 @@ local({ shQuote(path.expand(tarball)) ) - system2(R, args, stdout = TRUE, stderr = TRUE) + output <- system2(r, args, stdout = TRUE, stderr = TRUE) + message("Done!") + + # check for successful install + status <- attr(output, "status") + if (is.numeric(status) && !identical(status, 0L)) { + header <- "Error installing renv:" + lines <- paste(rep.int("=", nchar(header)), collapse = "") + text <- c(header, lines, output) + writeLines(text, con = stderr()) + } + + status } @@ -779,60 +667,32 @@ local({ } - renv_bootstrap_validate_version <- function(version, description = NULL) { - - # resolve description file - # - # avoid passing lib.loc to `packageDescription()` below, since R will - # use the loaded version of the package by default anyhow. note that - # this function should only be called after 'renv' is loaded - # https://github.com/rstudio/renv/issues/1625 - description <- description %||% packageDescription("renv") + renv_bootstrap_validate_version <- function(version) { - # check whether requested version 'version' matches loaded version of renv - sha <- attr(version, "sha", exact = TRUE) - valid <- if (!is.null(sha)) - renv_bootstrap_validate_version_dev(sha, description) - else - renv_bootstrap_validate_version_release(version, description) - - if (valid) + loadedversion <- utils::packageDescription("renv", fields = "Version") + if (version == loadedversion) return(TRUE) - # the loaded version of renv doesn't match the requested version; - # give the user instructions on how to proceed - remote <- if (!is.null(description[["RemoteSha"]])) { - paste("rstudio/renv", description[["RemoteSha"]], sep = "@") - } else { - paste("renv", description[["Version"]], sep = "@") - } - - # display both loaded version + sha if available - friendly <- renv_bootstrap_version_friendly( - version = description[["Version"]], - sha = description[["RemoteSha"]] - ) + # assume four-component versions are from GitHub; + # three-component versions are from CRAN + components <- strsplit(loadedversion, "[.-]")[[1]] + remote <- if (length(components) == 4L) + paste("rstudio/renv", loadedversion, sep = "@") + else + paste("renv", loadedversion, sep = "@") fmt <- paste( "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", - "- Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", - "- Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", + "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", + "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", sep = "\n" ) - catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) - - FALSE - } + msg <- sprintf(fmt, loadedversion, version, remote) + warning(msg, call. = FALSE) - renv_bootstrap_validate_version_dev <- function(version, description) { - expected <- description[["RemoteSha"]] - is.character(expected) && startswith(expected, version) - } + FALSE - renv_bootstrap_validate_version_release <- function(version, description) { - expected <- description[["Version"]] - is.character(expected) && identical(expected, version) } renv_bootstrap_hash_text <- function(text) { @@ -858,7 +718,7 @@ local({ hooks <- getHook("renv::autoload") for (hook in hooks) if (is.function(hook)) - tryCatch(hook(), error = warnify) + tryCatch(hook(), error = warning) # load the project renv::load(project) @@ -999,40 +859,6 @@ local({ } - renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) { - sha <- sha %||% attr(version, "sha", exact = TRUE) - parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L))) - paste(parts, collapse = "") - } - - renv_bootstrap_exec <- function(project, libpath, version) { - if (!renv_bootstrap_load(project, libpath, version)) - renv_bootstrap_run(version, libpath) - } - - renv_bootstrap_run <- function(version, libpath) { - - # perform bootstrap - bootstrap(version, libpath) - - # exit early if we're just testing bootstrap - if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) - return(TRUE) - - # try again to load - if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { - return(renv::load(project = getwd())) - } - - # failed to download or load renv; warn the user - msg <- c( - "Failed to find an renv installation: the project will not be loaded.", - "Use `renv::activate()` to re-initialize the project." - ) - - warning(paste(msg, collapse = "\n"), call. = FALSE) - - } renv_json_read <- function(file = NULL, text = NULL) { @@ -1172,9 +998,35 @@ local({ # construct full libpath libpath <- file.path(root, prefix) - # run bootstrap code - renv_bootstrap_exec(project, libpath, version) + # attempt to load + if (renv_bootstrap_load(project, libpath, version)) + return(TRUE) + + # load failed; inform user we're about to bootstrap + prefix <- paste("# Bootstrapping renv", version) + postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "") + header <- paste(prefix, postfix) + message(header) + + # perform bootstrap + bootstrap(version, libpath) + + # exit early if we're just testing bootstrap + if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) + return(TRUE) + + # try again to load + if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { + message("* Successfully installed and loaded renv ", version, ".") + return(renv::load()) + } + + # failed to download or load renv; warn the user + msg <- c( + "Failed to find an renv installation: the project will not be loaded.", + "Use `renv::activate()` to re-initialize the project." + ) - invisible() + warning(paste(msg, collapse = "\n"), call. = FALSE) }) diff --git a/renv/settings.json b/renv/settings.json index 5d1b7408..d2f7e2b8 100644 --- a/renv/settings.json +++ b/renv/settings.json @@ -7,6 +7,7 @@ "eddy4R.erf", "eddy4R.stor", "eddy4R.qaqc", + "eddy4R.maps", "som", "Noble", "eddy4R.ucrt", @@ -19,8 +20,6 @@ "Depends", "LinkingTo" ], - "ppm.enabled": null, - "ppm.ignored.urls": [], "r.version": null, "snapshot.type": "implicit", "use.cache": true, diff --git a/utilities/flow.inst.dock.renv.R b/utilities/flow.inst.dock.renv.R index c5f7bc1e..0fe734a7 100644 --- a/utilities/flow.inst.dock.renv.R +++ b/utilities/flow.inst.dock.renv.R @@ -101,10 +101,11 @@ renv::consent(provided=TRUE) # 4.2 specify base directory for repo clone NameDirRepo and for packages NameDirRepo <- "/home/eddy/eddy4R" +#NameDirRepo <- "/home/ddurden/eddy/code/eddy4R_ddurden" #Dealing with bioconductor install.packages("BiocManager") -BiocManager::install(version = "3.12") +BiocManager::install(version = "3.16") renv::install("bioc::EBImage") #Restore dependencies using renv @@ -112,7 +113,7 @@ renv::restore(lockfile=paste0(NameDirRepo,"/renv.lock")) #base::library(devtools) -NameDirPack <- c( "pack/eddy4R.base", "pack/eddy4R.turb", "pack/eddy4R.stor", "pack/eddy4R.qaqc","pack/Waves") +NameDirPack <- c( "pack/eddy4R.base", "pack/eddy4R.turb", "pack/eddy4R.stor", "pack/eddy4R.qaqc","pack/eddy4R.maps","pack/Waves") Dir <- paste(NameDirRepo, NameDirPack, sep = "/") # 4.3 actual installation @@ -149,3 +150,4 @@ renv::install(packages = "REddyProc@1.2"#, # repos=c("https://cran.rstudio.com/", # for dependencies on CRAN packages # "http://R-Forge.R-project.org") # for REddyProc on R-Forge ) +#library(stars) diff --git a/utilities/flow.pack.R b/utilities/flow.pack.R index 22eb317b..637240c2 100644 --- a/utilities/flow.pack.R +++ b/utilities/flow.pack.R @@ -58,8 +58,9 @@ namePack <- c("eddy4R.base", "eddy4R.turb", "eddy4R.qaqc", "eddy4R.stor", + "eddy4R.maps", "Waves" - )[1:5] + )[1:6] diff --git a/utilities/flow.renv.init.rstr.R b/utilities/flow.renv.init.rstr.R index 4adae2b8..fb3b7ff3 100644 --- a/utilities/flow.renv.init.rstr.R +++ b/utilities/flow.renv.init.rstr.R @@ -34,7 +34,7 @@ # ------ Choose options -------- #Be sure to set repos to pull packages from (example from last release): -options(repos = c( CRANNew = "https://packagemanager.rstudio.com/cran/2023-09-22", GCPFIX = "https://packagemanager.rstudio.com/cran/2023-04-17", FIX = "https://packagemanager.rstudio.com/cran/2022-11-30", CRAN = "https://packagemanager.rstudio.com/cran/2022-02-28")) +options(repos = c( CRANNew = "https://packagemanager.rstudio.com/cran/2023-10-22", GCPFIX = "https://packagemanager.rstudio.com/cran/2023-04-17", FIX = "https://packagemanager.rstudio.com/cran/2022-11-30", CRAN = "https://packagemanager.rstudio.com/cran/2022-02-28")) @@ -42,7 +42,7 @@ options(repos = c( CRANNew = "https://packagemanager.rstudio.com/cran/2023-09-22 #dirWork <- '~/NEON-IS-data-processing/pack/NEONprocIS.wq' #dirWork <- '~/R/NEON-IS-data-processing-homeDir/pack/NEONprocIS.base' dirWork <- "/home/ddurden/eddy/code/eddy4R_ddurden" -PackIgnr <- c("eddy4R.base", "eddy4R.turb", "eddy4R.erf", "eddy4R.stor", "eddy4R.qaqc","som","Noble", "eddy4R.ucrt", "Waves", "accs", "NEONprocIS.base") # These should already be in the respective docker containers +PackIgnr <- c("eddy4R.base", "eddy4R.turb", "eddy4R.erf", "eddy4R.stor", "eddy4R.qaqc","eddy4R.maps","som","Noble", "eddy4R.ucrt", "Waves", "accs", "NEONprocIS.base") # These should already be in the respective docker containers # Keep and use the local project that renv creates when creating/updating the lockfile # in dirWork? If TRUE, note .Rprofile and .Rproj files will be created/retained in dirWork,