- 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
216 lines
6.1 KiB
Bash
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 |