SmartCane/80_calculate_kpis.sh
Timon 458b8247be Cleanup: Fix CI formula, reorganize shell scripts and test files
- Fixed CI calculation: changed from NDVI (NIR-Red)/(NIR+Red) to correct NIR/Green-1 formula in:
  * process_single_tile() function
  * create_ci_band() utility function
  * Updated create_mask_and_crop() documentation

- Renamed numbered shell scripts for clarity (matching R script numbering):
  * 01_run_planet_download -> 10_planet_download.sh
  * 02_run_ci_extraction -> 20_ci_extraction.sh
  * 03_run_growth_model -> 30_growth_model.sh
  * 04_run_mosaic_creation -> 40_mosaic_creation.sh
  * 09_run_calculate_kpis -> 80_calculate_kpis.sh
  * 10_run_kpi_report -> 90_kpi_report.sh

- Archived obsolete shell scripts to old_sh/:
  * build_mosaic.sh, build_report.sh, interpolate_growth_model.sh
  * 05_run_dashboard_report.sh, 06_run_crop_messaging.sh
  * 11_run_yield_prediction.sh/ps1
  * runcane.sh, runpython.sh, smartcane.sh, update_RDS.sh

- Deleted test/debug files and temporary outputs:
  * analyze_*.R, benchmark_gpu_vs_cpu.py, convert_angata_harvest.py
  * debug_mosaic.R, examine_kpi_results.R, generate_sar_report.R
  * inspect_8band_structure.R, inspect_tif_bands.R
  * old_working_utils.R, predict_harvest_operational.R
  * run_kpi_calculation.R, run_report.R, simple_sar_test.R
  * data_validation_tool/, harvest_ci_pattern_analysis.png, kpi_debug.out

- Enhanced harvest prediction: Added threshold tuning (0.40-0.45) and field type handling

- Enhanced mosaic creation: Improved tile detection and routing logic
2026-01-14 16:58:51 +01:00

216 lines
6.1 KiB
Bash

