# 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) }) }