SmartCane/kpi_debug.out
Timon d5fd4bb463 Add KPI reporting system and deployment documentation
Major Changes:
- NEW: Scripts 09 & 10 for KPI calculation and enhanced reporting
- NEW: Shell script wrappers (01-10) for easier execution
- NEW: R packages flextable and officer for enhanced Word reports
- NEW: DEPLOYMENT_README.md with complete deployment guide
- RENAMED: Numbered R scripts (02, 03, 04) for clarity
- REMOVED: Old package management scripts (using renv only)
- UPDATED: Workflow now uses scripts 09->10 instead of 05

Files Changed: 90+ files
New Packages: flextable, officer
New Scripts: 09_run_calculate_kpis.sh, 10_run_kpi_report.sh
Documentation: DEPLOYMENT_README.md, EMAIL_TO_ADMIN.txt

See DEPLOYMENT_README.md for full deployment instructions.
2025-10-14 11:49:30 +02:00

315 lines
9.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

R version 4.4.3 (2025-02-28 ucrt) -- "Trophy Case"
Copyright (C) 2025 The R Foundation for Statistical Computing
Platform: x86_64-w64-mingw32/x64
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.
Natural language support but running in an English locale
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.
- Project 'C:/Users/timon/Resilience BV/4020 SCane ESA DEMO - Documenten/General/4020 SCDEMO Team/4020 TechnicalData/WP3/smartcane_v2/smartcane' loaded. [renv 1.1.4]
> # 09_CALCULATE_KPIS.R
> # ===================
> # This script calculates 6 Key Performance Indicators (KPIs) for sugarcane monitoring:
> # 1. Field Uniformity Summary
> # 2. Farm-wide Area Change Summary
> # 3. TCH Forecasted
> # 4. Growth Decline Index
> # 5. Weed Presence Score
> # 6. Gap Filling Score (placeholder)
> #
> # Usage: Rscript 09_calculate_kpis.R [end_date] [offset] [project_dir]
> # - end_date: End date for KPI calculation (YYYY-MM-DD format), default: today
> # - offset: Number of days to look back (not currently used for KPIs, but for consistency)
> # - project_dir: Project directory name (e.g., "aura", "esa")
>
> # 1. Load required libraries
> # -------------------------
> suppressPackageStartupMessages({
+ library(here)
+ library(sf)
+ library(terra)
+ library(dplyr)
+ library(tidyr)
+ library(lubridate)
+ library(readr)
+ library(caret)
+ library(CAST)
+ library(randomForest)
+ })
>
> # 2. Main function
> # --------------
> main <- function() {
+ # Process command line arguments
+ args <- commandArgs(trailingOnly = TRUE)
+
+ # Process end_date argument
+ if (length(args) >= 1 && !is.na(args[1])) {
+ end_date <- as.Date(args[1])
+ if (is.na(end_date)) {
+ warning("Invalid end_date provided. Using default (current date).")
+ end_date <- Sys.Date()
+ }
+ } else {
+ end_date <- Sys.Date()
+ }
+
+ # Process offset argument (for consistency with other scripts, not currently used)
+ if (length(args) >= 2 && !is.na(args[2])) {
+ offset <- as.numeric(args[2])
+ if (is.na(offset) || offset <= 0) {
+ warning("Invalid offset provided. Using default (7 days).")
+ offset <- 7
+ }
+ } else {
+ offset <- 7
+ }
+
+ # Process project_dir argument
+ if (length(args) >= 3 && !is.na(args[3])) {
+ project_dir <- as.character(args[3])
+ } else {
+ project_dir <- "esa" # Default project
+ }
+
+ # Make project_dir available globally so parameters_project.R can use it
+ assign("project_dir", project_dir, envir = .GlobalEnv)
+
+ # 3. Load utility functions and project configuration
+ # --------------------------------------------------
+
+ tryCatch({
+ source(here("r_app", "crop_messaging_utils.R"))
+ }, error = function(e) {
+ stop("Error loading crop_messaging_utils.R: ", e$message)
+ })
+
+ tryCatch({
+ source(here("r_app", "kpi_utils.R"))
+ }, error = function(e) {
+ stop("Error loading kpi_utils.R: ", e$message)
+ })
+
+ # Load project parameters (this sets up all directory paths and field boundaries)
+ tryCatch({
+ source(here("r_app", "parameters_project.R"))
+ }, error = function(e) {
+ stop("Error loading parameters_project.R: ", e$message)
+ })
+
+ # Load growth model utils if available (for yield prediction)
+ tryCatch({
+ source(here("r_app", "growth_model_utils.R"))
+ }, error = function(e) {
+ warning("growth_model_utils.R not found, yield prediction KPI will use placeholder data")
+ })
+
+ # Check if required variables exist
+ if (!exists("project_dir")) {
+ stop("project_dir must be set before running this script")
+ }
+
+ if (!exists("field_boundaries_sf") || is.null(field_boundaries_sf)) {
+ stop("Field boundaries not loaded. Check parameters_project.R initialization.")
+ }
+
+ # 4. Calculate all KPIs
+ # -------------------
+ output_dir <- file.path(reports_dir, "kpis")
+
+ kpi_results <- calculate_all_kpis(
+ report_date = end_date,
+ output_dir = output_dir,
+ field_boundaries_sf = field_boundaries_sf,
+ harvesting_data = harvesting_data,
+ cumulative_CI_vals_dir = cumulative_CI_vals_dir,
+ weekly_CI_mosaic = weekly_CI_mosaic,
+ reports_dir = reports_dir,
+ project_dir = project_dir
+ )
+
+ # 5. Print summary
+ # --------------
+ cat("\n=== KPI CALCULATION SUMMARY ===\n")
+ cat("Report Date:", as.character(kpi_results$metadata$report_date), "\n")
+ cat("Current Week:", kpi_results$metadata$current_week, "\n")
+ cat("Previous Week:", kpi_results$metadata$previous_week, "\n")
+ cat("Total Fields Analyzed:", kpi_results$metadata$total_fields, "\n")
+ cat("Calculation Time:", as.character(kpi_results$metadata$calculation_time), "\n")
+
+ cat("\nField Uniformity Summary:\n")
+ print(kpi_results$field_uniformity_summary)
+
+ cat("\nArea Change Summary:\n")
+ print(kpi_results$area_change)
+
+ cat("\nTCH Forecasted:\n")
+ print(kpi_results$tch_forecasted)
+
+ cat("\nGrowth Decline Index:\n")
+ print(kpi_results$growth_decline)
+
+ cat("\nWeed Presence Score:\n")
+ print(kpi_results$weed_presence)
+
+ cat("\nGap Filling Score:\n")
+ print(kpi_results$gap_filling)
+
+ cat("\n=== KPI CALCULATION COMPLETED ===\n")
+ }
>
> # 6. Script execution
> # -----------------
> if (sys.nframe() == 0) {
+ main()
+ }
[INFO] 2025-10-08 15:39:29 - Initializing project with directory: esa
[1] "model using cumulative_CI,DOY will be trained now..."
note: only 1 unique complexity parameters in default grid. Truncating the grid to 1 .
+ Fold1: mtry=2
- Fold1: mtry=2
+ Fold2: mtry=2
- Fold2: mtry=2
+ Fold3: mtry=2
- Fold3: mtry=2
+ Fold4: mtry=2
- Fold4: mtry=2
+ Fold5: mtry=2
- Fold5: mtry=2
Aggregating results
Fitting final model on full training set
[1] "maximum number of models that still need to be trained: 3"
[1] "model using cumulative_CI,CI_per_day will be trained now..."
note: only 1 unique complexity parameters in default grid. Truncating the grid to 1 .
+ Fold1: mtry=2
- Fold1: mtry=2
+ Fold2: mtry=2
- Fold2: mtry=2
+ Fold3: mtry=2
- Fold3: mtry=2
+ Fold4: mtry=2
- Fold4: mtry=2
+ Fold5: mtry=2
- Fold5: mtry=2
Aggregating results
Fitting final model on full training set
[1] "maximum number of models that still need to be trained: 2"
[1] "model using DOY,CI_per_day will be trained now..."
note: only 1 unique complexity parameters in default grid. Truncating the grid to 1 .
+ Fold1: mtry=2
- Fold1: mtry=2
+ Fold2: mtry=2
- Fold2: mtry=2
+ Fold3: mtry=2
- Fold3: mtry=2
+ Fold4: mtry=2
- Fold4: mtry=2
+ Fold5: mtry=2
- Fold5: mtry=2
Aggregating results
Fitting final model on full training set
[1] "maximum number of models that still need to be trained: 1"
[1] "vars selected: cumulative_CI,DOY with RMSE 24.808"
[1] "model using additional variable CI_per_day will be trained now..."
note: only 2 unique complexity parameters in default grid. Truncating the grid to 2 .
+ Fold1: mtry=2
- Fold1: mtry=2
+ Fold1: mtry=3
- Fold1: mtry=3
+ Fold2: mtry=2
- Fold2: mtry=2
+ Fold2: mtry=3
- Fold2: mtry=3
+ Fold3: mtry=2
- Fold3: mtry=2
+ Fold3: mtry=3
- Fold3: mtry=3
+ Fold4: mtry=2
- Fold4: mtry=2
+ Fold4: mtry=3
- Fold4: mtry=3
+ Fold5: mtry=2
- Fold5: mtry=2
+ Fold5: mtry=3
- Fold5: mtry=3
Aggregating results
Selecting tuning parameters
Fitting mtry = 3 on full training set
[1] "maximum number of models that still need to be trained: 0"
[1] "vars selected: cumulative_CI,DOY with RMSE 24.808"
field_groups count value
75% Top 25% 3 96.2
50% Average 7 93.0
25% Lowest 25% 2 84.0
Total area forecasted 12 219.0
=== KPI CALCULATION SUMMARY ===
Report Date: 2025-10-08
Current Week: 40
Previous Week: 39
Total Fields Analyzed: 12
Calculation Time: 2025-10-08 15:39:34.583434
Field Uniformity Summary:
uniformity_level count percent
1 Excellent 0 0
2 Good 0 0
3 Moderate 0 0
4 Poor 0 0
Area Change Summary:
change_type hectares percent
1 Improving areas 0 0
2 Stable areas 0 0
3 Declining areas 0 0
4 Total area 0 100
TCH Forecasted:
field_groups count value
75% Top 25% 3 96.2
50% Average 7 93.0
25% Lowest 25% 2 84.0
Total area forecasted 12 219.0
Growth Decline Index:
risk_level count percent
1 High 0 0
2 Low 0 0
3 Moderate 0 0
4 Very-high 0 0
Weed Presence Score:
weed_risk_level field_count percent
1 Canopy closed - Low weed risk 4 33.3
2 High 0 0.0
3 Low 0 0.0
4 Moderate 0 0.0
Gap Filling Score:
# A tibble: 1 × 3
gap_level field_count percent
<chr> <int> <dbl>
1 <NA> 12 100
=== KPI CALCULATION COMPLETED ===
There were 50 or more warnings (use warnings() to see the first 50)
>
> proc.time()
user system elapsed
11.93 0.93 13.45