#!/bin/bash
# 09_RUN_CALCULATE_KPIS.SH
# ======================
# Shell script wrapper for KPI calculation in the SmartCane pipeline
# This script integrates KPI calculation into the existing pipeline sequence (01-05)
# and ensures proper R execution with renv environment and error handling.
# Script configuration
SCRIPT_NAME="80_calculate_kpis.sh"
R_SCRIPT_NAME="80_calculate_kpis.R"
LOG_PREFIX="[KPI_CALC]"
project_dir="tz11_mbigiri_john_trial"
offset=7
end_date=$(date +"%Y-%m-%d")
# Function to log messages with timestamp
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') $LOG_PREFIX $1"
}
# Function to handle errors
handle_error() {
log_message "ERROR: $1"
exit 1
}
# Function to check if file exists
check_file() {
if [ ! -f "$1" ]; then
handle_error "Required file not found: $1"
fi
}
# Function to check if directory exists
check_directory() {
if [ ! -d "$1" ]; then
log_message "WARNING: Directory not found: $1"
return 1
fi
return 0
}
# Main execution function
main() {
R_CMD ="Rscript"
log_message "Starting KPI calculation pipeline step"
# Check if we're in the correct directory
if [ ! -f "../r_app/$R_SCRIPT_NAME" ]; then
handle_error "Must be run from lavevel_app directory (where ../r_app/ folder exists)"
fi
log_message "Using R at: $R_CMD"
log_message "Using project directory: $project_dir"
# Check if project directory exists
project_path="../laravel_app/storage/app/$project_dir"
check_directory "$project_path" || handle_error "Project directory not found: $project_path"
# Check for required data files
check_file "$project_path/Data/pivot.geojson"
# Check for weekly mosaic directory
mosaic_dir="$project_path/weekly_mosaic"
check_directory "$mosaic_dir" || handle_error "Weekly mosaic directory not found: $mosaic_dir"
# Count available mosaics
mosaic_count=$(find "$mosaic_dir" -name "week_*.tif" 2>/dev/null | wc -l)
if [ "$mosaic_count" -lt 1 ]; then
handle_error "No weekly mosaics found in $mosaic_dir"
fi
log_message "Found $mosaic_count weekly mosaics in $mosaic_dir"
# Create temporary R script with project configuration
temp_r_script="temp_kpi_calc_$$.R"
cat > "../r_app/$temp_r_script" << EOF
# Temporary KPI calculation script
# Generated by $SCRIPT_NAME on $(date)
# Set project directory
# project_dir <- "$PROJECT_DIR"
# Set working directory to r_app
#setwd("r_app")
# Source the main KPI calculation script
tryCatch({
source("$R_SCRIPT_NAME")
cat("✓ KPI calculation completed successfully!!n")
}, error = function(e) {
cat("✗ Error in KPI calculation:", e\$message, "\\n")
quit(status = 1)
})
EOF
log_message "Created temporary R script: r_app/$temp_r_script"
# Execute R script
log_message "Starting R execution..."
# Change to smartcane root directory for proper relative paths
cd "$(dirname "$0")" || handle_error "Failed to change to script directory"
# Run R script with proper error handling
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
# Windows execution
"$R_CMD" --vanilla < "r_app/$TEMP_R_SCRIPT"
R_EXIT_CODE=$?
else
# Unix/Linux execution
cd r_app
log_message "calling $R_CMD $temp_r_script "
Rscript "$temp_r_script" "$end_date" "$offset" "$project_dir"
R_EXIT_CODE=$?
fi
# Clean up temporary script
rm -f "../r_app/$temp_r_script"
log_message "Cleaned up temporary R script"
# Check R execution result
if [ $R_EXIT_CODE -eq 0 ]; then
log_message "✓ KPI calculation completed successfully"
# Check if output files were created
REPORTS_DIR="../laravel_app/storage/app/$project_dir/reports"
if check_directory "$REPORTS_DIR/kpis"; then
KPI_FILES=$(find "$REPORTS_DIR/kpis" -name "*$(date '+%Y%m%d')*" 2>/dev/null | wc -l)
if [ "$KPI_FILES" -gt 0 ]; then
log_message "✓ Generated $KPI_FILES KPI output files"
else
log_message "⚠ Warning: No KPI files found for today's date"
fi
fi
log_message "KPI calculation pipeline step completed successfully"
return 0
else
handle_error "R script execution failed with exit code: $R_EXIT_CODE"
fi
}
# Script usage information
usage() {
echo "Usage: $0 --project_dir=[PROJECT_DIR] --offset=[number] --end-date=[date]"
echo ""
echo "Calculate KPI metrics for SmartCane monitoring system"
echo ""
echo "Parameters:"
echo " --project_dir Project directory name (default: esa)"
echo " Must exist in laravel_app/storage/app/"
echo ""
echo " --offset (default: 7)"
echo ""
echo " --end-date (default: $(date +%Y-%m-%d))"
echo ""
echo "Examples:"
echo " $0 # Use default 'esa' project"
echo " $0 --project_dir=aura --offset=7 # Use 'aura' project with offset 7"
echo ""
echo "Requirements:"
echo " - R installation (4.4.3 or compatible)"
echo " - renv environment set up"
echo " - Weekly mosaic files in PROJECT_DIR/weekly_mosaic/"
echo " - Field boundaries in PROJECT_DIR/Data/pivot.geojson"
}
## Parse command line arguments
for arg in "$@"; do
case $arg in
-h|--help)
usage
exit 0
;;
--offset=*)
offset="${arg#*=}"
;;
--end_date=*)
end_date="${arg#*=}"
;;
--project_dir=*)
project_dir="${arg#*=}"
;;
*)
echo "Unknown option: $arg"
exit 1
;;
esac
shift
done
# ----------------------------------------------------------------
# Validate required arguments bit dumb because all have defaults;
# ----------------------------------------------------------------
if [[ -z "$project_dir" || -z "$offset" || -z "$end_date" ]]; then
echo "❌ Missing required arguments." >&2
usage
exit 1
fi
# -------------------------------------
# Run main
# -------------------------------------
main