174 lines
5.4 KiB
R
174 lines
5.4 KiB
R
# 40_MOSAIC_CREATION_PER_FIELD.R
|
|
# ===============================
|
|
# Per-Field Weekly Mosaic Creation
|
|
#
|
|
# Creates weekly mosaics FROM per-field daily CI TIFFs (output from Script 20)
|
|
# TO per-field weekly CI TIFFs (input for Scripts 90/91 reporting).
|
|
#
|
|
# ARCHITECTURE:
|
|
# Input: field_tiles_CI/{FIELD}/{DATE}.tif (5-band daily, per-field from Script 20)
|
|
# Output: weekly_mosaic/{FIELD}/week_WW_YYYY.tif (5-band weekly, per-field)
|
|
#
|
|
# USAGE:
|
|
# & "C:\Program Files\R\R-4.4.3\bin\x64\Rscript.exe" r_app/40_mosaic_creation_per_field.R [end_date] [offset] [project_dir]
|
|
#
|
|
# ARGUMENTS:
|
|
# end_date: End date for processing (YYYY-MM-DD format, default: today)
|
|
# offset: Days to look back from end_date (typically 7 for one week, default: 7)
|
|
# project_dir: Project directory (e.g., "aura", "angata", "chemba", "esa", default: "angata")
|
|
#
|
|
# EXAMPLES:
|
|
# & "C:\Program Files\R\R-4.4.3\bin\x64\Rscript.exe" r_app/40_mosaic_creation_per_field.R 2026-01-12 7 aura
|
|
# & "C:\Program Files\R\R-4.4.3\bin\x64\Rscript.exe" r_app/40_mosaic_creation_per_field.R 2025-12-31 7 angata
|
|
|
|
# 1. Load required packages
|
|
# -----------------------
|
|
suppressPackageStartupMessages({
|
|
library(sf)
|
|
library(terra)
|
|
library(tidyverse)
|
|
library(lubridate)
|
|
library(here)
|
|
})
|
|
|
|
# 2. Main execution function
|
|
# -------------------------
|
|
main <- function() {
|
|
|
|
cat("\n")
|
|
cat("========================================================\n")
|
|
cat(" Script 40: Per-Field Weekly Mosaic Creation\n")
|
|
cat("========================================================\n\n")
|
|
|
|
# Capture command line arguments
|
|
args <- commandArgs(trailingOnly = TRUE)
|
|
|
|
# ==== Process Arguments ====
|
|
|
|
# Project directory
|
|
if (length(args) >= 3 && !is.na(args[3])) {
|
|
project_dir <- as.character(args[3])
|
|
} else if (exists("project_dir", envir = .GlobalEnv)) {
|
|
project_dir <- get("project_dir", envir = .GlobalEnv)
|
|
} else {
|
|
project_dir <- "angata"
|
|
message("[INFO] No project_dir provided. Using default: angata")
|
|
}
|
|
|
|
assign("project_dir", project_dir, envir = .GlobalEnv)
|
|
message(paste("[INFO] Project:", project_dir))
|
|
|
|
# End date
|
|
if (length(args) >= 1 && !is.na(args[1])) {
|
|
end_date <- as.Date(args[1], format = "%Y-%m-%d")
|
|
if (is.na(end_date)) {
|
|
message("[WARNING] Invalid end_date. Using current date.")
|
|
end_date <- Sys.Date()
|
|
}
|
|
} else {
|
|
end_date <- Sys.Date()
|
|
message(paste("[INFO] No end_date provided. Using current date:", format(end_date)))
|
|
}
|
|
|
|
# Offset (days back)
|
|
if (length(args) >= 2 && !is.na(args[2])) {
|
|
offset <- as.numeric(args[2])
|
|
if (is.na(offset) || offset <= 0) {
|
|
message("[WARNING] Invalid offset. Using default: 7 days")
|
|
offset <- 7
|
|
}
|
|
} else {
|
|
offset <- 7
|
|
message("[INFO] No offset provided. Using default: 7 days")
|
|
}
|
|
|
|
# ==== Load Configuration ====
|
|
|
|
# Set working directory if needed
|
|
if (basename(getwd()) == "r_app") {
|
|
setwd("..")
|
|
}
|
|
|
|
tryCatch({
|
|
source("r_app/parameters_project.R")
|
|
message("[INFO] ✓ Loaded parameters_project.R")
|
|
}, error = function(e) {
|
|
stop("[ERROR] Failed to load parameters_project.R: ", e$message)
|
|
})
|
|
|
|
tryCatch({
|
|
source("r_app/40_mosaic_creation_per_field_utils.R")
|
|
message("[INFO] ✓ Loaded 40_mosaic_creation_per_field_utils.R")
|
|
}, error = function(e) {
|
|
stop("[ERROR] Failed to load utilities: ", e$message)
|
|
})
|
|
|
|
# ==== Get Project Directories ====
|
|
|
|
setup <- setup_project_directories(project_dir)
|
|
|
|
# Determine input/output directories
|
|
# Input: field_tiles_CI/ (from Script 20)
|
|
field_tiles_ci_dir <- setup$field_tiles_ci_dir
|
|
|
|
# Output: weekly_mosaic/ (for Scripts 90/91)
|
|
weekly_mosaic_output_dir <- file.path(setup$laravel_storage_dir, "weekly_mosaic")
|
|
|
|
message(paste("[INFO] Input directory:", field_tiles_ci_dir))
|
|
message(paste("[INFO] Output directory:", weekly_mosaic_output_dir))
|
|
|
|
# ==== Validate Input Directory ====
|
|
|
|
if (!dir.exists(field_tiles_ci_dir)) {
|
|
stop(paste("[ERROR] Input directory not found:", field_tiles_ci_dir,
|
|
"\nScript 20 (CI extraction) must be run first to create per-field TIFFs."))
|
|
}
|
|
|
|
# Check if directory has any TIFFs
|
|
field_dirs <- list.dirs(field_tiles_ci_dir, full.names = FALSE, recursive = FALSE)
|
|
if (length(field_dirs) == 0) {
|
|
stop(paste("[ERROR] No field subdirectories found in:", field_tiles_ci_dir))
|
|
}
|
|
|
|
message(paste("[INFO] Found", length(field_dirs), "field directories"))
|
|
|
|
# ==== Generate Date Range ====
|
|
|
|
dates <- date_list(end_date, offset)
|
|
|
|
# ==== Create Per-Field Weekly Mosaics ====
|
|
|
|
created_files <- create_all_field_weekly_mosaics(
|
|
dates = dates,
|
|
field_tiles_ci_dir = field_tiles_ci_dir,
|
|
output_dir = weekly_mosaic_output_dir
|
|
)
|
|
|
|
# ==== Summary ====
|
|
|
|
message("\n")
|
|
message("========================================================")
|
|
message(paste(" COMPLETED"))
|
|
message(paste(" Created:", length(created_files), "weekly field mosaics"))
|
|
message("========================================================\n")
|
|
|
|
if (length(created_files) > 0) {
|
|
message("[SUCCESS] Weekly mosaics ready for reporting (Scripts 90/91)")
|
|
} else {
|
|
message("[WARNING] No mosaics created - check input data")
|
|
}
|
|
|
|
return(invisible(created_files))
|
|
}
|
|
|
|
# Execute main if script is run directly
|
|
if (sys.nframe() == 0) {
|
|
tryCatch({
|
|
created <- main()
|
|
quit(save = "no", status = 0)
|
|
}, error = function(e) {
|
|
message(paste("\n[FATAL ERROR]", e$message))
|
|
quit(save = "no", status = 1)
|
|
})
|
|
}
|