Repository: CIROH-UA/NGIAB-CloudInfra
Pull request #294: Updated scripts for better visuals and error handling
Author: login: arpita0911patel
Created: 2025-05-14T15:13:40Z | Merged: 2025-05-14T17:48:43Z



Diff:
diff --git a/guide.sh b/guide.sh
index db9d46a..28ed162 100755
--- a/guide.sh
+++ b/guide.sh
@@ -1,6 +1,11 @@
 #!/bin/bash
 
-# Color definitions
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB)
+# Version: 1.4.3
+# ======================================================================
+
+# Color definitions with enhanced palette
 BBlack='\033[1;30m'
 BRed='\033[1;31m'
 BGreen='\033[1;32m'
@@ -19,63 +24,246 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
 set -e
 
 CONFIG_FILE="$HOME/.host_data_path.conf"
 TETHYS_SCRIPT="./viewOnTethys.sh"
+TEEHR_SCRIPT="./runTeehr.sh"
+
+# Container and image constants
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_IMAGE_NAME="awiciroh/tethys-ngiab"
+TEEHR_IMAGE_NAME="awiciroh/ngiab-teehr"
+NGEN_IMAGE_NAME="awiciroh/ciroh-ngen-image"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB)\033[38;5;39m                                                         ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mAdvanced Hydrologic Modeling Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${ARROW} \033[1;38;5;39mVisit our website: \033[4;38;5;87mhttps://ngiab.ciroh.org\033[0m"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Cleanup function for all resources
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Stop any running TEEHR containers
+    local teehr_containers=$(docker ps -q --filter "ancestor=$TEEHR_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$teehr_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $teehr_containers >/dev/null 2>&1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+    fi
+    
+    # Remove the Docker network
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1
+    fi
+    
+    # Check for other containers using our images and stop them
+    local ngen_containers=$(docker ps -q --filter "ancestor=$NGEN_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$ngen_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping NGEN containers..."
+        docker stop $ngen_containers >/dev/null 2>&1
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed.${Color_Off}"
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Set up trap for Ctrl-C and regular exit
+trap handle_sigint SIGINT
+trap clean_up_resources EXIT
+
+print_welcome_banner
+
+# Input data section with improved descriptions
+print_section_header "MODEL INPUT REQUIREMENTS"
 
-echo -e "\n========================================================="
-echo -e "${UWhite} Welcome to CIROH-UA:NextGen National Water Model App! ${Color_Off}"
-echo -e "=========================================================\n"
-echo -e "Looking for input data (a directory containing the following directories: forcings, config and outputs):\n"
-echo -e "${BBlue}forcings${Color_Off} is the hydrofabric input data for your model(s)."
-echo -e "${BGreen}config${Color_Off} folder has all the configuration related files for the model."
-echo -e "${BPurple}outputs${Color_Off} is where the output files are copied to when the model finish the run"
+echo -e "This application requires the following directory structure for proper operation:\n"
+echo -e "  ${ARROW} \033[38;5;33mforcings/\033[0m - Contains hydrofabric input data for model simulations"
+echo -e "          \033[38;5;117m└─ Meteorological and terrain data for hydrologic calculations\033[0m"
+echo -e "\n  ${ARROW} \033[38;5;35mconfig/\033[0m - Contains all configuration settings for the model"
+echo -e "          \033[38;5;117m└─ Model parameters, simulation period, and execution settings\033[0m"
+echo -e "\n  ${ARROW} \033[38;5;205moutputs/\033[0m - Target directory for simulation results"
+echo -e "          \033[38;5;117m└─ Flow estimates, water levels, and diagnostic information\033[0m"
 
-echo -e "\n"
+echo -e "\n${INFO_MARK} ${BWhite}Please specify a directory containing these components below.${Color_Off}\n"
 
-# Check if the config file exists and read from it
+# Path selection with improved user experience and fixed formatting
 if [ -f "$CONFIG_FILE" ]; then
     LAST_PATH=$(cat "$CONFIG_FILE")
-    echo -e "Last used data directory path: ${BBlue}$LAST_PATH${Color_Off}"
-    read -erp "Do you want to use the same path? (Y/n): " use_last_path
+    echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+    echo -ne "  ${ARROW} Use the same path? [Y/n]: "
+    read -e use_last_path
     if [[ "$use_last_path" != [Nn]* ]]; then
         HOST_DATA_PATH=$LAST_PATH
+        echo -e "  ${CHECK_MARK} Using previously configured path"
     else
-        read -erp "Enter your input data directory path (use absolute path): " HOST_DATA_PATH
+        echo -ne "  ${ARROW} Enter your input data directory path: "
+        read -e HOST_DATA_PATH
     fi
 else
-    read -erp "Enter your input data directory path (use absolute path): " HOST_DATA_PATH
+    echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+    echo -ne "  ${ARROW} Enter your input data directory path: "
+    read -e HOST_DATA_PATH
 fi
 
-# Check the directory exists
+# Handle paths with special characters properly
+HOST_DATA_PATH=$(echo "$HOST_DATA_PATH" | sed 's/\\/\\\\/g')
+
+# Directory validation with visual feedback
 if [ ! -d "$HOST_DATA_PATH" ]; then
-  echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-  exit 0
+    handle_error "Directory does not exist: $HOST_DATA_PATH"
 fi
 
-# Save the new path to the config file
+# Save the new path
 echo "$HOST_DATA_PATH" > "$CONFIG_FILE"
-echo -e "The Directory you've given is:\n$HOST_DATA_PATH\n"
-# Function to validate directories
+echo -e "\n${CHECK_MARK} Configuration saved successfully"
+
+# Improved directory validation with progress indication
+print_section_header "VALIDATING INPUT DIRECTORY"
+echo -e "Checking directory structure at: ${BWhite}$HOST_DATA_PATH${Color_Off}\n"
+
+show_loading "Analyzing directory structure" 2
+
+# Function to validate directories with improved visual feedback
 validate_directory() {
     local dir=$1
     local name=$2
     local color=$3
+    local required=$4
 
+    # Add a small delay to make the process visible to the user
+    sleep 0.3
+    
+    echo -ne "  ${ARROW} Checking for ${color}${name}${Color_Off} directory... "
+    
     if [ -d "$dir" ]; then
-        local count=$(find $dir -type f | uniq | wc -l)
-        echo -e "${color}${name}${Color_Off} exists. $count ${name} found."
+        # Count files safely with proper error handling
+        local count=0
+        if [ -n "$(ls -A "$dir" 2>/dev/null)" ]; then
+            count=$(find "$dir" -type f 2>/dev/null | wc -l)
+        fi
+        
+        # Colorize the count based on number of files
+        if [ $count -eq 0 ]; then
+            echo -e "${CHECK_MARK} Found but ${BYellow}empty${Color_Off} (0 files)"
+        elif [ $count -lt 5 ]; then
+            echo -e "${CHECK_MARK} Found with ${BYellow}$count${Color_Off} files"
+        else
+            echo -e "${CHECK_MARK} Found with ${BGreen}$count${Color_Off} files"
+        fi
     else
-        echo -e "Error: Directory $dir does not exist."
+        if [ "$required" = "true" ]; then
+            echo -e "${CROSS_MARK} ${BRed}Missing required directory!${Color_Off}"
+            return 1
+        else
+            echo -e "${WARNING_MARK} ${BYellow}Optional directory not found. Continuing...${Color_Off}"
+            return 0
+        fi
     fi
+    return 0
 }
 
-validate_directory "$HOST_DATA_PATH/forcings" "forcings" "$BBlue"
-validate_directory "$HOST_DATA_PATH/config" "config" "$BGreen"
-validate_directory "$HOST_DATA_PATH/outputs" "outputs" "$BPurple"
+# Validate critical directories with status tracking
+error_count=0
+validate_directory "$HOST_DATA_PATH/forcings" "forcings" "$BBlue" "true" || ((error_count++))
+validate_directory "$HOST_DATA_PATH/config" "config" "$BGreen" "true" || ((error_count++))
+validate_directory "$HOST_DATA_PATH/outputs" "outputs" "$BPurple" "true" || ((error_count++))
+validate_directory "$HOST_DATA_PATH/restarts" "restarts" "$BCyan" "false"
+
+# Check if we can proceed based on validation results
+if [ $error_count -gt 0 ]; then
+    handle_error "Missing required directories. Please check your setup."
+else
+    echo -e "\n${BG_Green}${BWhite} SUCCESS: Directory structure validated successfully! ${Color_Off}"
+fi
 
-# Function to perform cleanup
+# Improved cleanup function with better visuals
 cleanup_folder() {
     local folder_path="$1"
     local file_types="$2"
@@ -87,45 +275,54 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations!${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files.${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
@@ -133,140 +330,238 @@ cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
 
-# File discovery
-echo -e "\nLooking in the provided directory gives us:"
 find_files() {
     local path=$1
     local name=$2
     local regex=$3
     local color=$4
 
-    local files=$(find "$path" -iname "$regex")
-    echo -e "${color}Found these $name files:${Color_Off}"
-    echo "$files" || echo "No $name files found."
+    echo -e "${ARROW} Searching for ${color}$name${Color_Off} files..."
+    
+    local files=$(find "$path" -iname "$regex" 2>/dev/null)
+    if [ -n "$files" ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Found $(echo "$files" | wc -l) files:${Color_Off}"
+        echo -e "  ${BCyan}$(echo "$files" | sed 's/^/    /')${Color_Off}"
+    else
+        echo -e "  ${WARNING_MARK} ${BYellow}No $name files found.${Color_Off}"
+    fi
 }
 
 find_files "$HOST_DATA_PATH" "hydrofabric" "*.gpkg" "$UGreen"
 find_files "$HOST_DATA_PATH" "realization" "realization.json" "$UGreen"
 
-# Detect Arch and Docker
-echo -e "\nDetected ISA = $(uname -a)"
-if docker --version ; then
-    echo "Docker found"
+# System detection with improved visuals
+print_section_header "SYSTEM CONFIGURATION"
+
+echo -e "${ARROW} ${BWhite}Hardware Detection:${Color_Off}"
+system_arch=$(uname -m)
+os_name=$(uname -s)
+
+echo -e "  ${INFO_MARK} Operating System: ${BCyan}$os_name${Color_Off}"
+echo -e "  ${INFO_MARK} Architecture: ${BCyan}$system_arch${Color_Off}"
+
+# Docker detection with better error handling
+echo -e "\n${ARROW} ${BWhite}Checking for Docker:${Color_Off}"
+if command -v docker >/dev/null 2>&1; then
+    docker_version=$(docker --version | cut -d' ' -f3 | sed 's/,//')
+    echo -e "  ${CHECK_MARK} Docker detected (version: ${BGreen}$docker_version${Color_Off})"
 else
-    echo "Docker not found"
+    handle_error "Docker not found. This script requires Docker to run the NextGen model."
 fi
 
-IMAGE_NAME=awiciroh/ciroh-ngen-image:latest
+IMAGE_NAME=$NGEN_IMAGE_NAME:latest
+
+# Model run options with improved visuals
+print_section_header "MODEL EXECUTION OPTIONS"
 
-# Model run options
-echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-options=("Run NextGen using existing local docker image" "Run NextGen after updating to latest docker image" "Exit")
+echo -e "${ARROW} ${BWhite}Please select an option to proceed:${Color_Off}\n"
+options=("Run NextGen using existing local docker image" "Update to latest docker image and run" "Exit")
 select option in "${options[@]}"; do
     case $option in
         "Run NextGen using existing local docker image")
-            echo "running the model"
+            echo -e "\n${CHECK_MARK} ${BGreen}Using existing Docker image${Color_Off}"
             break
             ;;
-        "Run NextGen after updating to latest docker image")
-            echo "pulling container and running the model"
+        "Update to latest docker image and run")
+            echo -e "\n${ARROW} ${BYellow}Updating Docker image...${Color_Off}"
+            show_loading "Downloading latest NextGen image" 3
             docker pull $IMAGE_NAME
+            echo -e "${CHECK_MARK} ${BGreen}Docker image updated successfully${Color_Off}"
             break
             ;;
-        Exit)
-            echo "Have a nice day!"
+        "Exit")
+            echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
             exit 0
             ;;
-        *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
+        *) echo -e "${CROSS_MARK} ${BRed}Invalid option $REPLY. Please try again.${Color_Off}"
             ;;
     esac
 done
 
+# Running model with improved progress indicators
+print_section_header "RUNNING NEXTGEN MODEL SIMULATION"
+
+echo -e "${ARROW} ${BWhite}Preparing to run NextGen model...${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Local directory: ${BWhite}$HOST_DATA_PATH${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Container directory: ${BWhite}/ngen/ngen/data${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Docker image: ${BWhite}$IMAGE_NAME${Color_Off}"
+
+# Pause for visual confirmation
+sleep 2
 
-echo -e "\nRunning NextGen docker container..."
-echo -e "Mounting local host directory $HOST_DATA_PATH to /ngen/ngen/data within the container."
+echo -e "\n${ARROW} ${BYellow}Launching NextGen container...${Color_Off}"
 docker run --rm -it -v "$HOST_DATA_PATH:/ngen/ngen/data" "$IMAGE_NAME" /ngen/ngen/data/
 
-# Final output count
+# Final output count with improved presentation
+print_section_header "SIMULATION RESULTS"
+
 Final_Outputs_Count=$(find "$HOST_DATA_PATH/outputs/" -type f | wc -l)
-echo -e "$Final_Outputs_Count new outputs created."
-echo -e "Any copied files can be found here: $HOST_DATA_PATH/outputs"
-
-# ============ Run TEEHR ============
-# TODO: Support for ARM64
-# if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# else
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# fi
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
+
+if [ $Final_Outputs_Count -gt 0 ]; then
+    echo -e "${CHECK_MARK} ${BGreen}Simulation completed successfully!${Color_Off}"
+    echo -e "  ${INFO_MARK} ${BWhite}$Final_Outputs_Count${Color_Off} output files generated"
+    echo -e "  ${INFO_MARK} Results stored in: ${BWhite}$HOST_DATA_PATH/outputs${Color_Off}"
+else
+    echo -e "${WARNING_MARK} ${BYellow}No output files were generated.${Color_Off}"
+    echo -e "  ${INFO_MARK} Please check the simulation configuration and try again."
+fi
+
+# ============ Run TEEHR using the runTeehr.sh script ============
+if [ $Final_Outputs_Count -gt 0 ]; then
+    print_section_header "EVALUATION OPTIONS"
+    
+    echo -e "${ARROW} ${BWhite}Would you like to run a TEEHR evaluation on the output?${Color_Off}"
+    echo -e "  ${INFO_MARK} This will analyze your simulation results using the TEEHR toolkit"
+    echo -e "  ${INFO_MARK} Learn more: ${UBlue}https://rtiinternational.github.io/ngiab-teehr/${Color_Off}\n"
+    
+    read -erp "  Run TEEHR evaluation? [Y/n]: " run_teehr_choice
+    
     # Default to 'y' if input is empty
     if [[ -z "$run_teehr_choice" ]]; then
         run_teehr_choice="y"
     fi
-    # Check for valid input
-    if [[ "$run_teehr_choice" == [YyNn]* ]]; then
-        break
+    
+    # Execute TEEHR if requested
+    if [[ "$run_teehr_choice" == [Yy]* ]]; then
+        # Check if the runTeehr.sh script exists
+        if [ -f "$TEEHR_SCRIPT" ]; then
+            echo -e "\n${INFO_MARK} ${BWhite}Launching TEEHR evaluation...${Color_Off}"
+            
+            # Make sure the script is executable
+            if [ ! -x "$TEEHR_SCRIPT" ]; then
+                chmod +x "$TEEHR_SCRIPT"
+            fi
+            
+            # Call the runTeehr.sh script with the data path
+            if ! "$TEEHR_SCRIPT" "$HOST_DATA_PATH"; then
+                echo -e "\n${WARNING_MARK} ${BRed}Failed to run TEEHR evaluation.${Color_Off}"
+                echo -e "  ${INFO_MARK} Check that the runTeehr.sh script is properly configured."
+            fi
+        else
+            echo -e "\n${WARNING_MARK} ${BRed}Could not find the TEEHR evaluation script.${Color_Off}"
+            echo -e "  ${INFO_MARK} Expected location: ${BWhite}$TEEHR_SCRIPT${Color_Off}"
+            echo -e "  ${INFO_MARK} Please make sure the script is in the current directory."
+            
+            # Fallback to inline TEEHR execution
+            echo -e "\n${INFO_MARK} ${BYellow}Falling back to embedded TEEHR evaluation...${Color_Off}"
+            
+            # Detect architecture for default tag
+            if uname -a | grep -q 'arm64\|aarch64'; then
+                default_tag="latest"
+            else
+                default_tag="x86"
+            fi
+            
+            echo -e "  ${INFO_MARK} Detected architecture: ${BCyan}$(uname -m)${Color_Off} (default tag: ${BCyan}$default_tag${Color_Off})"
+            read -erp "  ${ARROW} Specify TEEHR image tag [default: '$default_tag']: " teehr_image_tag
+            
+            if [[ -z "$teehr_image_tag" ]]; then
+                teehr_image_tag=$default_tag
+            fi
+            
+            IMAGE_NAME=$TEEHR_IMAGE_NAME
+            
+            print_section_header "RUNNING TEEHR EVALUATION"
+            
+            echo -e "${ARROW} ${BYellow}Launching TEEHR evaluation...${Color_Off}\n"
+            docker run -v "$HOST_DATA_PATH:/app/data" "$IMAGE_NAME:$teehr_image_tag"
+            
+            echo -e "\n${BG_Green}${BWhite} TEEHR EVALUATION COMPLETE ${Color_Off}"
+            echo -e "${INFO_MARK} ${BCyan}Results have been saved to your output directory${Color_Off}"
+        fi
     else
-        echo -e "${RED}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (yes).${RESET}"
+        echo -e "${INFO_MARK} ${BCyan}Skipping TEEHR evaluation step.${Color_Off}"
     fi
-done
+else
+    echo -e "\n${INFO_MARK} ${BYellow}No outputs available for evaluation.${Color_Off}"
+fi
 
-# Execute the command
-if [[ "$run_teehr_choice" == [Yy]* ]]; then
-    # TEEHR run options
-    echo -e "${UYellow}Specify the TEEHR image tag to use: ${Color_Off}"
-    read -erp "Image tag (ex. v0.1.4, x86, default: 'latest'): " teehr_image_tag
-    if [[ -z "$teehr_image_tag" ]]; then
-        if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-            teehr_image_tag=latest
+# ============ Use viewOnTethys.sh for visualization ============
+if [ $Final_Outputs_Count -gt 0 ]; then
+    print_section_header "VISUALIZATION OPTIONS"
+    
+    echo -e "${ARROW} ${BWhite}Would you like to visualize results using Tethys?${Color_Off}"
+    echo -e "  ${INFO_MARK} This will provide an interactive web interface to explore your model results"
+    read -erp "  Visualize results? [Y/n]: " visualize_choice
+    
+    # Default to 'y' if input is empty
+    if [[ -z "$visualize_choice" || "$visualize_choice" == [Yy]* ]]; then
+        # Check if the viewOnTethys.sh script exists
+        if [ -f "$TETHYS_SCRIPT" ]; then
+            echo -e "\n${INFO_MARK} ${BWhite}Launching Tethys visualization...${Color_Off}"
+            
+            # Make sure the script is executable
+            if [ ! -x "$TETHYS_SCRIPT" ]; then
+                chmod +x "$TETHYS_SCRIPT"
+            fi
+            
+            # Call the viewOnTethys.sh script with the data path
+            if ! "$TETHYS_SCRIPT" "$HOST_DATA_PATH"; then
+                echo -e "\n${WARNING_MARK} ${BRed}Failed to launch Tethys visualization.${Color_Off}"
+                echo -e "  ${INFO_MARK} Check that the viewOnTethys.sh script is properly configured."
+            fi
         else
-            teehr_image_tag=x86
+            echo -e "\n${WARNING_MARK} ${BRed}Could not find the Tethys visualization script.${Color_Off}"
+            echo -e "  ${INFO_MARK} Expected location: ${BWhite}$TETHYS_SCRIPT${Color_Off}"
+            echo -e "  ${INFO_MARK} Please make sure the script is in the current directory."
         fi
+    else
+        echo -e "${INFO_MARK} ${BCyan}Skipping visualization step.${Color_Off}"
     fi
-    echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-    options=("Run TEEHR using existing local docker image" "Run TEEHR after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run TEEHR using existing local docker image")
-                echo "running the TEEHR evaluation"
-                break
-                ;;
-            "Run TEEHR after updating to latest docker image")
-                echo "pulling container and running the TEEHR evaluation"
-                docker pull $IMAGE_NAME:$teehr_image_tag
-                break
-                ;;
-            Exit)
-                echo "Have a nice day!"
-                exit 0
-                ;;
-            *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
-                ;;
-        esac
-    done
-
-    docker run -v "$HOST_DATA_PATH:/app/data" "$IMAGE_NAME:$teehr_image_tag"
-    echo -e "${GREEN}TEEHR evaluation complete.${RESET}\n"
 else
-    echo -e "${CYAN}Skipping TEEHR evaluation step.${RESET}\n"
+    echo -e "\n${INFO_MARK} ${BYellow}No outputs available for visualization.${Color_Off}"
 fi
-# ================================
 
-# visualize with Tethys
-if [ $Final_Outputs_Count -gt 0 ]; then
-    ARG1="$HOST_DATA_PATH"
-    if ! "$TETHYS_SCRIPT" "$ARG1"; then
-        printf "Failed to visualize outputs in Tethys:"
-    fi
+# Closing message with improved visuals
+print_section_header "SESSION COMPLETE"
+
+# Create a fancy box for the thank you message
+echo -e "\033[38;5;39m  ┌────────────────────────────────────────────────────────────┐\033[0m"
+echo -e "\033[38;5;39m  │\033[48;5;39m\033[1;37m  Thank you for using NGIAB!                                  \033[0m\033[38;5;39m  │\033[0m"
+echo -e "\033[38;5;39m  └────────────────────────────────────────────────────────────┘\033[0m\n"
+
+echo -e "${INFO_MARK} ${BWhite}Your simulation results are available at:${Color_Off}"
+echo -e "  ${ARROW} ${LBLUE}$HOST_DATA_PATH/outputs${Color_Off}\n"
+
+# Check if any outputs were generated
+output_count=$(find "$HOST_DATA_PATH/outputs/" -type f 2>/dev/null | wc -l)
+if [ "$output_count" -gt 0 ]; then
+    echo -e "  ${CHECK_MARK} ${BGreen}$output_count files were successfully generated${Color_Off}"
 else
-    echo -e "No outputs to visualize."
+    echo -e "  ${WARNING_MARK} ${BYellow}No output files found. Check simulation parameters.${Color_Off}"
 fi
 
-echo -e "Thank you for running NextGen In A Box: National Water Model! Have a nice day!"
-exit 0
+echo -e "\n${INFO_MARK} ${BWhite}For support, please email:${Color_Off}"
+echo -e "  ${ARROW} ${UBlue}ciroh-it-support@ua.edu${Color_Off}\n"
+
+# Show date and time of completion
+echo -e "  ${INFO_MARK} ${BWhite}Session completed at:${Color_Off} $(date '+%Y-%m-%d %H:%M:%S')\n"
+
+echo -e "${BWhite}Have a great day!${Color_Off}\n"
+
+exit 0
\ No newline at end of file
diff --git a/runTeehr.sh b/runTeehr.sh
old mode 100644
new mode 100755
index 12595a1..bd93e2f
--- a/runTeehr.sh
+++ b/runTeehr.sh
@@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
 }
 
-_check_if_data_folder_exits(){
-    # Check the directory exists
+# Set up trap for Ctrl-C and EXIT
+trap handle_sigint INT
+trap clean_up_resources EXIT
+
+# Check if a directory exists
+check_if_data_folder_exists() {
     if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
+        handle_error "Directory does not exist: $DATA_FOLDER_PATH"
     fi
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
+# Check and read from config file
+check_and_read_config() {
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            check_if_data_folder_exists
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
+        else
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
+            check_if_data_folder_exists
+            
             # Save the new path to the config file
             echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
+            echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
         fi
+    else
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+        echo -ne "  ${ARROW} Enter your input data directory path: "
+        read -e DATA_FOLDER_PATH
+        check_if_data_folder_exists
+        
+        # Save the path to the config file
+        echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
+        echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
     fi
 }
 
+# Handle path from arguments or config
 check_last_path() {
     if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+        check_and_read_config
     else
         DATA_FOLDER_PATH="$1"
+        check_if_data_folder_exists
     fi
 }
 
-### Start of the Script ###
+# Main script execution
+print_welcome_banner
 
-# Constanst
-CONFIG_FILE="$HOME/.host_data_path.conf"
+# Check if data path is provided as argument
+check_last_path "$1"
 
-check_last_path "$@"
+print_section_header "TEEHR EVALUATION SETUP"
 
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
-    # Default to 'y' if input is empty
-    if [[ -z "$run_teehr_choice" ]]; then
-        run_teehr_choice="y"
-    fi
-    # Check for valid input
-    if [[ "$run_teehr_choice" == [YyNn]* ]]; then
-        break
+echo -e "${INFO_MARK} ${BWhite}TEEHR will evaluate model outputs against observations${Color_Off}"
+echo -e "  ${ARROW} Learn more: ${UBlue}https://rtiinternational.github.io/ngiab-teehr/${Color_Off}\n"
+
+echo -e "${ARROW} ${BWhite}Would you like to run a TEEHR evaluation on your model outputs?${Color_Off}"
+read -erp "  Run evaluation? [Y/n]: " run_teehr_choice
+
+# Default to 'y' if input is empty
+if [[ -z "$run_teehr_choice" ]]; then
+    run_teehr_choice="y"
+fi
+
+# Execute the TEEHR evaluation if requested
+if [[ "$run_teehr_choice" =~ ^[Yy] ]]; then
+    # Detect platform architecture for default tag
+    if uname -a | grep -q 'arm64\|aarch64'; then
+        default_tag="latest" # ARM64 architecture
     else
-        echo -e "${RED}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (yes).${RESET}"
+        default_tag="x86"    # x86 architecture
     fi
-done
-
-# Execute the command
-if [[ "$run_teehr_choice" == [Yy]* ]]; then
-    # TEEHR run options
-    echo -e "${UYellow}Specify the TEEHR image tag to use: ${Color_Off}"
-    read -erp "Image tag (ex. v0.1.4, x86, default: 'latest'): " teehr_image_tag
+    
+    echo -e "\n${ARROW} ${BWhite}System architecture detected: ${BCyan}$(uname -m)${Color_Off}"
+    echo -e "  ${INFO_MARK} Recommended image tag: ${BCyan}$default_tag${Color_Off}"
+    echo -ne "  ${ARROW} Specify TEEHR image tag [default: $default_tag]: "
+    read -e teehr_image_tag
+    
     if [[ -z "$teehr_image_tag" ]]; then
-        if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-            teehr_image_tag=latest
-        else
-            teehr_image_tag=x86
-        fi
+        teehr_image_tag="$default_tag"
+        echo -e "  ${CHECK_MARK} ${BGreen}Using default tag: $default_tag${Color_Off}"
+    else
+        echo -e "  ${CHECK_MARK} ${BGreen}Using specified tag: $teehr_image_tag${Color_Off}"
     fi
-    echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-    options=("Run TEEHR using existing local docker image" "Run TEEHR after updating to latest docker image" "Exit")
+
+    print_section_header "CONTAINER MANAGEMENT"
+    
+    echo -e "${ARROW} ${BWhite}Select an option:${Color_Off}\n"
+    options=("Run TEEHR using existing local image" "Update to latest TEEHR image" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Run TEEHR using existing local docker image")
-                echo "running the TEEHR evaluation"
+            "Run TEEHR using existing local image")
+                echo -e "  ${CHECK_MARK} ${BGreen}Using existing local TEEHR image${Color_Off}"
                 break
                 ;;
-            "Run TEEHR after updating to latest docker image")
-                echo "pulling container and running the TEEHR evaluation"
-                docker pull $IMAGE_NAME:$teehr_image_tag
+            "Update to latest TEEHR image")
+                echo -e "  ${ARROW} ${BYellow}Updating TEEHR image...${Color_Off}"
+                show_loading "Downloading latest TEEHR image" 3
+                
+                if ! docker pull "${IMAGE_NAME}:${teehr_image_tag}"; then
+                    handle_error "Failed to pull Docker image: ${IMAGE_NAME}:${teehr_image_tag}"
+                fi
+                
+                echo -e "  ${CHECK_MARK} ${BGreen}TEEHR image updated successfully${Color_Off}"
                 break
                 ;;
-            Exit)
-                echo "Have a nice day!"
+            "Exit")
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
+            *)
+                echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please try again.${Color_Off}"
                 ;;
         esac
     done
 
-    docker run -v "$DATA_FOLDER_PATH:/app/data" "$IMAGE_NAME:$teehr_image_tag"
-    echo -e "${GREEN}TEEHR evaluation complete.${RESET}\n"
+    print_section_header "RUNNING TEEHR EVALUATION"
+    
+    echo -e "${INFO_MARK} ${BWhite}Evaluating model outputs in: ${BCyan}$DATA_FOLDER_PATH${Color_Off}"
+    echo -e "  ${ARROW} This analysis may take several minutes depending on your dataset size"
+    
+    show_loading "Initializing TEEHR evaluation" 2
+    
+    # Create a unique container name
+    CONTAINER_NAME="${TEEHR_CONTAINER_PREFIX}-$(date +%s)"
+    
+    # First clean up any old containers
+    clean_up_resources
+    
+    # Run the TEEHR container with a name for easier cleanup
+    if ! docker run --name "$CONTAINER_NAME" --rm -v "$DATA_FOLDER_PATH:/app/data" "${IMAGE_NAME}:${teehr_image_tag}"; then
+        handle_error "TEEHR evaluation failed"
+    fi
+    
+    print_section_header "EVALUATION COMPLETE"
+    
+    echo -e "${BG_Green}${BWhite} TEEHR evaluation completed successfully! ${Color_Off}\n"
+    echo -e "${INFO_MARK} ${BWhite}Results have been saved to your outputs directory:${Color_Off}"
+    echo -e "  ${ARROW} ${BCyan}$DATA_FOLDER_PATH/outputs/teehr/${Color_Off}"
+    echo -e "\n${INFO_MARK} You can visualize these results using the Tethys platform"
+    echo -e "  ${ARROW} Run ${UBlue}./viewOnTethys.sh $DATA_FOLDER_PATH${Color_Off} to start visualization"
 else
-    echo -e "${CYAN}Skipping TEEHR evaluation step.${RESET}\n"
+    echo -e "\n${INFO_MARK} ${BCyan}Skipping TEEHR evaluation.${Color_Off}"
 fi
-# ================================
+
+echo -e "\n${BG_Blue}${BWhite} Thank you for using NGIAB! ${Color_Off}"
+echo -e "${INFO_MARK} For support, please email: ${UBlue}ciroh-it-support@ua.edu${Color_Off}\n"
+
+# Clean up any lingering resources before exit
+clean_up_resources
+
+exit 0
\ No newline at end of file
diff --git a/viewOnTethys.sh b/viewOnTethys.sh
index a0a4bd4..ff5ef8e 100755
--- a/viewOnTethys.sh
+++ b/viewOnTethys.sh
@@ -1,5 +1,14 @@
 #!/bin/bash
-# ANSI color codes
+
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - Tethys Visualization
+# ======================================================================
+
+# Enable debug mode to see what's happening
+# set -x
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
 BRed='\033[1;31m'
 BGreen='\033[1;32m'
 BYellow='\033[1;33m'
@@ -17,289 +26,393 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
+        return 1
     fi
 
-    # 2) Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
-    local owner_uid=""
-    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
-        :  # GNU stat (Linux)
-    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
-        :  # BSD stat (macOS, Git-Bash)
+    # Derive the target path
+    local base_name
+    base_name="$(basename "$input_path")"
+    local model_run_path="$models_dir/$base_name"
+    
+    # Copy logic - simplified to reduce errors
+    echo -e "${INFO_MARK} ${BWhite}Copying model data to visualization directory...${Color_Off}"
+    
+    # Remove existing directory if it exists
+    if [ -e "$model_run_path" ]; then
+        echo -e "  ${INFO_MARK} ${BYellow}Directory already exists, overwriting...${Color_Off}"
+        rm -rf "$model_run_path"
     fi
-
-    # 3) If the directory is not owned by the current user, try to chown it
-    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
-        if command -v chown >/dev/null 2>&1; then
-            echo -e "${BYellow}Reclaiming ownership of $dir (sudo may prompt)…${Color_Off}"
-            sudo chown -R "$(id -u):$(id -g)" "$dir"
-        fi
+    
+    # Copy the data
+    if cp -r "$input_path" "$models_dir/"; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully${Color_Off}"
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to copy model data${Color_Off}"
+        return 1
     fi
-
-    # 4) Ensure the current user has rwx on the directory
-    chmod u+rwx "$dir"
+    
+    # Output the directory path
+    echo "$model_run_path"
 }
 
-# Ensure a *regular file* exists (and is writable) without touching siblings
-_ensure_visualizer_conf_host_file() {
-    local file="$1"
-    local dir
-    dir=$(dirname "$file")
-
-    # 1) make sure the directory exists and is writable by the user
-    _ensure_host_dir "$dir" || return 1
+add_model_run() {
+    local input_path="$1"
+    local json_file="$VISUALIZER_CONF"
 
-    # 2) create the file if it doesn't exist, and initialise it
-    if [ ! -f "$file" ]; then
-        echo -e "${BRed}File $file does not exist. Creating it...${Color_Off}"
-        echo '{"model_runs":[]}' > "$file"
+    # Ensure JSON file exists
+    if ! ensure_visualizer_conf_host_file "$json_file"; then
+        echo "Failed to create config file"
+        return 1
     fi
 
-    # 3) ensure *you* can read/write the file
-    chmod u+rw "$file"
-}
+    # Extract the basename for label
+    local base_name
+    base_name=$(basename "$input_path")
 
+    # Generate a new UUID for the id field - simplified
+    local new_uuid="ngiab-$(date +%Y%m%d%H%M%S)-$(( RANDOM % 1000 ))"
 
-_run_tethys() {
+    # Current date/time
+    local current_time
+    current_time=$(date +"%Y-%m-%d:%H:%M:%S")
 
-    _ensure_host_dir  "$MODELS_RUNS_DIRECTORY"
-    _ensure_host_dir  "$DATASTREAM_DIRECTORY"
-    _ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    # Path for Tethys container
+    local final_path="$TETHYS_PERSIST_PATH/ngiab_visualizer/$base_name"
+    
+    echo -e "${INFO_MARK} ${BWhite}Registering model run in visualization system...${Color_Off}"
+    
+    # Simplified approach - create a new file
+    echo '{"model_runs":[{"label":"'"$base_name"'","path":"'"$final_path"'","date":"'"$current_time"'","id":"'"$new_uuid"'","subset":"","tags":[]}]}' > "$json_file"
+    
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model run registered successfully${Color_Off}"
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to register model run.${Color_Off}"
+        return 1
+    fi
+}
 
-    _execute_command docker run --rm -it -d \
+run_tethys() {
+    ensure_host_dir "$MODELS_RUNS_DIRECTORY"
+    ensure_host_dir "$DATASTREAM_DIRECTORY"
+    ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    
+    echo -e "${ARROW} ${BWhite}Launching Tethys container...${Color_Off}"
+    
+    # First, make sure any existing Tethys containers are stopped
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys container is already running. Stopping it first...${Color_Off}"
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 3
+    fi
+    
+    # Final check - if container still exists, force removal
+    if docker ps -a -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${WARNING_MARK} ${BYellow}Forcibly removing container...${Color_Off}"
+        docker rm -f "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1 || true
+        sleep 2
+    fi
+    
+    # Create new network
+    create_tethys_docker_network
+    
+    # Brief delay before starting
+    sleep 1
+    echo -e "  ${INFO_MARK} ${BYellow}Starting Tethys container...${Color_Off}"
+    
+    # Launch container with explicit error handling
+    echo -e "  ${INFO_MARK} Running docker command..."
+    docker run --rm -d \
         -v "$MODELS_RUNS_DIRECTORY:$TETHYS_PERSIST_PATH/ngiab_visualizer" \
         -v "$DATASTREAM_DIRECTORY:$TETHYS_PERSIST_PATH/.datastream_ngiab" \
-        -p $NGINX_TETHYS_PORT:$NGINX_TETHYS_PORT \
-        --platform "$PLATFORM" \
+        -p "$NGINX_TETHYS_PORT:$NGINX_TETHYS_PORT" \
         --network "$DOCKER_NETWORK" \
         --name "$TETHYS_CONTAINER_NAME" \
         --env MEDIA_ROOT="$TETHYS_PERSIST_PATH/media" \
@@ -307,206 +420,113 @@ _run_tethys() {
         --env SKIP_DB_SETUP="$SKIP_DB_SETUP" \
         --env DATASTREAM_CONF="$TETHYS_PERSIST_PATH/.datastream_ngiab" \
         --env VISUALIZER_CONF="$TETHYS_PERSIST_PATH/ngiab_visualizer/ngiab_visualizer.json" \
-        --env NGINX_PORT=$NGINX_TETHYS_PORT \
-        --env CSRF_TRUSTED_ORIGINS=$CSRF_TRUSTED_ORIGINS \
-        "$TETHYS_IMAGE_NAME" \
-        > /dev/null 2>&1
-}
-
-
-_copy_models_run() {
-    local input_path="$1"
-    local models_dir="$HOME/ngiab_visualizer"
-    # 1) make sure ~/ngiab_visualizer exists and you own it
-    _ensure_host_dir "$models_dir" || {
-        echo -e "${BRed}Failed to create or fix permissions on $models_dir${Color_Off}" >&2
-        return 1
-    }
-
-    # 2) derive the target path
-    local base_name
-    base_name="$(basename "$input_path")"
-    local model_run_path="$models_dir/$base_name"
-    local final_copied_path="$model_run_path"
-
-    # 3) copy logic
-    if [ ! -e "$model_run_path" ]; then
-        cp -r "$input_path" "$models_dir" || {
-            echo -e "${BRed}Error: Could not copy $input_path → $models_dir${Color_Off}" >&2
-            return 1
-        }
-        echo -e "${BCyan}Copied: $input_path → $model_run_path${Color_Off}" >&2
+        --env NGINX_PORT="$NGINX_TETHYS_PORT" \
+        --env CSRF_TRUSTED_ORIGINS="$CSRF_TRUSTED_ORIGINS" \
+        "${TETHYS_REPO}:${TETHYS_TAG}"
+        
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys container started successfully.${Color_Off}"
+        return 0
     else
-        echo -e "${BYellow}Directory '$model_run_path' already exists.${Color_Off}" >&2
-        while true; do
-            echo -ne "${BYellow}Overwrite (O) or copy with different name (D)? [O/D]: ${Color_Off}" >&2
-            read -r choice < /dev/tty
-            case "$choice" in
-                [Oo]* )
-                    rm -rf "$model_run_path"
-                    cp -r "$input_path" "$models_dir" || {
-                        echo -e "${BRed}Error: Could not overwrite $model_run_path${Color_Off}" >&2
-                        return 1
-                    }
-                    echo -e "${BCyan}Overwritten with: $input_path → $model_run_path${Color_Off}" >&2
-                    break
-                    ;;
-                [Dd]* )
-                    echo -ne "${BBlue}Enter a new directory name: ${Color_Off}" >&2
-                    read -r new_name < /dev/tty
-                    if [ -z "$new_name" ]; then
-                        echo -e "${BRed}No name entered. Try again.${Color_Off}" >&2
-                        continue
-                    fi
-                    local new_path="$models_dir/$new_name"
-                    if [ -e "$new_path" ]; then
-                        echo -e "${BRed}'$new_name' already exists. Choose another name.${Color_Off}" >&2
-                        continue
-                    fi
-                    cp -r "$input_path" "$new_path" || {
-                        echo -e "${BRed}Error: Could not copy to $new_path${Color_Off}" >&2
-                        return 1
-                    }
-                    echo -e "${BPurple}Copied to: $new_path${Color_Off}" >&2
-                    final_copied_path="$new_path"
-                    break
-                    ;;
-                * )
-                    echo -e "${BRed}Invalid choice. Enter 'O' or 'D'.${Color_Off}" >&2
-                    ;;
-            esac
-        done
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to start Tethys container.${Color_Off}"
+        return 1
     fi
-
-    # 4) output the directory the caller should register
-    echo "$final_copied_path"
 }
 
-_add_model_run() {
-  local input_path="$1"
-  local json_file="$VISUALIZER_CONF"
-
-  # 1) Ensure $json_file exists
-  echo -e "${BGreen}Checking for $json_file...${Color_Off}"
-  if [ ! -f "$json_file" ]; then
-    echo '{"model_runs":[]}' > "$json_file"
-  fi
-
-  # 2) Extract the basename for label
-  local base_name
-  base_name=$(basename "$input_path")
-
-  # Generate a new UUID for the id field
-  local new_uuid
-  new_uuid=$(uuidgen)
-
-  # Current date/time (adjust format as needed)
-  local current_time
-  current_time=$(date +"%Y-%m-%d:%H:%M:%S")
-
-  # Always use /var/lib/tethys_persist/ngiab_visualizer as the base directory
-  local final_path="/var/lib/tethys_persist/ngiab_visualizer/$base_name"
-  jq --arg base_name "$base_name" \
-     --arg final_path  "$final_path" \
-     --arg current_time  "$current_time" \
-     --arg uuid    "$new_uuid" \
-     '.model_runs += [ 
-       { 
-         "label": $base_name, 
-         "path": $final_path, 
-         "date": $current_time, 
-         "id": $uuid, 
-         "subset": "", 
-         "tags": [] 
-       }
-     ]' \
-     "$json_file" > "${json_file}.tmp" && mv -f "${json_file}.tmp" "$json_file"
+pause_script_execution() {
+    echo -e "\n${BG_Blue}${BWhite} Tethys is now running ${Color_Off}"
+    echo -e "${INFO_MARK} Access the visualization at: ${UBlue}http://localhost:$NGINX_TETHYS_PORT/apps/ngiab${Color_Off}"
+    echo -e "${INFO_MARK} Press ${BWhite}Ctrl+C${Color_Off} to stop Tethys when you're done."
+    
+    # Keep script running until user interrupts
+    while true; do
+        sleep 10
+    done
 }
 
-create_tethys_portal(){
-    while true; do
-        echo -e "${BYellow}Visualize outputs using the Tethys Platform (https://www.tethysplatform.org/)? (Y/n, default: n):${Color_Off}"
-        read -r visualization_choice
-        
-        # Default to 'n' if input is empty
-        if [[ -z "$visualization_choice" ]]; then
-            visualization_choice="n"
-        fi
+# Main script execution
+print_welcome_banner
 
-        # Check for valid input
-        if [[ "$visualization_choice" =~ ^[YyNn]$ ]]; then
-            break
-        else
-            echo -e "${BRed}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (no).${Color_Off}"
-        fi
-    done
-    
-    echo -e "${BYellow}Specify the Tethys image tag to use: ${Color_Off}"
-    read -erp "Tag (e.g. v0.2.1, default: latest): " TETHYS_TAG
-    if [[ -z "$TETHYS_TAG" ]]; then
-        TETHYS_TAG="latest"
-    fi
+# Check if data path is provided as argument
+DATA_FOLDER_PATH="$1"
 
-    # Build the full image reference
-    TETHYS_IMAGE_NAME="${TETHYS_REPO}:${TETHYS_TAG}"    
-
-
-    # Execute the command
-    if [[ "$visualization_choice" =~ ^[Yy]$ ]]; then
-        echo -e "${BGreen}Setting up Tethys Portal image...${Color_Off}"
-        _create_tethys_docker_network
-        if _check_for_existing_tethys_image; then
-            _choose_port_to_run_tethys
-            _execute_command _run_containers
-            _wait_container $TETHYS_CONTAINER_NAME
-            echo -e "${BGreen}Your outputs are ready to be visualized at http://localhost:$NGINX_TETHYS_PORT/apps/ngiab ${Color_Off}"
-            echo -e "${UPurple}You can use the following to login: ${Color_Off}"
-            echo -e "${BCyan}user: admin${Color_Off}"
-            echo -e "${BCyan}password: pass${Color_Off}"
-            echo -e "${UPurple}Check the App source code: https://github.com/CIROH-UA/ngiab-client ${Color_Off}"
-            _pause_script_execution
+if [[ -z "$DATA_FOLDER_PATH" ]]; then
+    # If no path provided, check if we have a saved path
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
         else
-            echo -e "${BRed}Failed to prepare Tethys portal.\n${Color_Off}"
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
         fi
     else
-        echo -e "${BCyan}Skipping Tethys visualization setup.\n${Color_Off}"
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found.${Color_Off}"
+        echo -ne "  ${ARROW} Enter your input data directory path: "
+        read -e DATA_FOLDER_PATH
     fi
-}
+    
+    # Save the new path
+    echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
+    echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use.${Color_Off}"
+fi
 
+# Validate the directory
+if [ ! -d "$DATA_FOLDER_PATH" ]; then
+    echo -e "${CROSS_MARK} ${BRed}Directory does not exist: $DATA_FOLDER_PATH${Color_Off}"
+    exit 1
+fi
 
-##########################
-#####START OF SCRIPT######
-##########################
+print_section_header "PREPARING VISUALIZATION ENVIRONMENT"
 
-# Set up the SIGINT trap to call the handle_sigint function
-trap handle_sigint SIGINT
+# Copy model data to visualization directory
+final_dir=$(copy_models_run "$DATA_FOLDER_PATH") || {
+    echo -e "${CROSS_MARK} ${BRed}Failed to copy model data. Exiting.${Color_Off}"
+    exit 1
+}
 
-# Constanst
-PLATFORM='linux/amd64'
-MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
-VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
-DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
-TETHYS_CONTAINER_NAME="tethys-ngen-portal"
-DOCKER_NETWORK="tethys-network"
-TETHYS_REPO="awiciroh/tethys-ngiab"
-TETHYS_TAG="latest"
-TETHYS_IMAGE_NAME=""
-DATA_FOLDER_PATH="$1"
-TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
-CONFIG_FILE="$HOME/.host_data_path.conf"
-SKIP_DB_SETUP=false
-NGINX_TETHYS_PORT=80
-CSRF_TRUSTED_ORIGINS="\"[http://localhost:$NGINX_TETHYS_PORT, http://127.0.0.1:$NGINX_TETHYS_PORT]\""
+# Register the model run
+add_model_run "$final_dir" || {
+    echo -e "${CROSS_MARK} ${BRed}Failed to register model run. Exiting.${Color_Off}"
+    exit 1
+}
 
+print_section_header "LAUNCHING TETHYS VISUALIZATION"
 
-# check for architecture
-if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-    PLATFORM=linux/arm64
-else
-    PLATFORM=linux/amd64
-fi
+# Setup and run Tethys
+check_for_existing_tethys_image || {
+    echo -e "${CROSS_MARK} ${BRed}Failed to prepare Tethys image. Exiting.${Color_Off}"
+    exit 1
+}
+choose_port_to_run_tethys
+run_tethys || {
+    echo -e "${CROSS_MARK} ${BRed}Failed to start Tethys container. Exiting.${Color_Off}"
+    exit 1
+}
+
+# Wait for container to be ready
+wait_container "$TETHYS_CONTAINER_NAME" || {
+    echo -e "${CROSS_MARK} ${BRed}Tethys container failed to start properly. Exiting.${Color_Off}"
+    exit 1
+}
+
+print_section_header "VISUALIZATION READY"
 
+echo -e "${BG_Green}${BWhite} Your model outputs are now available for visualization! ${Color_Off}\n"
+echo -e "${INFO_MARK} Access the visualization at: ${UBlue}http://localhost:$NGINX_TETHYS_PORT/apps/ngiab${Color_Off}"
+echo -e "${INFO_MARK} Login credentials:"
+echo -e "  ${ARROW} ${BWhite}Username:${Color_Off} admin"
+echo -e "  ${ARROW} ${BWhite}Password:${Color_Off} pass"
+echo -e "\n${INFO_MARK} Source code: ${UBlue}https://github.com/CIROH-UA/ngiab-client${Color_Off}"
 
-check_last_path "$@"
+# Keep the script running
+pause_script_execution
 
-create_tethys_portal
+exit 0
\ No newline at end of file


Reviews:
user: login: Sheargrub
body: Purely a pass for grammar/formatting. Will test locally next.
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T17:41:19Z
user: login: benlee0423
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T17:48:23Z

Review comments:
diff_hunk: @@ -19,63 +24,242 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
 set -e
 
 CONFIG_FILE="$HOME/.host_data_path.conf"
 TETHYS_SCRIPT="./viewOnTethys.sh"
+TEEHR_SCRIPT="./runTeehr.sh"
+
+# Container and image constants
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_IMAGE_NAME="awiciroh/tethys-ngiab"
+TEEHR_IMAGE_NAME="awiciroh/ngiab-teehr"
+NGEN_IMAGE_NAME="awiciroh/ciroh-ngen-image"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB)\033[38;5;39m                                         ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mAdvanced Hydrologic Modeling Tool\033[38;5;39m                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Cleanup function for all resources
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Stop any running TEEHR containers
+    local teehr_containers=$(docker ps -q --filter "ancestor=$TEEHR_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$teehr_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $teehr_containers >/dev/null 2>&1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+    fi
+    
+    # Remove the Docker network
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1
+    fi
+    
+    # Check for other containers using our images and stop them
+    local ngen_containers=$(docker ps -q --filter "ancestor=$NGEN_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$ngen_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping NGEN containers..."
+        docker stop $ngen_containers >/dev/null 2>&1
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: Maybe add a period for these lines?
(There's several places that might be missing punctuation. I've added comments for all of them, but it's mostly a matter of taste, so stick with your own preference)
created_at: 2025-05-14T15:36:58Z
author_association: COLLABORATOR
diff_hunk: @@ -19,63 +24,242 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
 set -e
 
 CONFIG_FILE="$HOME/.host_data_path.conf"
 TETHYS_SCRIPT="./viewOnTethys.sh"
+TEEHR_SCRIPT="./runTeehr.sh"
+
+# Container and image constants
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_IMAGE_NAME="awiciroh/tethys-ngiab"
+TEEHR_IMAGE_NAME="awiciroh/ngiab-teehr"
+NGEN_IMAGE_NAME="awiciroh/ciroh-ngen-image"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB)\033[38;5;39m                                         ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mAdvanced Hydrologic Modeling Tool\033[38;5;39m                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Cleanup function for all resources
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Stop any running TEEHR containers
+    local teehr_containers=$(docker ps -q --filter "ancestor=$TEEHR_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$teehr_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $teehr_containers >/dev/null 2>&1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+    fi
+    
+    # Remove the Docker network
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1
+    fi
+    
+    # Check for other containers using our images and stop them
+    local ngen_containers=$(docker ps -q --filter "ancestor=$NGEN_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$ngen_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping NGEN containers..."
+        docker stop $ngen_containers >/dev/null 2>&1
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Set up trap for Ctrl-C and regular exit
+trap handle_sigint SIGINT
+trap clean_up_resources EXIT
+
+print_welcome_banner
+
+# Input data section with improved descriptions
+print_section_header "MODEL INPUT REQUIREMENTS"
 
-echo -e "\n========================================================="
-echo -e "${UWhite} Welcome to CIROH-UA:NextGen National Water Model App! ${Color_Off}"
-echo -e "=========================================================\n"
-echo -e "Looking for input data (a directory containing the following directories: forcings, config and outputs):\n"
-echo -e "${BBlue}forcings${Color_Off} is the hydrofabric input data for your model(s)."
-echo -e "${BGreen}config${Color_Off} folder has all the configuration related files for the model."
-echo -e "${BPurple}outputs${Color_Off} is where the output files are copied to when the model finish the run"
+echo -e "This application requires the following directory structure for proper operation:\n"
+echo -e "  ${ARROW} \033[38;5;33mforcings/\033[0m - Contains hydrofabric input data for model simulations"
+echo -e "          \033[38;5;117m└─ Meteorological and terrain data for hydrologic calculations\033[0m"
+echo -e "\n  ${ARROW} \033[38;5;35mconfig/\033[0m - Contains all configuration settings for the model"
+echo -e "          \033[38;5;117m└─ Model parameters, simulation period, and execution settings\033[0m"
+echo -e "\n  ${ARROW} \033[38;5;205moutputs/\033[0m - Target directory for simulation results"
+echo -e "          \033[38;5;117m└─ Flow estimates, water levels, and diagnostic information\033[0m"
 
-echo -e "\n"
+echo -e "\n${INFO_MARK} ${BWhite}Please specify a directory containing these components below.${Color_Off}\n"
 
-# Check if the config file exists and read from it
+# Path selection with improved user experience and fixed formatting
 if [ -f "$CONFIG_FILE" ]; then
     LAST_PATH=$(cat "$CONFIG_FILE")
-    echo -e "Last used data directory path: ${BBlue}$LAST_PATH${Color_Off}"
-    read -erp "Do you want to use the same path? (Y/n): " use_last_path
+    echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+    read -erp "  ${ARROW} Use the same path? [Y/n]: " use_last_path
     if [[ "$use_last_path" != [Nn]* ]]; then
         HOST_DATA_PATH=$LAST_PATH
+        echo -e "  ${CHECK_MARK} Using previously configured path"
     else
-        read -erp "Enter your input data directory path (use absolute path): " HOST_DATA_PATH
+        read -erp "  ${ARROW} Enter your input data directory path: " HOST_DATA_PATH
     fi
 else
-    read -erp "Enter your input data directory path (use absolute path): " HOST_DATA_PATH
+    echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+    read -erp "  ${ARROW} Enter your input data directory path: " HOST_DATA_PATH
 fi
 
-# Check the directory exists
+# Handle paths with special characters properly
+HOST_DATA_PATH=$(echo "$HOST_DATA_PATH" | sed 's/\\/\\\\/g')
+
+# Directory validation with visual feedback
 if [ ! -d "$HOST_DATA_PATH" ]; then
-  echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-  exit 0
+    handle_error "Directory does not exist: $HOST_DATA_PATH"
 fi
 
-# Save the new path to the config file
+# Save the new path
 echo "$HOST_DATA_PATH" > "$CONFIG_FILE"
-echo -e "The Directory you've given is:\n$HOST_DATA_PATH\n"
-# Function to validate directories
+echo -e "\n${CHECK_MARK} Configuration saved successfully"
+
+# Improved directory validation with progress indication
+print_section_header "VALIDATING INPUT DIRECTORY"
+echo -e "Checking directory structure at: ${BWhite}$HOST_DATA_PATH${Color_Off}\n"
+
+show_loading "Analyzing directory structure" 2
+
+# Function to validate directories with improved visual feedback
 validate_directory() {
     local dir=$1
     local name=$2
     local color=$3
+    local required=$4
 
+    # Add a small delay to make the process visible to the user
+    sleep 0.3
+    
+    echo -ne "  ${ARROW} Checking for ${color}${name}${Color_Off} directory... "
+    
     if [ -d "$dir" ]; then
-        local count=$(find $dir -type f | uniq | wc -l)
-        echo -e "${color}${name}${Color_Off} exists. $count ${name} found."
+        # Count files safely with proper error handling
+        local count=0
+        if [ -n "$(ls -A "$dir" 2>/dev/null)" ]; then
+            count=$(find "$dir" -type f 2>/dev/null | wc -l)
+        fi
+        
+        # Colorize the count based on number of files
+        if [ $count -eq 0 ]; then
+            echo -e "${CHECK_MARK} Found but ${BYellow}empty${Color_Off} (0 files)"
+        elif [ $count -lt 5 ]; then
+            echo -e "${CHECK_MARK} Found with ${BYellow}$count${Color_Off} files"
+        else
+            echo -e "${CHECK_MARK} Found with ${BGreen}$count${Color_Off} files"
+        fi
     else
-        echo -e "Error: Directory $dir does not exist."
+        if [ "$required" = "true" ]; then
+            echo -e "${CROSS_MARK} ${BRed}Missing required directory!${Color_Off}"
+            return 1
+        else
+            echo -e "${WARNING_MARK} ${BYellow}Not found (optional)${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: Something about this feels fragmented, somehow. Maybe something like this would work?
```suggestion
            echo -e "${WARNING_MARK} ${BYellow}Optional directory not found. Continuing...${Color_Off}"
```
created_at: 2025-05-14T15:42:30Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +271,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "\n${UYellow}Cleanup options for $folder_name:${Color_Off}"
```
created_at: 2025-05-14T15:46:39Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +271,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations!${Color_Off}"
```
A period would work, too
created_at: 2025-05-14T15:46:58Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +271,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: ```suggestion
                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files.${Color_Off}"
```
created_at: 2025-05-14T15:47:35Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +271,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
path: guide.sh
user: login: Sheargrub
body: ```suggestion
show_loading "Scanning for model files" 2...
```
created_at: 2025-05-14T15:47:48Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +271,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
 
-# File discovery
-echo -e "\nLooking in the provided directory gives us:"
 find_files() {
     local path=$1
     local name=$2
     local regex=$3
     local color=$4
 
-    local files=$(find "$path" -iname "$regex")
-    echo -e "${color}Found these $name files:${Color_Off}"
-    echo "$files" || echo "No $name files found."
+    echo -e "${ARROW} Searching for ${color}$name${Color_Off} files..."
+    
+    local files=$(find "$path" -iname "$regex" 2>/dev/null)
+    if [ -n "$files" ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Found $(echo "$files" | wc -l) files:${Color_Off}"
+        echo -e "  ${BCyan}$(echo "$files" | sed 's/^/    /')${Color_Off}"
+    else
+        echo -e "  ${WARNING_MARK} ${BYellow}No $name files found.${Color_Off}"
+    fi
 }
 
 find_files "$HOST_DATA_PATH" "hydrofabric" "*.gpkg" "$UGreen"
 find_files "$HOST_DATA_PATH" "realization" "realization.json" "$UGreen"
 
-# Detect Arch and Docker
-echo -e "\nDetected ISA = $(uname -a)"
-if docker --version ; then
-    echo "Docker found"
+# System detection with improved visuals
+print_section_header "SYSTEM CONFIGURATION"
+
+echo -e "${ARROW} ${BWhite}Hardware Detection:${Color_Off}"
+system_arch=$(uname -m)
+os_name=$(uname -s)
+
+echo -e "  ${INFO_MARK} Operating System: ${BCyan}$os_name${Color_Off}"
+echo -e "  ${INFO_MARK} Architecture: ${BCyan}$system_arch${Color_Off}"
+
+# Docker detection with better error handling
+echo -e "\n${ARROW} ${BWhite}Checking for Docker:${Color_Off}"
+if command -v docker >/dev/null 2>&1; then
+    docker_version=$(docker --version | cut -d' ' -f3 | sed 's/,//')
+    echo -e "  ${CHECK_MARK} Docker detected (version: ${BGreen}$docker_version${Color_Off})"
path: guide.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "  ${CHECK_MARK} Docker detected! (version: ${BGreen}$docker_version${Color_Off})"
```
(This one's extremely subjective)
created_at: 2025-05-14T15:49:47Z
author_association: COLLABORATOR
diff_hunk: @@ -19,63 +24,242 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
 set -e
 
 CONFIG_FILE="$HOME/.host_data_path.conf"
 TETHYS_SCRIPT="./viewOnTethys.sh"
+TEEHR_SCRIPT="./runTeehr.sh"
+
+# Container and image constants
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_IMAGE_NAME="awiciroh/tethys-ngiab"
+TEEHR_IMAGE_NAME="awiciroh/ngiab-teehr"
+NGEN_IMAGE_NAME="awiciroh/ciroh-ngen-image"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB)\033[38;5;39m                                         ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mAdvanced Hydrologic Modeling Tool\033[38;5;39m                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Cleanup function for all resources
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Stop any running TEEHR containers
+    local teehr_containers=$(docker ps -q --filter "ancestor=$TEEHR_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$teehr_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $teehr_containers >/dev/null 2>&1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+    fi
+    
+    # Remove the Docker network
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1
+    fi
+    
+    # Check for other containers using our images and stop them
+    local ngen_containers=$(docker ps -q --filter "ancestor=$NGEN_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$ngen_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping NGEN containers..."
+        docker stop $ngen_containers >/dev/null 2>&1
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: 
```suggestion
    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed.${Color_Off}"
```
created_at: 2025-05-14T15:53:41Z
author_association: COLLABORATOR
diff_hunk: @@ -19,63 +24,242 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
 set -e
 
 CONFIG_FILE="$HOME/.host_data_path.conf"
 TETHYS_SCRIPT="./viewOnTethys.sh"
+TEEHR_SCRIPT="./runTeehr.sh"
+
+# Container and image constants
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_IMAGE_NAME="awiciroh/tethys-ngiab"
+TEEHR_IMAGE_NAME="awiciroh/ngiab-teehr"
+NGEN_IMAGE_NAME="awiciroh/ciroh-ngen-image"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB)\033[38;5;39m                                         ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mAdvanced Hydrologic Modeling Tool\033[38;5;39m                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Cleanup function for all resources
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Stop any running TEEHR containers
+    local teehr_containers=$(docker ps -q --filter "ancestor=$TEEHR_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$teehr_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $teehr_containers >/dev/null 2>&1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+    fi
+    
+    # Remove the Docker network
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1
+    fi
+    
+    # Check for other containers using our images and stop them
+    local ngen_containers=$(docker ps -q --filter "ancestor=$NGEN_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$ngen_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping NGEN containers..."
+        docker stop $ngen_containers >/dev/null 2>&1
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: 
```suggestion
    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
```
created_at: 2025-05-14T16:22:50Z
author_association: COLLABORATOR
diff_hunk: @@ -19,63 +24,242 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
 set -e
 
 CONFIG_FILE="$HOME/.host_data_path.conf"
 TETHYS_SCRIPT="./viewOnTethys.sh"
+TEEHR_SCRIPT="./runTeehr.sh"
+
+# Container and image constants
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_IMAGE_NAME="awiciroh/tethys-ngiab"
+TEEHR_IMAGE_NAME="awiciroh/ngiab-teehr"
+NGEN_IMAGE_NAME="awiciroh/ciroh-ngen-image"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB)\033[38;5;39m                                         ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mAdvanced Hydrologic Modeling Tool\033[38;5;39m                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Cleanup function for all resources
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Stop any running TEEHR containers
+    local teehr_containers=$(docker ps -q --filter "ancestor=$TEEHR_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$teehr_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $teehr_containers >/dev/null 2>&1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+    fi
+    
+    # Remove the Docker network
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1
+    fi
+    
+    # Check for other containers using our images and stop them
+    local ngen_containers=$(docker ps -q --filter "ancestor=$NGEN_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$ngen_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping NGEN containers..."
+        docker stop $ngen_containers >/dev/null 2>&1
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Set up trap for Ctrl-C and regular exit
+trap handle_sigint SIGINT
+trap clean_up_resources EXIT
+
+print_welcome_banner
+
+# Input data section with improved descriptions
+print_section_header "MODEL INPUT REQUIREMENTS"
 
-echo -e "\n========================================================="
-echo -e "${UWhite} Welcome to CIROH-UA:NextGen National Water Model App! ${Color_Off}"
-echo -e "=========================================================\n"
-echo -e "Looking for input data (a directory containing the following directories: forcings, config and outputs):\n"
-echo -e "${BBlue}forcings${Color_Off} is the hydrofabric input data for your model(s)."
-echo -e "${BGreen}config${Color_Off} folder has all the configuration related files for the model."
-echo -e "${BPurple}outputs${Color_Off} is where the output files are copied to when the model finish the run"
+echo -e "This application requires the following directory structure for proper operation:\n"
+echo -e "  ${ARROW} \033[38;5;33mforcings/\033[0m - Contains hydrofabric input data for model simulations"
+echo -e "          \033[38;5;117m└─ Meteorological and terrain data for hydrologic calculations\033[0m"
+echo -e "\n  ${ARROW} \033[38;5;35mconfig/\033[0m - Contains all configuration settings for the model"
+echo -e "          \033[38;5;117m└─ Model parameters, simulation period, and execution settings\033[0m"
+echo -e "\n  ${ARROW} \033[38;5;205moutputs/\033[0m - Target directory for simulation results"
+echo -e "          \033[38;5;117m└─ Flow estimates, water levels, and diagnostic information\033[0m"
 
-echo -e "\n"
+echo -e "\n${INFO_MARK} ${BWhite}Please specify a directory containing these components below.${Color_Off}\n"
 
-# Check if the config file exists and read from it
+# Path selection with improved user experience and fixed formatting
 if [ -f "$CONFIG_FILE" ]; then
     LAST_PATH=$(cat "$CONFIG_FILE")
-    echo -e "Last used data directory path: ${BBlue}$LAST_PATH${Color_Off}"
-    read -erp "Do you want to use the same path? (Y/n): " use_last_path
+    echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+    read -erp "  ${ARROW} Use the same path? [Y/n]: " use_last_path
     if [[ "$use_last_path" != [Nn]* ]]; then
         HOST_DATA_PATH=$LAST_PATH
+        echo -e "  ${CHECK_MARK} Using previously configured path"
     else
-        read -erp "Enter your input data directory path (use absolute path): " HOST_DATA_PATH
+        read -erp "  ${ARROW} Enter your input data directory path: " HOST_DATA_PATH
     fi
 else
-    read -erp "Enter your input data directory path (use absolute path): " HOST_DATA_PATH
+    echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: 
```suggestion
    echo -e "${INFO_MARK} ${BYellow}No previous configuration found.${Color_Off}"
```
created_at: 2025-05-14T16:25:15Z
author_association: COLLABORATOR
diff_hunk: @@ -19,63 +24,242 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
 set -e
 
 CONFIG_FILE="$HOME/.host_data_path.conf"
 TETHYS_SCRIPT="./viewOnTethys.sh"
+TEEHR_SCRIPT="./runTeehr.sh"
+
+# Container and image constants
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_IMAGE_NAME="awiciroh/tethys-ngiab"
+TEEHR_IMAGE_NAME="awiciroh/ngiab-teehr"
+NGEN_IMAGE_NAME="awiciroh/ciroh-ngen-image"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB)\033[38;5;39m                                         ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mAdvanced Hydrologic Modeling Tool\033[38;5;39m                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Cleanup function for all resources
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Stop any running TEEHR containers
+    local teehr_containers=$(docker ps -q --filter "ancestor=$TEEHR_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$teehr_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $teehr_containers >/dev/null 2>&1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+    fi
+    
+    # Remove the Docker network
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1
+    fi
+    
+    # Check for other containers using our images and stop them
+    local ngen_containers=$(docker ps -q --filter "ancestor=$NGEN_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$ngen_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping NGEN containers..."
+        docker stop $ngen_containers >/dev/null 2>&1
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Set up trap for Ctrl-C and regular exit
+trap handle_sigint SIGINT
+trap clean_up_resources EXIT
+
+print_welcome_banner
+
+# Input data section with improved descriptions
+print_section_header "MODEL INPUT REQUIREMENTS"
 
-echo -e "\n========================================================="
-echo -e "${UWhite} Welcome to CIROH-UA:NextGen National Water Model App! ${Color_Off}"
-echo -e "=========================================================\n"
-echo -e "Looking for input data (a directory containing the following directories: forcings, config and outputs):\n"
-echo -e "${BBlue}forcings${Color_Off} is the hydrofabric input data for your model(s)."
-echo -e "${BGreen}config${Color_Off} folder has all the configuration related files for the model."
-echo -e "${BPurple}outputs${Color_Off} is where the output files are copied to when the model finish the run"
+echo -e "This application requires the following directory structure for proper operation:\n"
+echo -e "  ${ARROW} \033[38;5;33mforcings/\033[0m - Contains hydrofabric input data for model simulations"
+echo -e "          \033[38;5;117m└─ Meteorological and terrain data for hydrologic calculations\033[0m"
+echo -e "\n  ${ARROW} \033[38;5;35mconfig/\033[0m - Contains all configuration settings for the model"
+echo -e "          \033[38;5;117m└─ Model parameters, simulation period, and execution settings\033[0m"
+echo -e "\n  ${ARROW} \033[38;5;205moutputs/\033[0m - Target directory for simulation results"
+echo -e "          \033[38;5;117m└─ Flow estimates, water levels, and diagnostic information\033[0m"
 
-echo -e "\n"
+echo -e "\n${INFO_MARK} ${BWhite}Please specify a directory containing these components below.${Color_Off}\n"
 
-# Check if the config file exists and read from it
+# Path selection with improved user experience and fixed formatting
 if [ -f "$CONFIG_FILE" ]; then
     LAST_PATH=$(cat "$CONFIG_FILE")
-    echo -e "Last used data directory path: ${BBlue}$LAST_PATH${Color_Off}"
-    read -erp "Do you want to use the same path? (Y/n): " use_last_path
+    echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+    read -erp "  ${ARROW} Use the same path? [Y/n]: " use_last_path
     if [[ "$use_last_path" != [Nn]* ]]; then
         HOST_DATA_PATH=$LAST_PATH
+        echo -e "  ${CHECK_MARK} Using previously configured path"
     else
-        read -erp "Enter your input data directory path (use absolute path): " HOST_DATA_PATH
+        read -erp "  ${ARROW} Enter your input data directory path: " HOST_DATA_PATH
     fi
 else
-    read -erp "Enter your input data directory path (use absolute path): " HOST_DATA_PATH
+    echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+    read -erp "  ${ARROW} Enter your input data directory path: " HOST_DATA_PATH
 fi
 
-# Check the directory exists
+# Handle paths with special characters properly
+HOST_DATA_PATH=$(echo "$HOST_DATA_PATH" | sed 's/\\/\\\\/g')
+
+# Directory validation with visual feedback
 if [ ! -d "$HOST_DATA_PATH" ]; then
-  echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-  exit 0
+    handle_error "Directory does not exist: $HOST_DATA_PATH"
 fi
 
-# Save the new path to the config file
+# Save the new path
 echo "$HOST_DATA_PATH" > "$CONFIG_FILE"
-echo -e "The Directory you've given is:\n$HOST_DATA_PATH\n"
-# Function to validate directories
+echo -e "\n${CHECK_MARK} Configuration saved successfully"
+
+# Improved directory validation with progress indication
+print_section_header "VALIDATING INPUT DIRECTORY"
+echo -e "Checking directory structure at: ${BWhite}$HOST_DATA_PATH${Color_Off}\n"
+
+show_loading "Analyzing directory structure" 2
path: guide.sh
user: login: Sheargrub
body: 
```suggestion
show_loading "Analyzing directory structure..." 2
```
created_at: 2025-05-14T16:58:02Z
author_association: COLLABORATOR
diff_hunk: @@ -19,63 +24,242 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
 set -e
 
 CONFIG_FILE="$HOME/.host_data_path.conf"
 TETHYS_SCRIPT="./viewOnTethys.sh"
+TEEHR_SCRIPT="./runTeehr.sh"
+
+# Container and image constants
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_IMAGE_NAME="awiciroh/tethys-ngiab"
+TEEHR_IMAGE_NAME="awiciroh/ngiab-teehr"
+NGEN_IMAGE_NAME="awiciroh/ciroh-ngen-image"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB)\033[38;5;39m                                         ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mAdvanced Hydrologic Modeling Tool\033[38;5;39m                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Cleanup function for all resources
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Stop any running TEEHR containers
+    local teehr_containers=$(docker ps -q --filter "ancestor=$TEEHR_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$teehr_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $teehr_containers >/dev/null 2>&1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+    fi
+    
+    # Remove the Docker network
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1
+    fi
+    
+    # Check for other containers using our images and stop them
+    local ngen_containers=$(docker ps -q --filter "ancestor=$NGEN_IMAGE_NAME" 2>/dev/null)
+    if [ -n "$ngen_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping NGEN containers..."
+        docker stop $ngen_containers >/dev/null 2>&1
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Set up trap for Ctrl-C and regular exit
+trap handle_sigint SIGINT
+trap clean_up_resources EXIT
+
+print_welcome_banner
+
+# Input data section with improved descriptions
+print_section_header "MODEL INPUT REQUIREMENTS"
 
-echo -e "\n========================================================="
-echo -e "${UWhite} Welcome to CIROH-UA:NextGen National Water Model App! ${Color_Off}"
-echo -e "=========================================================\n"
-echo -e "Looking for input data (a directory containing the following directories: forcings, config and outputs):\n"
-echo -e "${BBlue}forcings${Color_Off} is the hydrofabric input data for your model(s)."
-echo -e "${BGreen}config${Color_Off} folder has all the configuration related files for the model."
-echo -e "${BPurple}outputs${Color_Off} is where the output files are copied to when the model finish the run"
+echo -e "This application requires the following directory structure for proper operation:\n"
+echo -e "  ${ARROW} \033[38;5;33mforcings/\033[0m - Contains hydrofabric input data for model simulations"
+echo -e "          \033[38;5;117m└─ Meteorological and terrain data for hydrologic calculations\033[0m"
+echo -e "\n  ${ARROW} \033[38;5;35mconfig/\033[0m - Contains all configuration settings for the model"
+echo -e "          \033[38;5;117m└─ Model parameters, simulation period, and execution settings\033[0m"
+echo -e "\n  ${ARROW} \033[38;5;205moutputs/\033[0m - Target directory for simulation results"
+echo -e "          \033[38;5;117m└─ Flow estimates, water levels, and diagnostic information\033[0m"
 
-echo -e "\n"
+echo -e "\n${INFO_MARK} ${BWhite}Please specify a directory containing these components below.${Color_Off}\n"
 
-# Check if the config file exists and read from it
+# Path selection with improved user experience and fixed formatting
 if [ -f "$CONFIG_FILE" ]; then
     LAST_PATH=$(cat "$CONFIG_FILE")
-    echo -e "Last used data directory path: ${BBlue}$LAST_PATH${Color_Off}"
-    read -erp "Do you want to use the same path? (Y/n): " use_last_path
+    echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+    read -erp "  ${ARROW} Use the same path? [Y/n]: " use_last_path
     if [[ "$use_last_path" != [Nn]* ]]; then
         HOST_DATA_PATH=$LAST_PATH
+        echo -e "  ${CHECK_MARK} Using previously configured path"
     else
-        read -erp "Enter your input data directory path (use absolute path): " HOST_DATA_PATH
+        read -erp "  ${ARROW} Enter your input data directory path: " HOST_DATA_PATH
     fi
 else
-    read -erp "Enter your input data directory path (use absolute path): " HOST_DATA_PATH
+    echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+    read -erp "  ${ARROW} Enter your input data directory path: " HOST_DATA_PATH
 fi
 
-# Check the directory exists
+# Handle paths with special characters properly
+HOST_DATA_PATH=$(echo "$HOST_DATA_PATH" | sed 's/\\/\\\\/g')
+
+# Directory validation with visual feedback
 if [ ! -d "$HOST_DATA_PATH" ]; then
-  echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-  exit 0
+    handle_error "Directory does not exist: $HOST_DATA_PATH"
 fi
 
-# Save the new path to the config file
+# Save the new path
 echo "$HOST_DATA_PATH" > "$CONFIG_FILE"
-echo -e "The Directory you've given is:\n$HOST_DATA_PATH\n"
-# Function to validate directories
+echo -e "\n${CHECK_MARK} Configuration saved successfully"
+
+# Improved directory validation with progress indication
+print_section_header "VALIDATING INPUT DIRECTORY"
+echo -e "Checking directory structure at: ${BWhite}$HOST_DATA_PATH${Color_Off}\n"
+
+show_loading "Analyzing directory structure" 2
+
+# Function to validate directories with improved visual feedback
 validate_directory() {
     local dir=$1
     local name=$2
     local color=$3
+    local required=$4
 
+    # Add a small delay to make the process visible to the user
+    sleep 0.3
+    
+    echo -ne "  ${ARROW} Checking for ${color}${name}${Color_Off} directory... "
+    
     if [ -d "$dir" ]; then
-        local count=$(find $dir -type f | uniq | wc -l)
-        echo -e "${color}${name}${Color_Off} exists. $count ${name} found."
+        # Count files safely with proper error handling
+        local count=0
+        if [ -n "$(ls -A "$dir" 2>/dev/null)" ]; then
+            count=$(find "$dir" -type f 2>/dev/null | wc -l)
+        fi
+        
+        # Colorize the count based on number of files
+        if [ $count -eq 0 ]; then
+            echo -e "${CHECK_MARK} Found but ${BYellow}empty${Color_Off} (0 files)"
+        elif [ $count -lt 5 ]; then
+            echo -e "${CHECK_MARK} Found with ${BYellow}$count${Color_Off} files"
+        else
+            echo -e "${CHECK_MARK} Found with ${BGreen}$count${Color_Off} files"
path: guide.sh
user: login: Sheargrub
body: 
```suggestion
            echo -e "${CHECK_MARK} Found but ${BYellow}empty${Color_Off}. (0 files)"
        elif [ $count -lt 5 ]; then
            echo -e "${CHECK_MARK} Found with ${BYellow}$count${Color_Off} files."
        else
            echo -e "${CHECK_MARK} Found with ${BGreen}$count${Color_Off} files."
```
created_at: 2025-05-14T16:59:20Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +275,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
 
-# File discovery
-echo -e "\nLooking in the provided directory gives us:"
 find_files() {
     local path=$1
     local name=$2
     local regex=$3
     local color=$4
 
-    local files=$(find "$path" -iname "$regex")
-    echo -e "${color}Found these $name files:${Color_Off}"
-    echo "$files" || echo "No $name files found."
+    echo -e "${ARROW} Searching for ${color}$name${Color_Off} files..."
+    
+    local files=$(find "$path" -iname "$regex" 2>/dev/null)
+    if [ -n "$files" ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Found $(echo "$files" | wc -l) files:${Color_Off}"
+        echo -e "  ${BCyan}$(echo "$files" | sed 's/^/    /')${Color_Off}"
+    else
+        echo -e "  ${WARNING_MARK} ${BYellow}No $name files found.${Color_Off}"
+    fi
 }
 
 find_files "$HOST_DATA_PATH" "hydrofabric" "*.gpkg" "$UGreen"
 find_files "$HOST_DATA_PATH" "realization" "realization.json" "$UGreen"
 
-# Detect Arch and Docker
-echo -e "\nDetected ISA = $(uname -a)"
-if docker --version ; then
-    echo "Docker found"
+# System detection with improved visuals
+print_section_header "SYSTEM CONFIGURATION"
+
+echo -e "${ARROW} ${BWhite}Hardware Detection:${Color_Off}"
+system_arch=$(uname -m)
+os_name=$(uname -s)
+
+echo -e "  ${INFO_MARK} Operating System: ${BCyan}$os_name${Color_Off}"
+echo -e "  ${INFO_MARK} Architecture: ${BCyan}$system_arch${Color_Off}"
+
+# Docker detection with better error handling
+echo -e "\n${ARROW} ${BWhite}Checking for Docker:${Color_Off}"
+if command -v docker >/dev/null 2>&1; then
+    docker_version=$(docker --version | cut -d' ' -f3 | sed 's/,//')
+    echo -e "  ${CHECK_MARK} Docker detected (version: ${BGreen}$docker_version${Color_Off})"
 else
-    echo "Docker not found"
+    handle_error "Docker not found. This script requires Docker to run the NextGen model."
 fi
 
-IMAGE_NAME=awiciroh/ciroh-ngen-image:latest
+IMAGE_NAME=$NGEN_IMAGE_NAME:latest
+
+# Model run options with improved visuals
+print_section_header "MODEL EXECUTION OPTIONS"
 
-# Model run options
-echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-options=("Run NextGen using existing local docker image" "Run NextGen after updating to latest docker image" "Exit")
+echo -e "${ARROW} ${BWhite}Please select an option to proceed:${Color_Off}\n"
+options=("Run NextGen using existing local docker image" "Update to latest docker image and run" "Exit")
 select option in "${options[@]}"; do
     case $option in
         "Run NextGen using existing local docker image")
-            echo "running the model"
+            echo -e "\n${CHECK_MARK} ${BGreen}Using existing Docker image${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: ```
            echo -e "\n${CHECK_MARK} ${BGreen}Using existing Docker image.${Color_Off}"
```
created_at: 2025-05-14T17:20:26Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +275,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
 
-# File discovery
-echo -e "\nLooking in the provided directory gives us:"
 find_files() {
     local path=$1
     local name=$2
     local regex=$3
     local color=$4
 
-    local files=$(find "$path" -iname "$regex")
-    echo -e "${color}Found these $name files:${Color_Off}"
-    echo "$files" || echo "No $name files found."
+    echo -e "${ARROW} Searching for ${color}$name${Color_Off} files..."
+    
+    local files=$(find "$path" -iname "$regex" 2>/dev/null)
+    if [ -n "$files" ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Found $(echo "$files" | wc -l) files:${Color_Off}"
+        echo -e "  ${BCyan}$(echo "$files" | sed 's/^/    /')${Color_Off}"
+    else
+        echo -e "  ${WARNING_MARK} ${BYellow}No $name files found.${Color_Off}"
+    fi
 }
 
 find_files "$HOST_DATA_PATH" "hydrofabric" "*.gpkg" "$UGreen"
 find_files "$HOST_DATA_PATH" "realization" "realization.json" "$UGreen"
 
-# Detect Arch and Docker
-echo -e "\nDetected ISA = $(uname -a)"
-if docker --version ; then
-    echo "Docker found"
+# System detection with improved visuals
+print_section_header "SYSTEM CONFIGURATION"
+
+echo -e "${ARROW} ${BWhite}Hardware Detection:${Color_Off}"
+system_arch=$(uname -m)
+os_name=$(uname -s)
+
+echo -e "  ${INFO_MARK} Operating System: ${BCyan}$os_name${Color_Off}"
+echo -e "  ${INFO_MARK} Architecture: ${BCyan}$system_arch${Color_Off}"
+
+# Docker detection with better error handling
+echo -e "\n${ARROW} ${BWhite}Checking for Docker:${Color_Off}"
+if command -v docker >/dev/null 2>&1; then
+    docker_version=$(docker --version | cut -d' ' -f3 | sed 's/,//')
+    echo -e "  ${CHECK_MARK} Docker detected (version: ${BGreen}$docker_version${Color_Off})"
 else
-    echo "Docker not found"
+    handle_error "Docker not found. This script requires Docker to run the NextGen model."
 fi
 
-IMAGE_NAME=awiciroh/ciroh-ngen-image:latest
+IMAGE_NAME=$NGEN_IMAGE_NAME:latest
+
+# Model run options with improved visuals
+print_section_header "MODEL EXECUTION OPTIONS"
 
-# Model run options
-echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-options=("Run NextGen using existing local docker image" "Run NextGen after updating to latest docker image" "Exit")
+echo -e "${ARROW} ${BWhite}Please select an option to proceed:${Color_Off}\n"
+options=("Run NextGen using existing local docker image" "Update to latest docker image and run" "Exit")
 select option in "${options[@]}"; do
     case $option in
         "Run NextGen using existing local docker image")
-            echo "running the model"
+            echo -e "\n${CHECK_MARK} ${BGreen}Using existing Docker image${Color_Off}"
             break
             ;;
-        "Run NextGen after updating to latest docker image")
-            echo "pulling container and running the model"
+        "Update to latest docker image and run")
+            echo -e "\n${ARROW} ${BYellow}Updating Docker image...${Color_Off}"
+            show_loading "Downloading latest NextGen image" 3
path: guide.sh
user: login: Sheargrub
body: ```suggestion
            echo -e "\n${ARROW} ${BYellow}Updating Docker image.${Color_Off}"
            show_loading "Downloading latest NextGen image..." 3
```
created_at: 2025-05-14T17:22:27Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +275,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
 
-# File discovery
-echo -e "\nLooking in the provided directory gives us:"
 find_files() {
     local path=$1
     local name=$2
     local regex=$3
     local color=$4
 
-    local files=$(find "$path" -iname "$regex")
-    echo -e "${color}Found these $name files:${Color_Off}"
-    echo "$files" || echo "No $name files found."
+    echo -e "${ARROW} Searching for ${color}$name${Color_Off} files..."
+    
+    local files=$(find "$path" -iname "$regex" 2>/dev/null)
+    if [ -n "$files" ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Found $(echo "$files" | wc -l) files:${Color_Off}"
+        echo -e "  ${BCyan}$(echo "$files" | sed 's/^/    /')${Color_Off}"
+    else
+        echo -e "  ${WARNING_MARK} ${BYellow}No $name files found.${Color_Off}"
+    fi
 }
 
 find_files "$HOST_DATA_PATH" "hydrofabric" "*.gpkg" "$UGreen"
 find_files "$HOST_DATA_PATH" "realization" "realization.json" "$UGreen"
 
-# Detect Arch and Docker
-echo -e "\nDetected ISA = $(uname -a)"
-if docker --version ; then
-    echo "Docker found"
+# System detection with improved visuals
+print_section_header "SYSTEM CONFIGURATION"
+
+echo -e "${ARROW} ${BWhite}Hardware Detection:${Color_Off}"
+system_arch=$(uname -m)
+os_name=$(uname -s)
+
+echo -e "  ${INFO_MARK} Operating System: ${BCyan}$os_name${Color_Off}"
+echo -e "  ${INFO_MARK} Architecture: ${BCyan}$system_arch${Color_Off}"
+
+# Docker detection with better error handling
+echo -e "\n${ARROW} ${BWhite}Checking for Docker:${Color_Off}"
+if command -v docker >/dev/null 2>&1; then
+    docker_version=$(docker --version | cut -d' ' -f3 | sed 's/,//')
+    echo -e "  ${CHECK_MARK} Docker detected (version: ${BGreen}$docker_version${Color_Off})"
 else
-    echo "Docker not found"
+    handle_error "Docker not found. This script requires Docker to run the NextGen model."
 fi
 
-IMAGE_NAME=awiciroh/ciroh-ngen-image:latest
+IMAGE_NAME=$NGEN_IMAGE_NAME:latest
+
+# Model run options with improved visuals
+print_section_header "MODEL EXECUTION OPTIONS"
 
-# Model run options
-echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-options=("Run NextGen using existing local docker image" "Run NextGen after updating to latest docker image" "Exit")
+echo -e "${ARROW} ${BWhite}Please select an option to proceed:${Color_Off}\n"
+options=("Run NextGen using existing local docker image" "Update to latest docker image and run" "Exit")
 select option in "${options[@]}"; do
     case $option in
         "Run NextGen using existing local docker image")
-            echo "running the model"
+            echo -e "\n${CHECK_MARK} ${BGreen}Using existing Docker image${Color_Off}"
             break
             ;;
-        "Run NextGen after updating to latest docker image")
-            echo "pulling container and running the model"
+        "Update to latest docker image and run")
+            echo -e "\n${ARROW} ${BYellow}Updating Docker image...${Color_Off}"
+            show_loading "Downloading latest NextGen image" 3
             docker pull $IMAGE_NAME
+            echo -e "${CHECK_MARK} ${BGreen}Docker image updated successfully${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: ```suggestion
            echo -e "${CHECK_MARK} ${BGreen}Docker image updated successfully!${Color_Off}"
```
created_at: 2025-05-14T17:22:39Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +275,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
 
-# File discovery
-echo -e "\nLooking in the provided directory gives us:"
 find_files() {
     local path=$1
     local name=$2
     local regex=$3
     local color=$4
 
-    local files=$(find "$path" -iname "$regex")
-    echo -e "${color}Found these $name files:${Color_Off}"
-    echo "$files" || echo "No $name files found."
+    echo -e "${ARROW} Searching for ${color}$name${Color_Off} files..."
+    
+    local files=$(find "$path" -iname "$regex" 2>/dev/null)
+    if [ -n "$files" ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Found $(echo "$files" | wc -l) files:${Color_Off}"
+        echo -e "  ${BCyan}$(echo "$files" | sed 's/^/    /')${Color_Off}"
+    else
+        echo -e "  ${WARNING_MARK} ${BYellow}No $name files found.${Color_Off}"
+    fi
 }
 
 find_files "$HOST_DATA_PATH" "hydrofabric" "*.gpkg" "$UGreen"
 find_files "$HOST_DATA_PATH" "realization" "realization.json" "$UGreen"
 
-# Detect Arch and Docker
-echo -e "\nDetected ISA = $(uname -a)"
-if docker --version ; then
-    echo "Docker found"
+# System detection with improved visuals
+print_section_header "SYSTEM CONFIGURATION"
+
+echo -e "${ARROW} ${BWhite}Hardware Detection:${Color_Off}"
+system_arch=$(uname -m)
+os_name=$(uname -s)
+
+echo -e "  ${INFO_MARK} Operating System: ${BCyan}$os_name${Color_Off}"
+echo -e "  ${INFO_MARK} Architecture: ${BCyan}$system_arch${Color_Off}"
+
+# Docker detection with better error handling
+echo -e "\n${ARROW} ${BWhite}Checking for Docker:${Color_Off}"
+if command -v docker >/dev/null 2>&1; then
+    docker_version=$(docker --version | cut -d' ' -f3 | sed 's/,//')
+    echo -e "  ${CHECK_MARK} Docker detected (version: ${BGreen}$docker_version${Color_Off})"
 else
-    echo "Docker not found"
+    handle_error "Docker not found. This script requires Docker to run the NextGen model."
 fi
 
-IMAGE_NAME=awiciroh/ciroh-ngen-image:latest
+IMAGE_NAME=$NGEN_IMAGE_NAME:latest
+
+# Model run options with improved visuals
+print_section_header "MODEL EXECUTION OPTIONS"
 
-# Model run options
-echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-options=("Run NextGen using existing local docker image" "Run NextGen after updating to latest docker image" "Exit")
+echo -e "${ARROW} ${BWhite}Please select an option to proceed:${Color_Off}\n"
+options=("Run NextGen using existing local docker image" "Update to latest docker image and run" "Exit")
 select option in "${options[@]}"; do
     case $option in
         "Run NextGen using existing local docker image")
-            echo "running the model"
+            echo -e "\n${CHECK_MARK} ${BGreen}Using existing Docker image${Color_Off}"
             break
             ;;
-        "Run NextGen after updating to latest docker image")
-            echo "pulling container and running the model"
+        "Update to latest docker image and run")
+            echo -e "\n${ARROW} ${BYellow}Updating Docker image...${Color_Off}"
+            show_loading "Downloading latest NextGen image" 3
             docker pull $IMAGE_NAME
+            echo -e "${CHECK_MARK} ${BGreen}Docker image updated successfully${Color_Off}"
             break
             ;;
-        Exit)
-            echo "Have a nice day!"
+        "Exit")
+            echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
             exit 0
             ;;
-        *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
+        *) echo -e "${CROSS_MARK} ${BRed}Invalid option $REPLY. Please try again.${Color_Off}"
             ;;
     esac
 done
 
+# Running model with improved progress indicators
+print_section_header "RUNNING NEXTGEN MODEL SIMULATION"
+
+echo -e "${ARROW} ${BWhite}Preparing to run NextGen model...${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Local directory: ${BWhite}$HOST_DATA_PATH${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Container directory: ${BWhite}/ngen/ngen/data${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Docker image: ${BWhite}$IMAGE_NAME${Color_Off}"
+
+# Pause for visual confirmation
+sleep 2
 
-echo -e "\nRunning NextGen docker container..."
-echo -e "Mounting local host directory $HOST_DATA_PATH to /ngen/ngen/data within the container."
+echo -e "\n${ARROW} ${BYellow}Launching NextGen container...${Color_Off}"
 docker run --rm -it -v "$HOST_DATA_PATH:/ngen/ngen/data" "$IMAGE_NAME" /ngen/ngen/data/
 
-# Final output count
+# Final output count with improved presentation
+print_section_header "SIMULATION RESULTS"
+
 Final_Outputs_Count=$(find "$HOST_DATA_PATH/outputs/" -type f | wc -l)
-echo -e "$Final_Outputs_Count new outputs created."
-echo -e "Any copied files can be found here: $HOST_DATA_PATH/outputs"
-
-# ============ Run TEEHR ============
-# TODO: Support for ARM64
-# if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# else
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# fi
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
+
+if [ $Final_Outputs_Count -gt 0 ]; then
+    echo -e "${CHECK_MARK} ${BGreen}Simulation completed successfully!${Color_Off}"
+    echo -e "  ${INFO_MARK} ${BWhite}$Final_Outputs_Count${Color_Off} output files generated"
path: guide.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "  ${INFO_MARK} ${BWhite}$Final_Outputs_Count${Color_Off} output files generated."
```
created_at: 2025-05-14T17:23:03Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +275,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
 
-# File discovery
-echo -e "\nLooking in the provided directory gives us:"
 find_files() {
     local path=$1
     local name=$2
     local regex=$3
     local color=$4
 
-    local files=$(find "$path" -iname "$regex")
-    echo -e "${color}Found these $name files:${Color_Off}"
-    echo "$files" || echo "No $name files found."
+    echo -e "${ARROW} Searching for ${color}$name${Color_Off} files..."
+    
+    local files=$(find "$path" -iname "$regex" 2>/dev/null)
+    if [ -n "$files" ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Found $(echo "$files" | wc -l) files:${Color_Off}"
+        echo -e "  ${BCyan}$(echo "$files" | sed 's/^/    /')${Color_Off}"
+    else
+        echo -e "  ${WARNING_MARK} ${BYellow}No $name files found.${Color_Off}"
+    fi
 }
 
 find_files "$HOST_DATA_PATH" "hydrofabric" "*.gpkg" "$UGreen"
 find_files "$HOST_DATA_PATH" "realization" "realization.json" "$UGreen"
 
-# Detect Arch and Docker
-echo -e "\nDetected ISA = $(uname -a)"
-if docker --version ; then
-    echo "Docker found"
+# System detection with improved visuals
+print_section_header "SYSTEM CONFIGURATION"
+
+echo -e "${ARROW} ${BWhite}Hardware Detection:${Color_Off}"
+system_arch=$(uname -m)
+os_name=$(uname -s)
+
+echo -e "  ${INFO_MARK} Operating System: ${BCyan}$os_name${Color_Off}"
+echo -e "  ${INFO_MARK} Architecture: ${BCyan}$system_arch${Color_Off}"
+
+# Docker detection with better error handling
+echo -e "\n${ARROW} ${BWhite}Checking for Docker:${Color_Off}"
+if command -v docker >/dev/null 2>&1; then
+    docker_version=$(docker --version | cut -d' ' -f3 | sed 's/,//')
+    echo -e "  ${CHECK_MARK} Docker detected (version: ${BGreen}$docker_version${Color_Off})"
 else
-    echo "Docker not found"
+    handle_error "Docker not found. This script requires Docker to run the NextGen model."
 fi
 
-IMAGE_NAME=awiciroh/ciroh-ngen-image:latest
+IMAGE_NAME=$NGEN_IMAGE_NAME:latest
+
+# Model run options with improved visuals
+print_section_header "MODEL EXECUTION OPTIONS"
 
-# Model run options
-echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-options=("Run NextGen using existing local docker image" "Run NextGen after updating to latest docker image" "Exit")
+echo -e "${ARROW} ${BWhite}Please select an option to proceed:${Color_Off}\n"
+options=("Run NextGen using existing local docker image" "Update to latest docker image and run" "Exit")
 select option in "${options[@]}"; do
     case $option in
         "Run NextGen using existing local docker image")
-            echo "running the model"
+            echo -e "\n${CHECK_MARK} ${BGreen}Using existing Docker image${Color_Off}"
             break
             ;;
-        "Run NextGen after updating to latest docker image")
-            echo "pulling container and running the model"
+        "Update to latest docker image and run")
+            echo -e "\n${ARROW} ${BYellow}Updating Docker image...${Color_Off}"
+            show_loading "Downloading latest NextGen image" 3
             docker pull $IMAGE_NAME
+            echo -e "${CHECK_MARK} ${BGreen}Docker image updated successfully${Color_Off}"
             break
             ;;
-        Exit)
-            echo "Have a nice day!"
+        "Exit")
+            echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
             exit 0
             ;;
-        *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
+        *) echo -e "${CROSS_MARK} ${BRed}Invalid option $REPLY. Please try again.${Color_Off}"
             ;;
     esac
 done
 
+# Running model with improved progress indicators
+print_section_header "RUNNING NEXTGEN MODEL SIMULATION"
+
+echo -e "${ARROW} ${BWhite}Preparing to run NextGen model...${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Local directory: ${BWhite}$HOST_DATA_PATH${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Container directory: ${BWhite}/ngen/ngen/data${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Docker image: ${BWhite}$IMAGE_NAME${Color_Off}"
+
+# Pause for visual confirmation
+sleep 2
 
-echo -e "\nRunning NextGen docker container..."
-echo -e "Mounting local host directory $HOST_DATA_PATH to /ngen/ngen/data within the container."
+echo -e "\n${ARROW} ${BYellow}Launching NextGen container...${Color_Off}"
 docker run --rm -it -v "$HOST_DATA_PATH:/ngen/ngen/data" "$IMAGE_NAME" /ngen/ngen/data/
 
-# Final output count
+# Final output count with improved presentation
+print_section_header "SIMULATION RESULTS"
+
 Final_Outputs_Count=$(find "$HOST_DATA_PATH/outputs/" -type f | wc -l)
-echo -e "$Final_Outputs_Count new outputs created."
-echo -e "Any copied files can be found here: $HOST_DATA_PATH/outputs"
-
-# ============ Run TEEHR ============
-# TODO: Support for ARM64
-# if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# else
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# fi
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
+
+if [ $Final_Outputs_Count -gt 0 ]; then
+    echo -e "${CHECK_MARK} ${BGreen}Simulation completed successfully!${Color_Off}"
+    echo -e "  ${INFO_MARK} ${BWhite}$Final_Outputs_Count${Color_Off} output files generated"
+    echo -e "  ${INFO_MARK} Results stored in: ${BWhite}$HOST_DATA_PATH/outputs${Color_Off}"
+else
+    echo -e "${WARNING_MARK} ${BYellow}No output files were generated.${Color_Off}"
+    echo -e "  ${INFO_MARK} Please check the simulation configuration and try again."
+fi
+
+# ============ Run TEEHR using the runTeehr.sh script ============
+if [ $Final_Outputs_Count -gt 0 ]; then
+    print_section_header "EVALUATION OPTIONS"
+    
+    echo -e "${ARROW} ${BWhite}Would you like to run a TEEHR evaluation on the output?${Color_Off}"
+    echo -e "  ${INFO_MARK} This will analyze your simulation results using the TEEHR toolkit"
path: guide.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "  ${INFO_MARK} This will analyze your simulation results using the TEEHR toolkit."
```
created_at: 2025-05-14T17:23:19Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +275,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
 
-# File discovery
-echo -e "\nLooking in the provided directory gives us:"
 find_files() {
     local path=$1
     local name=$2
     local regex=$3
     local color=$4
 
-    local files=$(find "$path" -iname "$regex")
-    echo -e "${color}Found these $name files:${Color_Off}"
-    echo "$files" || echo "No $name files found."
+    echo -e "${ARROW} Searching for ${color}$name${Color_Off} files..."
+    
+    local files=$(find "$path" -iname "$regex" 2>/dev/null)
+    if [ -n "$files" ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Found $(echo "$files" | wc -l) files:${Color_Off}"
+        echo -e "  ${BCyan}$(echo "$files" | sed 's/^/    /')${Color_Off}"
+    else
+        echo -e "  ${WARNING_MARK} ${BYellow}No $name files found.${Color_Off}"
+    fi
 }
 
 find_files "$HOST_DATA_PATH" "hydrofabric" "*.gpkg" "$UGreen"
 find_files "$HOST_DATA_PATH" "realization" "realization.json" "$UGreen"
 
-# Detect Arch and Docker
-echo -e "\nDetected ISA = $(uname -a)"
-if docker --version ; then
-    echo "Docker found"
+# System detection with improved visuals
+print_section_header "SYSTEM CONFIGURATION"
+
+echo -e "${ARROW} ${BWhite}Hardware Detection:${Color_Off}"
+system_arch=$(uname -m)
+os_name=$(uname -s)
+
+echo -e "  ${INFO_MARK} Operating System: ${BCyan}$os_name${Color_Off}"
+echo -e "  ${INFO_MARK} Architecture: ${BCyan}$system_arch${Color_Off}"
+
+# Docker detection with better error handling
+echo -e "\n${ARROW} ${BWhite}Checking for Docker:${Color_Off}"
+if command -v docker >/dev/null 2>&1; then
+    docker_version=$(docker --version | cut -d' ' -f3 | sed 's/,//')
+    echo -e "  ${CHECK_MARK} Docker detected (version: ${BGreen}$docker_version${Color_Off})"
 else
-    echo "Docker not found"
+    handle_error "Docker not found. This script requires Docker to run the NextGen model."
 fi
 
-IMAGE_NAME=awiciroh/ciroh-ngen-image:latest
+IMAGE_NAME=$NGEN_IMAGE_NAME:latest
+
+# Model run options with improved visuals
+print_section_header "MODEL EXECUTION OPTIONS"
 
-# Model run options
-echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-options=("Run NextGen using existing local docker image" "Run NextGen after updating to latest docker image" "Exit")
+echo -e "${ARROW} ${BWhite}Please select an option to proceed:${Color_Off}\n"
+options=("Run NextGen using existing local docker image" "Update to latest docker image and run" "Exit")
 select option in "${options[@]}"; do
     case $option in
         "Run NextGen using existing local docker image")
-            echo "running the model"
+            echo -e "\n${CHECK_MARK} ${BGreen}Using existing Docker image${Color_Off}"
             break
             ;;
-        "Run NextGen after updating to latest docker image")
-            echo "pulling container and running the model"
+        "Update to latest docker image and run")
+            echo -e "\n${ARROW} ${BYellow}Updating Docker image...${Color_Off}"
+            show_loading "Downloading latest NextGen image" 3
             docker pull $IMAGE_NAME
+            echo -e "${CHECK_MARK} ${BGreen}Docker image updated successfully${Color_Off}"
             break
             ;;
-        Exit)
-            echo "Have a nice day!"
+        "Exit")
+            echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
             exit 0
             ;;
-        *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
+        *) echo -e "${CROSS_MARK} ${BRed}Invalid option $REPLY. Please try again.${Color_Off}"
             ;;
     esac
 done
 
+# Running model with improved progress indicators
+print_section_header "RUNNING NEXTGEN MODEL SIMULATION"
+
+echo -e "${ARROW} ${BWhite}Preparing to run NextGen model...${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Local directory: ${BWhite}$HOST_DATA_PATH${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Container directory: ${BWhite}/ngen/ngen/data${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Docker image: ${BWhite}$IMAGE_NAME${Color_Off}"
+
+# Pause for visual confirmation
+sleep 2
 
-echo -e "\nRunning NextGen docker container..."
-echo -e "Mounting local host directory $HOST_DATA_PATH to /ngen/ngen/data within the container."
+echo -e "\n${ARROW} ${BYellow}Launching NextGen container...${Color_Off}"
 docker run --rm -it -v "$HOST_DATA_PATH:/ngen/ngen/data" "$IMAGE_NAME" /ngen/ngen/data/
 
-# Final output count
+# Final output count with improved presentation
+print_section_header "SIMULATION RESULTS"
+
 Final_Outputs_Count=$(find "$HOST_DATA_PATH/outputs/" -type f | wc -l)
-echo -e "$Final_Outputs_Count new outputs created."
-echo -e "Any copied files can be found here: $HOST_DATA_PATH/outputs"
-
-# ============ Run TEEHR ============
-# TODO: Support for ARM64
-# if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# else
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# fi
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
+
+if [ $Final_Outputs_Count -gt 0 ]; then
+    echo -e "${CHECK_MARK} ${BGreen}Simulation completed successfully!${Color_Off}"
+    echo -e "  ${INFO_MARK} ${BWhite}$Final_Outputs_Count${Color_Off} output files generated"
+    echo -e "  ${INFO_MARK} Results stored in: ${BWhite}$HOST_DATA_PATH/outputs${Color_Off}"
+else
+    echo -e "${WARNING_MARK} ${BYellow}No output files were generated.${Color_Off}"
+    echo -e "  ${INFO_MARK} Please check the simulation configuration and try again."
+fi
+
+# ============ Run TEEHR using the runTeehr.sh script ============
+if [ $Final_Outputs_Count -gt 0 ]; then
+    print_section_header "EVALUATION OPTIONS"
+    
+    echo -e "${ARROW} ${BWhite}Would you like to run a TEEHR evaluation on the output?${Color_Off}"
+    echo -e "  ${INFO_MARK} This will analyze your simulation results using the TEEHR toolkit"
+    echo -e "  ${INFO_MARK} Learn more: ${UBlue}https://rtiinternational.github.io/ngiab-teehr/${Color_Off}\n"
+    
+    read -erp "  Run TEEHR evaluation? [Y/n]: " run_teehr_choice
+    
     # Default to 'y' if input is empty
     if [[ -z "$run_teehr_choice" ]]; then
         run_teehr_choice="y"
     fi
-    # Check for valid input
-    if [[ "$run_teehr_choice" == [YyNn]* ]]; then
-        break
+    
+    # Execute TEEHR if requested
+    if [[ "$run_teehr_choice" == [Yy]* ]]; then
+        # Check if the runTeehr.sh script exists
+        if [ -f "$TEEHR_SCRIPT" ]; then
+            echo -e "\n${INFO_MARK} ${BWhite}Launching TEEHR evaluation...${Color_Off}"
+            
+            # Make sure the script is executable
+            if [ ! -x "$TEEHR_SCRIPT" ]; then
+                chmod +x "$TEEHR_SCRIPT"
+            fi
+            
+            # Call the runTeehr.sh script with the data path
+            if ! "$TEEHR_SCRIPT" "$HOST_DATA_PATH"; then
+                echo -e "\n${WARNING_MARK} ${BRed}Failed to run TEEHR evaluation.${Color_Off}"
+                echo -e "  ${INFO_MARK} Check that the runTeehr.sh script is properly configured."
+            fi
+        else
+            echo -e "\n${WARNING_MARK} ${BRed}Could not find the TEEHR evaluation script.${Color_Off}"
+            echo -e "  ${INFO_MARK} Expected location: ${BWhite}$TEEHR_SCRIPT${Color_Off}"
+            echo -e "  ${INFO_MARK} Please make sure the script is in the current directory."
+            
+            # Fallback to inline TEEHR execution
+            echo -e "\n${INFO_MARK} ${BYellow}Falling back to embedded TEEHR evaluation...${Color_Off}"
+            
+            # Detect architecture for default tag
+            if uname -a | grep -q 'arm64\|aarch64'; then
+                default_tag="latest"
+            else
+                default_tag="x86"
+            fi
+            
+            echo -e "  ${INFO_MARK} Detected architecture: ${BCyan}$(uname -m)${Color_Off} (default tag: ${BCyan}$default_tag${Color_Off})"
+            read -erp "  ${ARROW} Specify TEEHR image tag [default: '$default_tag']: " teehr_image_tag
+            
+            if [[ -z "$teehr_image_tag" ]]; then
+                teehr_image_tag=$default_tag
+            fi
+            
+            IMAGE_NAME=$TEEHR_IMAGE_NAME
+            
+            print_section_header "RUNNING TEEHR EVALUATION"
+            
+            echo -e "${ARROW} ${BYellow}Launching TEEHR evaluation...${Color_Off}\n"
+            docker run -v "$HOST_DATA_PATH:/app/data" "$IMAGE_NAME:$teehr_image_tag"
+            
+            echo -e "\n${BG_Green}${BWhite} TEEHR EVALUATION COMPLETE ${Color_Off}"
+            echo -e "${INFO_MARK} ${BCyan}Results have been saved to your output directory${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: ```suggestion
            echo -e "${INFO_MARK} ${BCyan}Results have been saved to your output directory.${Color_Off}"
```
created_at: 2025-05-14T17:23:43Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +275,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
 
-# File discovery
-echo -e "\nLooking in the provided directory gives us:"
 find_files() {
     local path=$1
     local name=$2
     local regex=$3
     local color=$4
 
-    local files=$(find "$path" -iname "$regex")
-    echo -e "${color}Found these $name files:${Color_Off}"
-    echo "$files" || echo "No $name files found."
+    echo -e "${ARROW} Searching for ${color}$name${Color_Off} files..."
+    
+    local files=$(find "$path" -iname "$regex" 2>/dev/null)
+    if [ -n "$files" ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Found $(echo "$files" | wc -l) files:${Color_Off}"
+        echo -e "  ${BCyan}$(echo "$files" | sed 's/^/    /')${Color_Off}"
+    else
+        echo -e "  ${WARNING_MARK} ${BYellow}No $name files found.${Color_Off}"
+    fi
 }
 
 find_files "$HOST_DATA_PATH" "hydrofabric" "*.gpkg" "$UGreen"
 find_files "$HOST_DATA_PATH" "realization" "realization.json" "$UGreen"
 
-# Detect Arch and Docker
-echo -e "\nDetected ISA = $(uname -a)"
-if docker --version ; then
-    echo "Docker found"
+# System detection with improved visuals
+print_section_header "SYSTEM CONFIGURATION"
+
+echo -e "${ARROW} ${BWhite}Hardware Detection:${Color_Off}"
+system_arch=$(uname -m)
+os_name=$(uname -s)
+
+echo -e "  ${INFO_MARK} Operating System: ${BCyan}$os_name${Color_Off}"
+echo -e "  ${INFO_MARK} Architecture: ${BCyan}$system_arch${Color_Off}"
+
+# Docker detection with better error handling
+echo -e "\n${ARROW} ${BWhite}Checking for Docker:${Color_Off}"
+if command -v docker >/dev/null 2>&1; then
+    docker_version=$(docker --version | cut -d' ' -f3 | sed 's/,//')
+    echo -e "  ${CHECK_MARK} Docker detected (version: ${BGreen}$docker_version${Color_Off})"
 else
-    echo "Docker not found"
+    handle_error "Docker not found. This script requires Docker to run the NextGen model."
 fi
 
-IMAGE_NAME=awiciroh/ciroh-ngen-image:latest
+IMAGE_NAME=$NGEN_IMAGE_NAME:latest
+
+# Model run options with improved visuals
+print_section_header "MODEL EXECUTION OPTIONS"
 
-# Model run options
-echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-options=("Run NextGen using existing local docker image" "Run NextGen after updating to latest docker image" "Exit")
+echo -e "${ARROW} ${BWhite}Please select an option to proceed:${Color_Off}\n"
+options=("Run NextGen using existing local docker image" "Update to latest docker image and run" "Exit")
 select option in "${options[@]}"; do
     case $option in
         "Run NextGen using existing local docker image")
-            echo "running the model"
+            echo -e "\n${CHECK_MARK} ${BGreen}Using existing Docker image${Color_Off}"
             break
             ;;
-        "Run NextGen after updating to latest docker image")
-            echo "pulling container and running the model"
+        "Update to latest docker image and run")
+            echo -e "\n${ARROW} ${BYellow}Updating Docker image...${Color_Off}"
+            show_loading "Downloading latest NextGen image" 3
             docker pull $IMAGE_NAME
+            echo -e "${CHECK_MARK} ${BGreen}Docker image updated successfully${Color_Off}"
             break
             ;;
-        Exit)
-            echo "Have a nice day!"
+        "Exit")
+            echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
             exit 0
             ;;
-        *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
+        *) echo -e "${CROSS_MARK} ${BRed}Invalid option $REPLY. Please try again.${Color_Off}"
             ;;
     esac
 done
 
+# Running model with improved progress indicators
+print_section_header "RUNNING NEXTGEN MODEL SIMULATION"
+
+echo -e "${ARROW} ${BWhite}Preparing to run NextGen model...${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Local directory: ${BWhite}$HOST_DATA_PATH${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Container directory: ${BWhite}/ngen/ngen/data${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Docker image: ${BWhite}$IMAGE_NAME${Color_Off}"
+
+# Pause for visual confirmation
+sleep 2
 
-echo -e "\nRunning NextGen docker container..."
-echo -e "Mounting local host directory $HOST_DATA_PATH to /ngen/ngen/data within the container."
+echo -e "\n${ARROW} ${BYellow}Launching NextGen container...${Color_Off}"
 docker run --rm -it -v "$HOST_DATA_PATH:/ngen/ngen/data" "$IMAGE_NAME" /ngen/ngen/data/
 
-# Final output count
+# Final output count with improved presentation
+print_section_header "SIMULATION RESULTS"
+
 Final_Outputs_Count=$(find "$HOST_DATA_PATH/outputs/" -type f | wc -l)
-echo -e "$Final_Outputs_Count new outputs created."
-echo -e "Any copied files can be found here: $HOST_DATA_PATH/outputs"
-
-# ============ Run TEEHR ============
-# TODO: Support for ARM64
-# if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# else
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# fi
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
+
+if [ $Final_Outputs_Count -gt 0 ]; then
+    echo -e "${CHECK_MARK} ${BGreen}Simulation completed successfully!${Color_Off}"
+    echo -e "  ${INFO_MARK} ${BWhite}$Final_Outputs_Count${Color_Off} output files generated"
+    echo -e "  ${INFO_MARK} Results stored in: ${BWhite}$HOST_DATA_PATH/outputs${Color_Off}"
+else
+    echo -e "${WARNING_MARK} ${BYellow}No output files were generated.${Color_Off}"
+    echo -e "  ${INFO_MARK} Please check the simulation configuration and try again."
+fi
+
+# ============ Run TEEHR using the runTeehr.sh script ============
+if [ $Final_Outputs_Count -gt 0 ]; then
+    print_section_header "EVALUATION OPTIONS"
+    
+    echo -e "${ARROW} ${BWhite}Would you like to run a TEEHR evaluation on the output?${Color_Off}"
+    echo -e "  ${INFO_MARK} This will analyze your simulation results using the TEEHR toolkit"
+    echo -e "  ${INFO_MARK} Learn more: ${UBlue}https://rtiinternational.github.io/ngiab-teehr/${Color_Off}\n"
+    
+    read -erp "  Run TEEHR evaluation? [Y/n]: " run_teehr_choice
+    
     # Default to 'y' if input is empty
     if [[ -z "$run_teehr_choice" ]]; then
         run_teehr_choice="y"
     fi
-    # Check for valid input
-    if [[ "$run_teehr_choice" == [YyNn]* ]]; then
-        break
+    
+    # Execute TEEHR if requested
+    if [[ "$run_teehr_choice" == [Yy]* ]]; then
+        # Check if the runTeehr.sh script exists
+        if [ -f "$TEEHR_SCRIPT" ]; then
+            echo -e "\n${INFO_MARK} ${BWhite}Launching TEEHR evaluation...${Color_Off}"
+            
+            # Make sure the script is executable
+            if [ ! -x "$TEEHR_SCRIPT" ]; then
+                chmod +x "$TEEHR_SCRIPT"
+            fi
+            
+            # Call the runTeehr.sh script with the data path
+            if ! "$TEEHR_SCRIPT" "$HOST_DATA_PATH"; then
+                echo -e "\n${WARNING_MARK} ${BRed}Failed to run TEEHR evaluation.${Color_Off}"
+                echo -e "  ${INFO_MARK} Check that the runTeehr.sh script is properly configured."
+            fi
+        else
+            echo -e "\n${WARNING_MARK} ${BRed}Could not find the TEEHR evaluation script.${Color_Off}"
+            echo -e "  ${INFO_MARK} Expected location: ${BWhite}$TEEHR_SCRIPT${Color_Off}"
+            echo -e "  ${INFO_MARK} Please make sure the script is in the current directory."
+            
+            # Fallback to inline TEEHR execution
+            echo -e "\n${INFO_MARK} ${BYellow}Falling back to embedded TEEHR evaluation...${Color_Off}"
+            
+            # Detect architecture for default tag
+            if uname -a | grep -q 'arm64\|aarch64'; then
+                default_tag="latest"
+            else
+                default_tag="x86"
+            fi
+            
+            echo -e "  ${INFO_MARK} Detected architecture: ${BCyan}$(uname -m)${Color_Off} (default tag: ${BCyan}$default_tag${Color_Off})"
+            read -erp "  ${ARROW} Specify TEEHR image tag [default: '$default_tag']: " teehr_image_tag
+            
+            if [[ -z "$teehr_image_tag" ]]; then
+                teehr_image_tag=$default_tag
+            fi
+            
+            IMAGE_NAME=$TEEHR_IMAGE_NAME
+            
+            print_section_header "RUNNING TEEHR EVALUATION"
+            
+            echo -e "${ARROW} ${BYellow}Launching TEEHR evaluation...${Color_Off}\n"
+            docker run -v "$HOST_DATA_PATH:/app/data" "$IMAGE_NAME:$teehr_image_tag"
+            
+            echo -e "\n${BG_Green}${BWhite} TEEHR EVALUATION COMPLETE ${Color_Off}"
+            echo -e "${INFO_MARK} ${BCyan}Results have been saved to your output directory${Color_Off}"
+        fi
     else
-        echo -e "${RED}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (yes).${RESET}"
+        echo -e "${INFO_MARK} ${BCyan}Skipping TEEHR evaluation step.${Color_Off}"
     fi
-done
+else
+    echo -e "\n${INFO_MARK} ${BYellow}No outputs available for evaluation.${Color_Off}"
+fi
 
-# Execute the command
-if [[ "$run_teehr_choice" == [Yy]* ]]; then
-    # TEEHR run options
-    echo -e "${UYellow}Specify the TEEHR image tag to use: ${Color_Off}"
-    read -erp "Image tag (ex. v0.1.4, x86, default: 'latest'): " teehr_image_tag
-    if [[ -z "$teehr_image_tag" ]]; then
-        if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-            teehr_image_tag=latest
+# ============ Use viewOnTethys.sh for visualization ============
+if [ $Final_Outputs_Count -gt 0 ]; then
+    print_section_header "VISUALIZATION OPTIONS"
+    
+    echo -e "${ARROW} ${BWhite}Would you like to visualize results using Tethys?${Color_Off}"
+    echo -e "  ${INFO_MARK} This will provide an interactive web interface to explore your model results"
path: guide.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "  ${INFO_MARK} This will provide an interactive web interface to explore your model results."
```
created_at: 2025-05-14T17:24:05Z
author_association: COLLABORATOR
diff_hunk: @@ -87,186 +275,293 @@ cleanup_folder() {
     # Execute the find command and count the results
     local file_count=$(eval "$find_cmd" 2> /dev/null | wc -l)
 
-    echo "Files found: $file_count"
-
+    echo -e "\n${ARROW} Checking ${BWhite}$folder_name${Color_Off} directory for existing files..."
+    
     if [ "$file_count" -gt 0 ]; then
-        echo -e "${UYellow}Cleanup Process: matching files ($file_types) in $folder_name: $folder_path${Color_Off}"
-        echo -e "Select an option (type a number): "
-        choose_option
+        echo -e "  ${WARNING_MARK} Found ${BYellow}$file_count${Color_Off} existing files"
+        echo -e "\n${UYellow}Cleanup Options for $folder_name:${Color_Off}"
+        choose_option "$folder_path" "$file_types"
     else
-        echo "$folder_name is ready for run. No matching files found."
+        echo -e "  ${CHECK_MARK} ${BGreen}$folder_name is clean and ready for new simulations${Color_Off}"
     fi
 }
 
 choose_option() {
-    options=("Delete files and run fresh" "Continue without cleaning" "Exit")
+    local folder_path="$1"
+    local file_types="$2"
+    
+    options=("Delete files and run fresh simulation" "Continue with existing files" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Delete files and run fresh")
-                echo "Cleaning folder for fresh run"
-
+            "Delete files and run fresh simulation")
+                echo -e "\n  ${ARROW} ${BYellow}Cleaning folder for fresh run...${Color_Off}"
+                
+                # Show progress for long operations
+                show_loading "Removing existing files" 2
+                
                 # Construct the find delete command
                 local find_delete_cmd="find \"$folder_path\" -maxdepth 2 -type f \( $file_types \) -delete"
-
+                
                 # Execute the find delete command
                 eval "$find_delete_cmd"
+                echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed successfully${Color_Off}"
                 break
                 ;;
-            "Continue without cleaning")
-                echo "Continuing with existing files."
+            "Continue with existing files")
+                echo -e "  ${INFO_MARK} ${BCyan}Proceeding with existing files${Color_Off}"
                 break
                 ;;
             "Exit")
-                echo "Exiting script. Have a nice day!"
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY. Please select again."
+            *) echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please select again.${Color_Off}"
                 ;;
         esac
     done
 }
 
+# Cleanup process with improved section header
+print_section_header "FILE MANAGEMENT"
 
 # Cleanup Process for Outputs Folder
 cleanup_folder "$HOST_DATA_PATH/outputs/" "-name '*' " "Outputs"
 
 # Cleanup Process for restarts Folder
 cleanup_folder "$HOST_DATA_PATH/restarts/" "-name '*' " "Restarts"
 
+# File discovery with improved visuals
+print_section_header "HYDROFABRIC ANALYSIS"
 
+show_loading "Scanning for model files" 2
 
-# File discovery
-echo -e "\nLooking in the provided directory gives us:"
 find_files() {
     local path=$1
     local name=$2
     local regex=$3
     local color=$4
 
-    local files=$(find "$path" -iname "$regex")
-    echo -e "${color}Found these $name files:${Color_Off}"
-    echo "$files" || echo "No $name files found."
+    echo -e "${ARROW} Searching for ${color}$name${Color_Off} files..."
+    
+    local files=$(find "$path" -iname "$regex" 2>/dev/null)
+    if [ -n "$files" ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Found $(echo "$files" | wc -l) files:${Color_Off}"
+        echo -e "  ${BCyan}$(echo "$files" | sed 's/^/    /')${Color_Off}"
+    else
+        echo -e "  ${WARNING_MARK} ${BYellow}No $name files found.${Color_Off}"
+    fi
 }
 
 find_files "$HOST_DATA_PATH" "hydrofabric" "*.gpkg" "$UGreen"
 find_files "$HOST_DATA_PATH" "realization" "realization.json" "$UGreen"
 
-# Detect Arch and Docker
-echo -e "\nDetected ISA = $(uname -a)"
-if docker --version ; then
-    echo "Docker found"
+# System detection with improved visuals
+print_section_header "SYSTEM CONFIGURATION"
+
+echo -e "${ARROW} ${BWhite}Hardware Detection:${Color_Off}"
+system_arch=$(uname -m)
+os_name=$(uname -s)
+
+echo -e "  ${INFO_MARK} Operating System: ${BCyan}$os_name${Color_Off}"
+echo -e "  ${INFO_MARK} Architecture: ${BCyan}$system_arch${Color_Off}"
+
+# Docker detection with better error handling
+echo -e "\n${ARROW} ${BWhite}Checking for Docker:${Color_Off}"
+if command -v docker >/dev/null 2>&1; then
+    docker_version=$(docker --version | cut -d' ' -f3 | sed 's/,//')
+    echo -e "  ${CHECK_MARK} Docker detected (version: ${BGreen}$docker_version${Color_Off})"
 else
-    echo "Docker not found"
+    handle_error "Docker not found. This script requires Docker to run the NextGen model."
 fi
 
-IMAGE_NAME=awiciroh/ciroh-ngen-image:latest
+IMAGE_NAME=$NGEN_IMAGE_NAME:latest
+
+# Model run options with improved visuals
+print_section_header "MODEL EXECUTION OPTIONS"
 
-# Model run options
-echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-options=("Run NextGen using existing local docker image" "Run NextGen after updating to latest docker image" "Exit")
+echo -e "${ARROW} ${BWhite}Please select an option to proceed:${Color_Off}\n"
+options=("Run NextGen using existing local docker image" "Update to latest docker image and run" "Exit")
 select option in "${options[@]}"; do
     case $option in
         "Run NextGen using existing local docker image")
-            echo "running the model"
+            echo -e "\n${CHECK_MARK} ${BGreen}Using existing Docker image${Color_Off}"
             break
             ;;
-        "Run NextGen after updating to latest docker image")
-            echo "pulling container and running the model"
+        "Update to latest docker image and run")
+            echo -e "\n${ARROW} ${BYellow}Updating Docker image...${Color_Off}"
+            show_loading "Downloading latest NextGen image" 3
             docker pull $IMAGE_NAME
+            echo -e "${CHECK_MARK} ${BGreen}Docker image updated successfully${Color_Off}"
             break
             ;;
-        Exit)
-            echo "Have a nice day!"
+        "Exit")
+            echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
             exit 0
             ;;
-        *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
+        *) echo -e "${CROSS_MARK} ${BRed}Invalid option $REPLY. Please try again.${Color_Off}"
             ;;
     esac
 done
 
+# Running model with improved progress indicators
+print_section_header "RUNNING NEXTGEN MODEL SIMULATION"
+
+echo -e "${ARROW} ${BWhite}Preparing to run NextGen model...${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Local directory: ${BWhite}$HOST_DATA_PATH${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Container directory: ${BWhite}/ngen/ngen/data${Color_Off}"
+echo -e "  ${INFO_MARK} ${BCyan}Docker image: ${BWhite}$IMAGE_NAME${Color_Off}"
+
+# Pause for visual confirmation
+sleep 2
 
-echo -e "\nRunning NextGen docker container..."
-echo -e "Mounting local host directory $HOST_DATA_PATH to /ngen/ngen/data within the container."
+echo -e "\n${ARROW} ${BYellow}Launching NextGen container...${Color_Off}"
 docker run --rm -it -v "$HOST_DATA_PATH:/ngen/ngen/data" "$IMAGE_NAME" /ngen/ngen/data/
 
-# Final output count
+# Final output count with improved presentation
+print_section_header "SIMULATION RESULTS"
+
 Final_Outputs_Count=$(find "$HOST_DATA_PATH/outputs/" -type f | wc -l)
-echo -e "$Final_Outputs_Count new outputs created."
-echo -e "Any copied files can be found here: $HOST_DATA_PATH/outputs"
-
-# ============ Run TEEHR ============
-# TODO: Support for ARM64
-# if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# else
-#     IMAGE_NAME=a935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:latest
-# fi
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
+
+if [ $Final_Outputs_Count -gt 0 ]; then
+    echo -e "${CHECK_MARK} ${BGreen}Simulation completed successfully!${Color_Off}"
+    echo -e "  ${INFO_MARK} ${BWhite}$Final_Outputs_Count${Color_Off} output files generated"
+    echo -e "  ${INFO_MARK} Results stored in: ${BWhite}$HOST_DATA_PATH/outputs${Color_Off}"
+else
+    echo -e "${WARNING_MARK} ${BYellow}No output files were generated.${Color_Off}"
+    echo -e "  ${INFO_MARK} Please check the simulation configuration and try again."
+fi
+
+# ============ Run TEEHR using the runTeehr.sh script ============
+if [ $Final_Outputs_Count -gt 0 ]; then
+    print_section_header "EVALUATION OPTIONS"
+    
+    echo -e "${ARROW} ${BWhite}Would you like to run a TEEHR evaluation on the output?${Color_Off}"
+    echo -e "  ${INFO_MARK} This will analyze your simulation results using the TEEHR toolkit"
+    echo -e "  ${INFO_MARK} Learn more: ${UBlue}https://rtiinternational.github.io/ngiab-teehr/${Color_Off}\n"
+    
+    read -erp "  Run TEEHR evaluation? [Y/n]: " run_teehr_choice
+    
     # Default to 'y' if input is empty
     if [[ -z "$run_teehr_choice" ]]; then
         run_teehr_choice="y"
     fi
-    # Check for valid input
-    if [[ "$run_teehr_choice" == [YyNn]* ]]; then
-        break
+    
+    # Execute TEEHR if requested
+    if [[ "$run_teehr_choice" == [Yy]* ]]; then
+        # Check if the runTeehr.sh script exists
+        if [ -f "$TEEHR_SCRIPT" ]; then
+            echo -e "\n${INFO_MARK} ${BWhite}Launching TEEHR evaluation...${Color_Off}"
+            
+            # Make sure the script is executable
+            if [ ! -x "$TEEHR_SCRIPT" ]; then
+                chmod +x "$TEEHR_SCRIPT"
+            fi
+            
+            # Call the runTeehr.sh script with the data path
+            if ! "$TEEHR_SCRIPT" "$HOST_DATA_PATH"; then
+                echo -e "\n${WARNING_MARK} ${BRed}Failed to run TEEHR evaluation.${Color_Off}"
+                echo -e "  ${INFO_MARK} Check that the runTeehr.sh script is properly configured."
+            fi
+        else
+            echo -e "\n${WARNING_MARK} ${BRed}Could not find the TEEHR evaluation script.${Color_Off}"
+            echo -e "  ${INFO_MARK} Expected location: ${BWhite}$TEEHR_SCRIPT${Color_Off}"
+            echo -e "  ${INFO_MARK} Please make sure the script is in the current directory."
+            
+            # Fallback to inline TEEHR execution
+            echo -e "\n${INFO_MARK} ${BYellow}Falling back to embedded TEEHR evaluation...${Color_Off}"
+            
+            # Detect architecture for default tag
+            if uname -a | grep -q 'arm64\|aarch64'; then
+                default_tag="latest"
+            else
+                default_tag="x86"
+            fi
+            
+            echo -e "  ${INFO_MARK} Detected architecture: ${BCyan}$(uname -m)${Color_Off} (default tag: ${BCyan}$default_tag${Color_Off})"
+            read -erp "  ${ARROW} Specify TEEHR image tag [default: '$default_tag']: " teehr_image_tag
+            
+            if [[ -z "$teehr_image_tag" ]]; then
+                teehr_image_tag=$default_tag
+            fi
+            
+            IMAGE_NAME=$TEEHR_IMAGE_NAME
+            
+            print_section_header "RUNNING TEEHR EVALUATION"
+            
+            echo -e "${ARROW} ${BYellow}Launching TEEHR evaluation...${Color_Off}\n"
+            docker run -v "$HOST_DATA_PATH:/app/data" "$IMAGE_NAME:$teehr_image_tag"
+            
+            echo -e "\n${BG_Green}${BWhite} TEEHR EVALUATION COMPLETE ${Color_Off}"
+            echo -e "${INFO_MARK} ${BCyan}Results have been saved to your output directory${Color_Off}"
+        fi
     else
-        echo -e "${RED}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (yes).${RESET}"
+        echo -e "${INFO_MARK} ${BCyan}Skipping TEEHR evaluation step.${Color_Off}"
     fi
-done
+else
+    echo -e "\n${INFO_MARK} ${BYellow}No outputs available for evaluation.${Color_Off}"
+fi
 
-# Execute the command
-if [[ "$run_teehr_choice" == [Yy]* ]]; then
-    # TEEHR run options
-    echo -e "${UYellow}Specify the TEEHR image tag to use: ${Color_Off}"
-    read -erp "Image tag (ex. v0.1.4, x86, default: 'latest'): " teehr_image_tag
-    if [[ -z "$teehr_image_tag" ]]; then
-        if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-            teehr_image_tag=latest
+# ============ Use viewOnTethys.sh for visualization ============
+if [ $Final_Outputs_Count -gt 0 ]; then
+    print_section_header "VISUALIZATION OPTIONS"
+    
+    echo -e "${ARROW} ${BWhite}Would you like to visualize results using Tethys?${Color_Off}"
+    echo -e "  ${INFO_MARK} This will provide an interactive web interface to explore your model results"
+    read -erp "  Visualize results? [Y/n]: " visualize_choice
+    
+    # Default to 'y' if input is empty
+    if [[ -z "$visualize_choice" || "$visualize_choice" == [Yy]* ]]; then
+        # Check if the viewOnTethys.sh script exists
+        if [ -f "$TETHYS_SCRIPT" ]; then
+            echo -e "\n${INFO_MARK} ${BWhite}Launching Tethys visualization...${Color_Off}"
+            
+            # Make sure the script is executable
+            if [ ! -x "$TETHYS_SCRIPT" ]; then
+                chmod +x "$TETHYS_SCRIPT"
+            fi
+            
+            # Call the viewOnTethys.sh script with the data path
+            if ! "$TETHYS_SCRIPT" "$HOST_DATA_PATH"; then
+                echo -e "\n${WARNING_MARK} ${BRed}Failed to launch Tethys visualization.${Color_Off}"
+                echo -e "  ${INFO_MARK} Check that the viewOnTethys.sh script is properly configured."
+            fi
         else
-            teehr_image_tag=x86
+            echo -e "\n${WARNING_MARK} ${BRed}Could not find the Tethys visualization script.${Color_Off}"
+            echo -e "  ${INFO_MARK} Expected location: ${BWhite}$TETHYS_SCRIPT${Color_Off}"
+            echo -e "  ${INFO_MARK} Please make sure the script is in the current directory."
         fi
+    else
+        echo -e "${INFO_MARK} ${BCyan}Skipping visualization step.${Color_Off}"
     fi
-    echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-    options=("Run TEEHR using existing local docker image" "Run TEEHR after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run TEEHR using existing local docker image")
-                echo "running the TEEHR evaluation"
-                break
-                ;;
-            "Run TEEHR after updating to latest docker image")
-                echo "pulling container and running the TEEHR evaluation"
-                docker pull $IMAGE_NAME:$teehr_image_tag
-                break
-                ;;
-            Exit)
-                echo "Have a nice day!"
-                exit 0
-                ;;
-            *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
-                ;;
-        esac
-    done
-
-    docker run -v "$HOST_DATA_PATH:/app/data" "$IMAGE_NAME:$teehr_image_tag"
-    echo -e "${GREEN}TEEHR evaluation complete.${RESET}\n"
 else
-    echo -e "${CYAN}Skipping TEEHR evaluation step.${RESET}\n"
+    echo -e "\n${INFO_MARK} ${BYellow}No outputs available for visualization.${Color_Off}"
 fi
-# ================================
 
-# visualize with Tethys
-if [ $Final_Outputs_Count -gt 0 ]; then
-    ARG1="$HOST_DATA_PATH"
-    if ! "$TETHYS_SCRIPT" "$ARG1"; then
-        printf "Failed to visualize outputs in Tethys:"
-    fi
+# Closing message with improved visuals
+print_section_header "SESSION COMPLETE"
+
+# Create a fancy box for the thank you message
+echo -e "\033[38;5;39m  ┌────────────────────────────────────────────────────────────┐\033[0m"
+echo -e "\033[38;5;39m  │\033[48;5;39m\033[1;37m  Thank you for using NGIAB!                                  \033[0m\033[38;5;39m  │\033[0m"
+echo -e "\033[38;5;39m  └────────────────────────────────────────────────────────────┘\033[0m\n"
+
+echo -e "${INFO_MARK} ${BWhite}Your simulation results are available at:${Color_Off}"
+echo -e "  ${ARROW} ${LBLUE}$HOST_DATA_PATH/outputs${Color_Off}\n"
+
+# Check if any outputs were generated
+output_count=$(find "$HOST_DATA_PATH/outputs/" -type f 2>/dev/null | wc -l)
+if [ "$output_count" -gt 0 ]; then
+    echo -e "  ${CHECK_MARK} ${BGreen}$output_count files were successfully generated${Color_Off}"
path: guide.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "  ${CHECK_MARK} ${BGreen}$output_count files were successfully generated.${Color_Off}"
```
created_at: 2025-05-14T17:24:34Z
author_association: COLLABORATOR
diff_hunk: @@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
path: runTeehr.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed!${Color_Off}"
```
created_at: 2025-05-14T17:25:25Z
author_association: COLLABORATOR
diff_hunk: @@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
 }
 
-_check_if_data_folder_exits(){
-    # Check the directory exists
+# Set up trap for Ctrl-C and EXIT
+trap handle_sigint INT
+trap clean_up_resources EXIT
+
+# Check if a directory exists
+check_if_data_folder_exists() {
     if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
+        handle_error "Directory does not exist: $DATA_FOLDER_PATH"
     fi
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
+# Check and read from config file
+check_and_read_config() {
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            check_if_data_folder_exists
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
path: runTeehr.sh
user: login: Sheargrub
body: ```suggestion
            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path.${Color_Off}"
```
created_at: 2025-05-14T17:25:46Z
author_association: COLLABORATOR
diff_hunk: @@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
 }
 
-_check_if_data_folder_exits(){
-    # Check the directory exists
+# Set up trap for Ctrl-C and EXIT
+trap handle_sigint INT
+trap clean_up_resources EXIT
+
+# Check if a directory exists
+check_if_data_folder_exists() {
     if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
+        handle_error "Directory does not exist: $DATA_FOLDER_PATH"
     fi
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
+# Check and read from config file
+check_and_read_config() {
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            check_if_data_folder_exists
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
+        else
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
+            check_if_data_folder_exists
+            
             # Save the new path to the config file
             echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
+            echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
path: runTeehr.sh
user: login: Sheargrub
body: ```suggestion
            echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use.${Color_Off}"
```
created_at: 2025-05-14T17:26:02Z
author_association: COLLABORATOR
diff_hunk: @@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
 }
 
-_check_if_data_folder_exits(){
-    # Check the directory exists
+# Set up trap for Ctrl-C and EXIT
+trap handle_sigint INT
+trap clean_up_resources EXIT
+
+# Check if a directory exists
+check_if_data_folder_exists() {
     if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
+        handle_error "Directory does not exist: $DATA_FOLDER_PATH"
     fi
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
+# Check and read from config file
+check_and_read_config() {
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            check_if_data_folder_exists
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
+        else
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
+            check_if_data_folder_exists
+            
             # Save the new path to the config file
             echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
+            echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
         fi
+    else
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
path: runTeehr.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "${INFO_MARK} ${BYellow}No previous configuration found.${Color_Off}"
```
created_at: 2025-05-14T17:30:04Z
author_association: COLLABORATOR
diff_hunk: @@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
 }
 
-_check_if_data_folder_exits(){
-    # Check the directory exists
+# Set up trap for Ctrl-C and EXIT
+trap handle_sigint INT
+trap clean_up_resources EXIT
+
+# Check if a directory exists
+check_if_data_folder_exists() {
     if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
+        handle_error "Directory does not exist: $DATA_FOLDER_PATH"
     fi
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
+# Check and read from config file
+check_and_read_config() {
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            check_if_data_folder_exists
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
+        else
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
+            check_if_data_folder_exists
+            
             # Save the new path to the config file
             echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
+            echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
         fi
+    else
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+        echo -ne "  ${ARROW} Enter your input data directory path: "
+        read -e DATA_FOLDER_PATH
+        check_if_data_folder_exists
+        
+        # Save the path to the config file
+        echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
+        echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
path: runTeehr.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use.${Color_Off}"
```
created_at: 2025-05-14T17:30:14Z
author_association: COLLABORATOR
diff_hunk: @@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
 }
 
-_check_if_data_folder_exits(){
-    # Check the directory exists
+# Set up trap for Ctrl-C and EXIT
+trap handle_sigint INT
+trap clean_up_resources EXIT
+
+# Check if a directory exists
+check_if_data_folder_exists() {
     if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
+        handle_error "Directory does not exist: $DATA_FOLDER_PATH"
     fi
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
+# Check and read from config file
+check_and_read_config() {
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            check_if_data_folder_exists
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
+        else
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
+            check_if_data_folder_exists
+            
             # Save the new path to the config file
             echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
+            echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
         fi
+    else
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+        echo -ne "  ${ARROW} Enter your input data directory path: "
+        read -e DATA_FOLDER_PATH
+        check_if_data_folder_exists
+        
+        # Save the path to the config file
+        echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
+        echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
     fi
 }
 
+# Handle path from arguments or config
 check_last_path() {
     if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+        check_and_read_config
     else
         DATA_FOLDER_PATH="$1"
+        check_if_data_folder_exists
     fi
 }
 
-### Start of the Script ###
+# Main script execution
+print_welcome_banner
 
-# Constanst
-CONFIG_FILE="$HOME/.host_data_path.conf"
+# Check if data path is provided as argument
+check_last_path "$1"
 
-check_last_path "$@"
+print_section_header "TEEHR EVALUATION SETUP"
 
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
-    # Default to 'y' if input is empty
-    if [[ -z "$run_teehr_choice" ]]; then
-        run_teehr_choice="y"
-    fi
-    # Check for valid input
-    if [[ "$run_teehr_choice" == [YyNn]* ]]; then
-        break
+echo -e "${INFO_MARK} ${BWhite}TEEHR will evaluate model outputs against observations${Color_Off}"
path: runTeehr.sh
user: login: Sheargrub
body: ```suggestion
echo -e "${INFO_MARK} ${BWhite}TEEHR will evaluate model outputs against observations.${Color_Off}"
```
created_at: 2025-05-14T17:30:41Z
author_association: COLLABORATOR
diff_hunk: @@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
 }
 
-_check_if_data_folder_exits(){
-    # Check the directory exists
+# Set up trap for Ctrl-C and EXIT
+trap handle_sigint INT
+trap clean_up_resources EXIT
+
+# Check if a directory exists
+check_if_data_folder_exists() {
     if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
+        handle_error "Directory does not exist: $DATA_FOLDER_PATH"
     fi
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
+# Check and read from config file
+check_and_read_config() {
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            check_if_data_folder_exists
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
+        else
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
+            check_if_data_folder_exists
+            
             # Save the new path to the config file
             echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
+            echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
         fi
+    else
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+        echo -ne "  ${ARROW} Enter your input data directory path: "
+        read -e DATA_FOLDER_PATH
+        check_if_data_folder_exists
+        
+        # Save the path to the config file
+        echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
+        echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
     fi
 }
 
+# Handle path from arguments or config
 check_last_path() {
     if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+        check_and_read_config
     else
         DATA_FOLDER_PATH="$1"
+        check_if_data_folder_exists
     fi
 }
 
-### Start of the Script ###
+# Main script execution
+print_welcome_banner
 
-# Constanst
-CONFIG_FILE="$HOME/.host_data_path.conf"
+# Check if data path is provided as argument
+check_last_path "$1"
 
-check_last_path "$@"
+print_section_header "TEEHR EVALUATION SETUP"
 
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
-    # Default to 'y' if input is empty
-    if [[ -z "$run_teehr_choice" ]]; then
-        run_teehr_choice="y"
-    fi
-    # Check for valid input
-    if [[ "$run_teehr_choice" == [YyNn]* ]]; then
-        break
+echo -e "${INFO_MARK} ${BWhite}TEEHR will evaluate model outputs against observations${Color_Off}"
+echo -e "  ${ARROW} Learn more: ${UBlue}https://rtiinternational.github.io/ngiab-teehr/${Color_Off}\n"
+
+echo -e "${ARROW} ${BWhite}Would you like to run a TEEHR evaluation on your model outputs?${Color_Off}"
+read -erp "  Run evaluation? [Y/n]: " run_teehr_choice
+
+# Default to 'y' if input is empty
+if [[ -z "$run_teehr_choice" ]]; then
+    run_teehr_choice="y"
+fi
+
+# Execute the TEEHR evaluation if requested
+if [[ "$run_teehr_choice" =~ ^[Yy] ]]; then
+    # Detect platform architecture for default tag
+    if uname -a | grep -q 'arm64\|aarch64'; then
+        default_tag="latest" # ARM64 architecture
     else
-        echo -e "${RED}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (yes).${RESET}"
+        default_tag="x86"    # x86 architecture
     fi
-done
-
-# Execute the command
-if [[ "$run_teehr_choice" == [Yy]* ]]; then
-    # TEEHR run options
-    echo -e "${UYellow}Specify the TEEHR image tag to use: ${Color_Off}"
-    read -erp "Image tag (ex. v0.1.4, x86, default: 'latest'): " teehr_image_tag
+    
+    echo -e "\n${ARROW} ${BWhite}System architecture detected: ${BCyan}$(uname -m)${Color_Off}"
+    echo -e "  ${INFO_MARK} Recommended image tag: ${BCyan}$default_tag${Color_Off}"
+    echo -ne "  ${ARROW} Specify TEEHR image tag [default: $default_tag]: "
+    read -e teehr_image_tag
+    
     if [[ -z "$teehr_image_tag" ]]; then
-        if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-            teehr_image_tag=latest
-        else
-            teehr_image_tag=x86
-        fi
+        teehr_image_tag="$default_tag"
+        echo -e "  ${CHECK_MARK} ${BGreen}Using default tag: $default_tag${Color_Off}"
+    else
+        echo -e "  ${CHECK_MARK} ${BGreen}Using specified tag: $teehr_image_tag${Color_Off}"
     fi
-    echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-    options=("Run TEEHR using existing local docker image" "Run TEEHR after updating to latest docker image" "Exit")
+
+    print_section_header "CONTAINER MANAGEMENT"
+    
+    echo -e "${ARROW} ${BWhite}Select an option:${Color_Off}\n"
+    options=("Run TEEHR using existing local image" "Update to latest TEEHR image" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Run TEEHR using existing local docker image")
-                echo "running the TEEHR evaluation"
+            "Run TEEHR using existing local image")
+                echo -e "  ${CHECK_MARK} ${BGreen}Using existing local TEEHR image${Color_Off}"
                 break
                 ;;
-            "Run TEEHR after updating to latest docker image")
-                echo "pulling container and running the TEEHR evaluation"
-                docker pull $IMAGE_NAME:$teehr_image_tag
+            "Update to latest TEEHR image")
+                echo -e "  ${ARROW} ${BYellow}Updating TEEHR image...${Color_Off}"
+                show_loading "Downloading latest TEEHR image" 3
path: runTeehr.sh
user: login: Sheargrub
body: ```suggestion
                echo -e "  ${ARROW} ${BYellow}Updating TEEHR image.${Color_Off}"
                show_loading "Downloading latest TEEHR image..." 3
```
created_at: 2025-05-14T17:31:22Z
author_association: COLLABORATOR
diff_hunk: @@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
 }
 
-_check_if_data_folder_exits(){
-    # Check the directory exists
+# Set up trap for Ctrl-C and EXIT
+trap handle_sigint INT
+trap clean_up_resources EXIT
+
+# Check if a directory exists
+check_if_data_folder_exists() {
     if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
+        handle_error "Directory does not exist: $DATA_FOLDER_PATH"
     fi
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
+# Check and read from config file
+check_and_read_config() {
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            check_if_data_folder_exists
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
+        else
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
+            check_if_data_folder_exists
+            
             # Save the new path to the config file
             echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
+            echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
         fi
+    else
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+        echo -ne "  ${ARROW} Enter your input data directory path: "
+        read -e DATA_FOLDER_PATH
+        check_if_data_folder_exists
+        
+        # Save the path to the config file
+        echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
+        echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
     fi
 }
 
+# Handle path from arguments or config
 check_last_path() {
     if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+        check_and_read_config
     else
         DATA_FOLDER_PATH="$1"
+        check_if_data_folder_exists
     fi
 }
 
-### Start of the Script ###
+# Main script execution
+print_welcome_banner
 
-# Constanst
-CONFIG_FILE="$HOME/.host_data_path.conf"
+# Check if data path is provided as argument
+check_last_path "$1"
 
-check_last_path "$@"
+print_section_header "TEEHR EVALUATION SETUP"
 
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
-    # Default to 'y' if input is empty
-    if [[ -z "$run_teehr_choice" ]]; then
-        run_teehr_choice="y"
-    fi
-    # Check for valid input
-    if [[ "$run_teehr_choice" == [YyNn]* ]]; then
-        break
+echo -e "${INFO_MARK} ${BWhite}TEEHR will evaluate model outputs against observations${Color_Off}"
+echo -e "  ${ARROW} Learn more: ${UBlue}https://rtiinternational.github.io/ngiab-teehr/${Color_Off}\n"
+
+echo -e "${ARROW} ${BWhite}Would you like to run a TEEHR evaluation on your model outputs?${Color_Off}"
+read -erp "  Run evaluation? [Y/n]: " run_teehr_choice
+
+# Default to 'y' if input is empty
+if [[ -z "$run_teehr_choice" ]]; then
+    run_teehr_choice="y"
+fi
+
+# Execute the TEEHR evaluation if requested
+if [[ "$run_teehr_choice" =~ ^[Yy] ]]; then
+    # Detect platform architecture for default tag
+    if uname -a | grep -q 'arm64\|aarch64'; then
+        default_tag="latest" # ARM64 architecture
     else
-        echo -e "${RED}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (yes).${RESET}"
+        default_tag="x86"    # x86 architecture
     fi
-done
-
-# Execute the command
-if [[ "$run_teehr_choice" == [Yy]* ]]; then
-    # TEEHR run options
-    echo -e "${UYellow}Specify the TEEHR image tag to use: ${Color_Off}"
-    read -erp "Image tag (ex. v0.1.4, x86, default: 'latest'): " teehr_image_tag
+    
+    echo -e "\n${ARROW} ${BWhite}System architecture detected: ${BCyan}$(uname -m)${Color_Off}"
+    echo -e "  ${INFO_MARK} Recommended image tag: ${BCyan}$default_tag${Color_Off}"
+    echo -ne "  ${ARROW} Specify TEEHR image tag [default: $default_tag]: "
+    read -e teehr_image_tag
+    
     if [[ -z "$teehr_image_tag" ]]; then
-        if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-            teehr_image_tag=latest
-        else
-            teehr_image_tag=x86
-        fi
+        teehr_image_tag="$default_tag"
+        echo -e "  ${CHECK_MARK} ${BGreen}Using default tag: $default_tag${Color_Off}"
+    else
+        echo -e "  ${CHECK_MARK} ${BGreen}Using specified tag: $teehr_image_tag${Color_Off}"
     fi
-    echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-    options=("Run TEEHR using existing local docker image" "Run TEEHR after updating to latest docker image" "Exit")
+
+    print_section_header "CONTAINER MANAGEMENT"
+    
+    echo -e "${ARROW} ${BWhite}Select an option:${Color_Off}\n"
+    options=("Run TEEHR using existing local image" "Update to latest TEEHR image" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Run TEEHR using existing local docker image")
-                echo "running the TEEHR evaluation"
+            "Run TEEHR using existing local image")
+                echo -e "  ${CHECK_MARK} ${BGreen}Using existing local TEEHR image${Color_Off}"
                 break
                 ;;
-            "Run TEEHR after updating to latest docker image")
-                echo "pulling container and running the TEEHR evaluation"
-                docker pull $IMAGE_NAME:$teehr_image_tag
+            "Update to latest TEEHR image")
+                echo -e "  ${ARROW} ${BYellow}Updating TEEHR image...${Color_Off}"
+                show_loading "Downloading latest TEEHR image" 3
+                
+                if ! docker pull "${IMAGE_NAME}:${teehr_image_tag}"; then
+                    handle_error "Failed to pull Docker image: ${IMAGE_NAME}:${teehr_image_tag}"
+                fi
+                
+                echo -e "  ${CHECK_MARK} ${BGreen}TEEHR image updated successfully${Color_Off}"
path: runTeehr.sh
user: login: Sheargrub
body: ```suggestion
                echo -e "  ${CHECK_MARK} ${BGreen}TEEHR image updated successfully!${Color_Off}"
```
created_at: 2025-05-14T17:31:32Z
author_association: COLLABORATOR
diff_hunk: @@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
 }
 
-_check_if_data_folder_exits(){
-    # Check the directory exists
+# Set up trap for Ctrl-C and EXIT
+trap handle_sigint INT
+trap clean_up_resources EXIT
+
+# Check if a directory exists
+check_if_data_folder_exists() {
     if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
+        handle_error "Directory does not exist: $DATA_FOLDER_PATH"
     fi
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
+# Check and read from config file
+check_and_read_config() {
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            check_if_data_folder_exists
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
+        else
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
+            check_if_data_folder_exists
+            
             # Save the new path to the config file
             echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
+            echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
         fi
+    else
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+        echo -ne "  ${ARROW} Enter your input data directory path: "
+        read -e DATA_FOLDER_PATH
+        check_if_data_folder_exists
+        
+        # Save the path to the config file
+        echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
+        echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
     fi
 }
 
+# Handle path from arguments or config
 check_last_path() {
     if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+        check_and_read_config
     else
         DATA_FOLDER_PATH="$1"
+        check_if_data_folder_exists
     fi
 }
 
-### Start of the Script ###
+# Main script execution
+print_welcome_banner
 
-# Constanst
-CONFIG_FILE="$HOME/.host_data_path.conf"
+# Check if data path is provided as argument
+check_last_path "$1"
 
-check_last_path "$@"
+print_section_header "TEEHR EVALUATION SETUP"
 
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
-    # Default to 'y' if input is empty
-    if [[ -z "$run_teehr_choice" ]]; then
-        run_teehr_choice="y"
-    fi
-    # Check for valid input
-    if [[ "$run_teehr_choice" == [YyNn]* ]]; then
-        break
+echo -e "${INFO_MARK} ${BWhite}TEEHR will evaluate model outputs against observations${Color_Off}"
+echo -e "  ${ARROW} Learn more: ${UBlue}https://rtiinternational.github.io/ngiab-teehr/${Color_Off}\n"
+
+echo -e "${ARROW} ${BWhite}Would you like to run a TEEHR evaluation on your model outputs?${Color_Off}"
+read -erp "  Run evaluation? [Y/n]: " run_teehr_choice
+
+# Default to 'y' if input is empty
+if [[ -z "$run_teehr_choice" ]]; then
+    run_teehr_choice="y"
+fi
+
+# Execute the TEEHR evaluation if requested
+if [[ "$run_teehr_choice" =~ ^[Yy] ]]; then
+    # Detect platform architecture for default tag
+    if uname -a | grep -q 'arm64\|aarch64'; then
+        default_tag="latest" # ARM64 architecture
     else
-        echo -e "${RED}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (yes).${RESET}"
+        default_tag="x86"    # x86 architecture
     fi
-done
-
-# Execute the command
-if [[ "$run_teehr_choice" == [Yy]* ]]; then
-    # TEEHR run options
-    echo -e "${UYellow}Specify the TEEHR image tag to use: ${Color_Off}"
-    read -erp "Image tag (ex. v0.1.4, x86, default: 'latest'): " teehr_image_tag
+    
+    echo -e "\n${ARROW} ${BWhite}System architecture detected: ${BCyan}$(uname -m)${Color_Off}"
+    echo -e "  ${INFO_MARK} Recommended image tag: ${BCyan}$default_tag${Color_Off}"
+    echo -ne "  ${ARROW} Specify TEEHR image tag [default: $default_tag]: "
+    read -e teehr_image_tag
+    
     if [[ -z "$teehr_image_tag" ]]; then
-        if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-            teehr_image_tag=latest
-        else
-            teehr_image_tag=x86
-        fi
+        teehr_image_tag="$default_tag"
+        echo -e "  ${CHECK_MARK} ${BGreen}Using default tag: $default_tag${Color_Off}"
+    else
+        echo -e "  ${CHECK_MARK} ${BGreen}Using specified tag: $teehr_image_tag${Color_Off}"
     fi
-    echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-    options=("Run TEEHR using existing local docker image" "Run TEEHR after updating to latest docker image" "Exit")
+
+    print_section_header "CONTAINER MANAGEMENT"
+    
+    echo -e "${ARROW} ${BWhite}Select an option:${Color_Off}\n"
+    options=("Run TEEHR using existing local image" "Update to latest TEEHR image" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Run TEEHR using existing local docker image")
-                echo "running the TEEHR evaluation"
+            "Run TEEHR using existing local image")
+                echo -e "  ${CHECK_MARK} ${BGreen}Using existing local TEEHR image${Color_Off}"
                 break
                 ;;
-            "Run TEEHR after updating to latest docker image")
-                echo "pulling container and running the TEEHR evaluation"
-                docker pull $IMAGE_NAME:$teehr_image_tag
+            "Update to latest TEEHR image")
+                echo -e "  ${ARROW} ${BYellow}Updating TEEHR image...${Color_Off}"
+                show_loading "Downloading latest TEEHR image" 3
+                
+                if ! docker pull "${IMAGE_NAME}:${teehr_image_tag}"; then
+                    handle_error "Failed to pull Docker image: ${IMAGE_NAME}:${teehr_image_tag}"
+                fi
+                
+                echo -e "  ${CHECK_MARK} ${BGreen}TEEHR image updated successfully${Color_Off}"
                 break
                 ;;
-            Exit)
-                echo "Have a nice day!"
+            "Exit")
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
+            *)
+                echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please try again.${Color_Off}"
                 ;;
         esac
     done
 
-    docker run -v "$DATA_FOLDER_PATH:/app/data" "$IMAGE_NAME:$teehr_image_tag"
-    echo -e "${GREEN}TEEHR evaluation complete.${RESET}\n"
+    print_section_header "RUNNING TEEHR EVALUATION"
+    
+    echo -e "${INFO_MARK} ${BWhite}Evaluating model outputs in: ${BCyan}$DATA_FOLDER_PATH${Color_Off}"
+    echo -e "  ${ARROW} This analysis may take several minutes depending on your dataset size"
path: runTeehr.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "  ${ARROW} This analysis may take several minutes depending on your dataset size."
```
created_at: 2025-05-14T17:31:48Z
author_association: COLLABORATOR
diff_hunk: @@ -1,131 +1,321 @@
 #!/bin/bash
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    echo "check"
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
+# ======================================================================
+# CIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation Tool
+# Version: 1.4.1
+# ======================================================================
+
+# Color definitions with enhanced palette
+BBlack='\033[1;30m'
+BRed='\033[1;31m'
+BGreen='\033[1;32m'
+BYellow='\033[1;33m'
+BBlue='\033[1;34m'
+BPurple='\033[1;35m'
+BCyan='\033[1;36m'
+BWhite='\033[1;37m'
+UBlack='\033[4;30m'
+URed='\033[4;31m'
+UGreen='\033[4;32m'
+UYellow='\033[4;33m'
+UBlue='\033[4;34m'
+UPurple='\033[4;35m'
+UCyan='\033[4;36m'
+UWhite='\033[4;37m'
+Color_Off='\033[0m'
+
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+set -e
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DATA_FOLDER_PATH=""
+IMAGE_NAME="awiciroh/ngiab-teehr"
+TEEHR_CONTAINER_PREFIX="teehr-evaluation"
+
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
+}
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
+}
+
+# Welcome banner with improved design - fixed formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n\n"
+    echo -e "\033[38;5;39m  ╔══════════════════════════════════════════════════════════════════════════════════════════╗\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mCIROH: NextGen In A Box (NGIAB) - TEEHR Evaluation\033[38;5;39m                                      ║\033[0m"
+    echo -e "\033[38;5;39m  ║  \033[1;38;5;231mModel Performance Assessment Tool\033[38;5;39m                                                       ║\033[0m"
+    echo -e "\033[38;5;39m  ║                                                                                          ║\033[0m"
+    echo -e "\033[38;5;39m  ╚══════════════════════════════════════════════════════════════════════════════════════════╝\033[0m"
+    echo -e "\n"
+    echo -e "  ${INFO_MARK} \033[1;38;5;231mDeveloped by CIROH\033[0m"
+    echo -e "\n"
+    sleep 1
+}
+
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    clean_up_resources
+    exit 1
+}
+
+# Clean up resources function
+clean_up_resources() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
     fi
+    
+    # Find and stop any running TEEHR containers
+    local running_containers=$(docker ps -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$running_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping TEEHR containers..."
+        docker stop $running_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also check for containers with our prefix
+    local prefix_containers=$(docker ps -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Stopping additional TEEHR containers..."
+        docker stop $prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Remove any stopped containers matching our criteria
+    local all_containers=$(docker ps -a -q --filter "ancestor=$IMAGE_NAME")
+    if [ -n "$all_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing TEEHR containers..."
+        docker rm $all_containers >/dev/null 2>&1 || true
+    fi
+    
+    # Also remove any with our prefix
+    local all_prefix_containers=$(docker ps -a -q --filter "name=$TEEHR_CONTAINER_PREFIX")
+    if [ -n "$all_prefix_containers" ]; then
+        echo -e "  ${INFO_MARK} Removing additional TEEHR containers..."
+        docker rm $all_prefix_containers >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
 }
 
-_check_if_data_folder_exits(){
-    # Check the directory exists
+# Set up trap for Ctrl-C and EXIT
+trap handle_sigint INT
+trap clean_up_resources EXIT
+
+# Check if a directory exists
+check_if_data_folder_exists() {
     if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
+        handle_error "Directory does not exist: $DATA_FOLDER_PATH"
     fi
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
+# Check and read from config file
+check_and_read_config() {
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            check_if_data_folder_exists
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
+        else
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
+            check_if_data_folder_exists
+            
             # Save the new path to the config file
             echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
+            echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
         fi
+    else
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+        echo -ne "  ${ARROW} Enter your input data directory path: "
+        read -e DATA_FOLDER_PATH
+        check_if_data_folder_exists
+        
+        # Save the path to the config file
+        echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
+        echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
     fi
 }
 
+# Handle path from arguments or config
 check_last_path() {
     if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+        check_and_read_config
     else
         DATA_FOLDER_PATH="$1"
+        check_if_data_folder_exists
     fi
 }
 
-### Start of the Script ###
+# Main script execution
+print_welcome_banner
 
-# Constanst
-CONFIG_FILE="$HOME/.host_data_path.conf"
+# Check if data path is provided as argument
+check_last_path "$1"
 
-check_last_path "$@"
+print_section_header "TEEHR EVALUATION SETUP"
 
-IMAGE_NAME=awiciroh/ngiab-teehr
-while true; do
-    echo -e "${YELLOW}Run a TEEHR Evaluation on the output (https://rtiinternational.github.io/ngiab-teehr/)? (y/N, default: y):${RESET}"
-    read -r run_teehr_choice
-    # Default to 'y' if input is empty
-    if [[ -z "$run_teehr_choice" ]]; then
-        run_teehr_choice="y"
-    fi
-    # Check for valid input
-    if [[ "$run_teehr_choice" == [YyNn]* ]]; then
-        break
+echo -e "${INFO_MARK} ${BWhite}TEEHR will evaluate model outputs against observations${Color_Off}"
+echo -e "  ${ARROW} Learn more: ${UBlue}https://rtiinternational.github.io/ngiab-teehr/${Color_Off}\n"
+
+echo -e "${ARROW} ${BWhite}Would you like to run a TEEHR evaluation on your model outputs?${Color_Off}"
+read -erp "  Run evaluation? [Y/n]: " run_teehr_choice
+
+# Default to 'y' if input is empty
+if [[ -z "$run_teehr_choice" ]]; then
+    run_teehr_choice="y"
+fi
+
+# Execute the TEEHR evaluation if requested
+if [[ "$run_teehr_choice" =~ ^[Yy] ]]; then
+    # Detect platform architecture for default tag
+    if uname -a | grep -q 'arm64\|aarch64'; then
+        default_tag="latest" # ARM64 architecture
     else
-        echo -e "${RED}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (yes).${RESET}"
+        default_tag="x86"    # x86 architecture
     fi
-done
-
-# Execute the command
-if [[ "$run_teehr_choice" == [Yy]* ]]; then
-    # TEEHR run options
-    echo -e "${UYellow}Specify the TEEHR image tag to use: ${Color_Off}"
-    read -erp "Image tag (ex. v0.1.4, x86, default: 'latest'): " teehr_image_tag
+    
+    echo -e "\n${ARROW} ${BWhite}System architecture detected: ${BCyan}$(uname -m)${Color_Off}"
+    echo -e "  ${INFO_MARK} Recommended image tag: ${BCyan}$default_tag${Color_Off}"
+    echo -ne "  ${ARROW} Specify TEEHR image tag [default: $default_tag]: "
+    read -e teehr_image_tag
+    
     if [[ -z "$teehr_image_tag" ]]; then
-        if uname -a | grep arm64 || uname -a | grep aarch64 ; then
-            teehr_image_tag=latest
-        else
-            teehr_image_tag=x86
-        fi
+        teehr_image_tag="$default_tag"
+        echo -e "  ${CHECK_MARK} ${BGreen}Using default tag: $default_tag${Color_Off}"
+    else
+        echo -e "  ${CHECK_MARK} ${BGreen}Using specified tag: $teehr_image_tag${Color_Off}"
     fi
-    echo -e "${UYellow}Select an option (type a number): ${Color_Off}"
-    options=("Run TEEHR using existing local docker image" "Run TEEHR after updating to latest docker image" "Exit")
+
+    print_section_header "CONTAINER MANAGEMENT"
+    
+    echo -e "${ARROW} ${BWhite}Select an option:${Color_Off}\n"
+    options=("Run TEEHR using existing local image" "Update to latest TEEHR image" "Exit")
     select option in "${options[@]}"; do
         case $option in
-            "Run TEEHR using existing local docker image")
-                echo "running the TEEHR evaluation"
+            "Run TEEHR using existing local image")
+                echo -e "  ${CHECK_MARK} ${BGreen}Using existing local TEEHR image${Color_Off}"
                 break
                 ;;
-            "Run TEEHR after updating to latest docker image")
-                echo "pulling container and running the TEEHR evaluation"
-                docker pull $IMAGE_NAME:$teehr_image_tag
+            "Update to latest TEEHR image")
+                echo -e "  ${ARROW} ${BYellow}Updating TEEHR image...${Color_Off}"
+                show_loading "Downloading latest TEEHR image" 3
+                
+                if ! docker pull "${IMAGE_NAME}:${teehr_image_tag}"; then
+                    handle_error "Failed to pull Docker image: ${IMAGE_NAME}:${teehr_image_tag}"
+                fi
+                
+                echo -e "  ${CHECK_MARK} ${BGreen}TEEHR image updated successfully${Color_Off}"
                 break
                 ;;
-            Exit)
-                echo "Have a nice day!"
+            "Exit")
+                echo -e "\n${BYellow}Exiting script. Have a nice day!${Color_Off}"
                 exit 0
                 ;;
-            *) echo "Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit"
+            *)
+                echo -e "  ${CROSS_MARK} ${BRed}Invalid option $REPLY. Please try again.${Color_Off}"
                 ;;
         esac
     done
 
-    docker run -v "$DATA_FOLDER_PATH:/app/data" "$IMAGE_NAME:$teehr_image_tag"
-    echo -e "${GREEN}TEEHR evaluation complete.${RESET}\n"
+    print_section_header "RUNNING TEEHR EVALUATION"
+    
+    echo -e "${INFO_MARK} ${BWhite}Evaluating model outputs in: ${BCyan}$DATA_FOLDER_PATH${Color_Off}"
+    echo -e "  ${ARROW} This analysis may take several minutes depending on your dataset size"
+    
+    show_loading "Initializing TEEHR evaluation" 2
+    
+    # Create a unique container name
+    CONTAINER_NAME="${TEEHR_CONTAINER_PREFIX}-$(date +%s)"
+    
+    # First clean up any old containers
+    clean_up_resources
+    
+    # Run the TEEHR container with a name for easier cleanup
+    if ! docker run --name "$CONTAINER_NAME" --rm -v "$DATA_FOLDER_PATH:/app/data" "${IMAGE_NAME}:${teehr_image_tag}"; then
+        handle_error "TEEHR evaluation failed"
+    fi
+    
+    print_section_header "EVALUATION COMPLETE"
+    
+    echo -e "${BG_Green}${BWhite} TEEHR evaluation completed successfully! ${Color_Off}\n"
+    echo -e "${INFO_MARK} ${BWhite}Results have been saved to your outputs directory:${Color_Off}"
+    echo -e "  ${ARROW} ${BCyan}$DATA_FOLDER_PATH/outputs/teehr/${Color_Off}"
+    echo -e "\n${INFO_MARK} You can visualize these results using the Tethys platform"
path: runTeehr.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "\n${INFO_MARK} You can visualize these results using the Tethys platform."
```
created_at: 2025-05-14T17:32:01Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo "${BRed}Failed to ensure directory for config file.${Color_Off}"
```
created_at: 2025-05-14T17:33:27Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
    chmod u+rw "$file" || { echo "${BRed}Could not set file permissions on $file${Color_Off}"; return 1; }
```
created_at: 2025-05-14T17:34:02Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo '{"model_runs":[]}' > "$file" || { echo "${BRed}Could not create file $file${Color_Off}"; return 1; }
```
created_at: 2025-05-14T17:34:20Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry.${Color_Off}"
        show_loading "Downloading Tethys image..." 3
```
created_at: 2025-05-14T17:35:01Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully!${Color_Off}"
```
created_at: 2025-05-14T17:35:13Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed.${Color_Off}"
```
created_at: 2025-05-14T17:36:26Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running.${Color_Off}"
```
created_at: 2025-05-14T17:36:45Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly.${Color_Off}"
```
created_at: 2025-05-14T17:37:00Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running.${Color_Off}"
```
created_at: 2025-05-14T17:37:07Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo "${BRed}Failed to create models directory.${Color_Off}"
```
created_at: 2025-05-14T17:37:27Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
+        return 1
     fi
 
-    # 2) Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
-    local owner_uid=""
-    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
-        :  # GNU stat (Linux)
-    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
-        :  # BSD stat (macOS, Git-Bash)
+    # Derive the target path
+    local base_name
+    base_name="$(basename "$input_path")"
+    local model_run_path="$models_dir/$base_name"
+    
+    # Copy logic - simplified to reduce errors
+    echo -e "${INFO_MARK} ${BWhite}Copying model data to visualization directory...${Color_Off}"
+    
+    # Remove existing directory if it exists
+    if [ -e "$model_run_path" ]; then
+        echo -e "  ${INFO_MARK} ${BYellow}Directory already exists, overwriting...${Color_Off}"
+        rm -rf "$model_run_path"
     fi
-
-    # 3) If the directory is not owned by the current user, try to chown it
-    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
-        if command -v chown >/dev/null 2>&1; then
-            echo -e "${BYellow}Reclaiming ownership of $dir (sudo may prompt)…${Color_Off}"
-            sudo chown -R "$(id -u):$(id -g)" "$dir"
-        fi
+    
+    # Copy the data
+    if cp -r "$input_path" "$models_dir/"; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully!${Color_Off}"
```
created_at: 2025-05-14T17:37:51Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
+        return 1
     fi
 
-    # 2) Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
-    local owner_uid=""
-    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
-        :  # GNU stat (Linux)
-    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
-        :  # BSD stat (macOS, Git-Bash)
+    # Derive the target path
+    local base_name
+    base_name="$(basename "$input_path")"
+    local model_run_path="$models_dir/$base_name"
+    
+    # Copy logic - simplified to reduce errors
+    echo -e "${INFO_MARK} ${BWhite}Copying model data to visualization directory...${Color_Off}"
+    
+    # Remove existing directory if it exists
+    if [ -e "$model_run_path" ]; then
+        echo -e "  ${INFO_MARK} ${BYellow}Directory already exists, overwriting...${Color_Off}"
+        rm -rf "$model_run_path"
     fi
-
-    # 3) If the directory is not owned by the current user, try to chown it
-    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
-        if command -v chown >/dev/null 2>&1; then
-            echo -e "${BYellow}Reclaiming ownership of $dir (sudo may prompt)…${Color_Off}"
-            sudo chown -R "$(id -u):$(id -g)" "$dir"
-        fi
+    
+    # Copy the data
+    if cp -r "$input_path" "$models_dir/"; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully${Color_Off}"
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to copy model data${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CROSS_MARK} ${BRed}Failed to copy model data.${Color_Off}"
```
created_at: 2025-05-14T17:38:00Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
+        return 1
     fi
 
-    # 2) Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
-    local owner_uid=""
-    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
-        :  # GNU stat (Linux)
-    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
-        :  # BSD stat (macOS, Git-Bash)
+    # Derive the target path
+    local base_name
+    base_name="$(basename "$input_path")"
+    local model_run_path="$models_dir/$base_name"
+    
+    # Copy logic - simplified to reduce errors
+    echo -e "${INFO_MARK} ${BWhite}Copying model data to visualization directory...${Color_Off}"
+    
+    # Remove existing directory if it exists
+    if [ -e "$model_run_path" ]; then
+        echo -e "  ${INFO_MARK} ${BYellow}Directory already exists, overwriting...${Color_Off}"
+        rm -rf "$model_run_path"
     fi
-
-    # 3) If the directory is not owned by the current user, try to chown it
-    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
-        if command -v chown >/dev/null 2>&1; then
-            echo -e "${BYellow}Reclaiming ownership of $dir (sudo may prompt)…${Color_Off}"
-            sudo chown -R "$(id -u):$(id -g)" "$dir"
-        fi
+    
+    # Copy the data
+    if cp -r "$input_path" "$models_dir/"; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully${Color_Off}"
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to copy model data${Color_Off}"
+        return 1
     fi
-
-    # 4) Ensure the current user has rwx on the directory
-    chmod u+rwx "$dir"
+    
+    # Output the directory path
+    echo "$model_run_path"
 }
 
-# Ensure a *regular file* exists (and is writable) without touching siblings
-_ensure_visualizer_conf_host_file() {
-    local file="$1"
-    local dir
-    dir=$(dirname "$file")
-
-    # 1) make sure the directory exists and is writable by the user
-    _ensure_host_dir "$dir" || return 1
+add_model_run() {
+    local input_path="$1"
+    local json_file="$VISUALIZER_CONF"
 
-    # 2) create the file if it doesn't exist, and initialise it
-    if [ ! -f "$file" ]; then
-        echo -e "${BRed}File $file does not exist. Creating it...${Color_Off}"
-        echo '{"model_runs":[]}' > "$file"
+    # Ensure JSON file exists
+    if ! ensure_visualizer_conf_host_file "$json_file"; then
+        echo "Failed to create config file"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo "${BRed}Failed to create config file.${Color_Off}"
```
created_at: 2025-05-14T17:38:19Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
+        return 1
     fi
 
-    # 2) Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
-    local owner_uid=""
-    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
-        :  # GNU stat (Linux)
-    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
-        :  # BSD stat (macOS, Git-Bash)
+    # Derive the target path
+    local base_name
+    base_name="$(basename "$input_path")"
+    local model_run_path="$models_dir/$base_name"
+    
+    # Copy logic - simplified to reduce errors
+    echo -e "${INFO_MARK} ${BWhite}Copying model data to visualization directory...${Color_Off}"
+    
+    # Remove existing directory if it exists
+    if [ -e "$model_run_path" ]; then
+        echo -e "  ${INFO_MARK} ${BYellow}Directory already exists, overwriting...${Color_Off}"
+        rm -rf "$model_run_path"
     fi
-
-    # 3) If the directory is not owned by the current user, try to chown it
-    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
-        if command -v chown >/dev/null 2>&1; then
-            echo -e "${BYellow}Reclaiming ownership of $dir (sudo may prompt)…${Color_Off}"
-            sudo chown -R "$(id -u):$(id -g)" "$dir"
-        fi
+    
+    # Copy the data
+    if cp -r "$input_path" "$models_dir/"; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully${Color_Off}"
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to copy model data${Color_Off}"
+        return 1
     fi
-
-    # 4) Ensure the current user has rwx on the directory
-    chmod u+rwx "$dir"
+    
+    # Output the directory path
+    echo "$model_run_path"
 }
 
-# Ensure a *regular file* exists (and is writable) without touching siblings
-_ensure_visualizer_conf_host_file() {
-    local file="$1"
-    local dir
-    dir=$(dirname "$file")
-
-    # 1) make sure the directory exists and is writable by the user
-    _ensure_host_dir "$dir" || return 1
+add_model_run() {
+    local input_path="$1"
+    local json_file="$VISUALIZER_CONF"
 
-    # 2) create the file if it doesn't exist, and initialise it
-    if [ ! -f "$file" ]; then
-        echo -e "${BRed}File $file does not exist. Creating it...${Color_Off}"
-        echo '{"model_runs":[]}' > "$file"
+    # Ensure JSON file exists
+    if ! ensure_visualizer_conf_host_file "$json_file"; then
+        echo "Failed to create config file"
+        return 1
     fi
 
-    # 3) ensure *you* can read/write the file
-    chmod u+rw "$file"
-}
+    # Extract the basename for label
+    local base_name
+    base_name=$(basename "$input_path")
 
+    # Generate a new UUID for the id field - simplified
+    local new_uuid="ngiab-$(date +%Y%m%d%H%M%S)-$(( RANDOM % 1000 ))"
 
-_run_tethys() {
+    # Current date/time
+    local current_time
+    current_time=$(date +"%Y-%m-%d:%H:%M:%S")
 
-    _ensure_host_dir  "$MODELS_RUNS_DIRECTORY"
-    _ensure_host_dir  "$DATASTREAM_DIRECTORY"
-    _ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    # Path for Tethys container
+    local final_path="$TETHYS_PERSIST_PATH/ngiab_visualizer/$base_name"
+    
+    echo -e "${INFO_MARK} ${BWhite}Registering model run in visualization system...${Color_Off}"
+    
+    # Simplified approach - create a new file
+    echo '{"model_runs":[{"label":"'"$base_name"'","path":"'"$final_path"'","date":"'"$current_time"'","id":"'"$new_uuid"'","subset":"","tags":[]}]}' > "$json_file"
+    
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model run registered successfully${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CHECK_MARK} ${BGreen}Model run registered successfully!${Color_Off}"
```
created_at: 2025-05-14T17:38:52Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
+        return 1
     fi
 
-    # 2) Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
-    local owner_uid=""
-    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
-        :  # GNU stat (Linux)
-    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
-        :  # BSD stat (macOS, Git-Bash)
+    # Derive the target path
+    local base_name
+    base_name="$(basename "$input_path")"
+    local model_run_path="$models_dir/$base_name"
+    
+    # Copy logic - simplified to reduce errors
+    echo -e "${INFO_MARK} ${BWhite}Copying model data to visualization directory...${Color_Off}"
+    
+    # Remove existing directory if it exists
+    if [ -e "$model_run_path" ]; then
+        echo -e "  ${INFO_MARK} ${BYellow}Directory already exists, overwriting...${Color_Off}"
+        rm -rf "$model_run_path"
     fi
-
-    # 3) If the directory is not owned by the current user, try to chown it
-    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
-        if command -v chown >/dev/null 2>&1; then
-            echo -e "${BYellow}Reclaiming ownership of $dir (sudo may prompt)…${Color_Off}"
-            sudo chown -R "$(id -u):$(id -g)" "$dir"
-        fi
+    
+    # Copy the data
+    if cp -r "$input_path" "$models_dir/"; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully${Color_Off}"
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to copy model data${Color_Off}"
+        return 1
     fi
-
-    # 4) Ensure the current user has rwx on the directory
-    chmod u+rwx "$dir"
+    
+    # Output the directory path
+    echo "$model_run_path"
 }
 
-# Ensure a *regular file* exists (and is writable) without touching siblings
-_ensure_visualizer_conf_host_file() {
-    local file="$1"
-    local dir
-    dir=$(dirname "$file")
-
-    # 1) make sure the directory exists and is writable by the user
-    _ensure_host_dir "$dir" || return 1
+add_model_run() {
+    local input_path="$1"
+    local json_file="$VISUALIZER_CONF"
 
-    # 2) create the file if it doesn't exist, and initialise it
-    if [ ! -f "$file" ]; then
-        echo -e "${BRed}File $file does not exist. Creating it...${Color_Off}"
-        echo '{"model_runs":[]}' > "$file"
+    # Ensure JSON file exists
+    if ! ensure_visualizer_conf_host_file "$json_file"; then
+        echo "Failed to create config file"
+        return 1
     fi
 
-    # 3) ensure *you* can read/write the file
-    chmod u+rw "$file"
-}
+    # Extract the basename for label
+    local base_name
+    base_name=$(basename "$input_path")
 
+    # Generate a new UUID for the id field - simplified
+    local new_uuid="ngiab-$(date +%Y%m%d%H%M%S)-$(( RANDOM % 1000 ))"
 
-_run_tethys() {
+    # Current date/time
+    local current_time
+    current_time=$(date +"%Y-%m-%d:%H:%M:%S")
 
-    _ensure_host_dir  "$MODELS_RUNS_DIRECTORY"
-    _ensure_host_dir  "$DATASTREAM_DIRECTORY"
-    _ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    # Path for Tethys container
+    local final_path="$TETHYS_PERSIST_PATH/ngiab_visualizer/$base_name"
+    
+    echo -e "${INFO_MARK} ${BWhite}Registering model run in visualization system...${Color_Off}"
+    
+    # Simplified approach - create a new file
+    echo '{"model_runs":[{"label":"'"$base_name"'","path":"'"$final_path"'","date":"'"$current_time"'","id":"'"$new_uuid"'","subset":"","tags":[]}]}' > "$json_file"
+    
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model run registered successfully${Color_Off}"
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to register model run${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CROSS_MARK} ${BRed}Failed to register model run.${Color_Off}"
```
created_at: 2025-05-14T17:39:00Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
+        return 1
     fi
 
-    # 2) Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
-    local owner_uid=""
-    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
-        :  # GNU stat (Linux)
-    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
-        :  # BSD stat (macOS, Git-Bash)
+    # Derive the target path
+    local base_name
+    base_name="$(basename "$input_path")"
+    local model_run_path="$models_dir/$base_name"
+    
+    # Copy logic - simplified to reduce errors
+    echo -e "${INFO_MARK} ${BWhite}Copying model data to visualization directory...${Color_Off}"
+    
+    # Remove existing directory if it exists
+    if [ -e "$model_run_path" ]; then
+        echo -e "  ${INFO_MARK} ${BYellow}Directory already exists, overwriting...${Color_Off}"
+        rm -rf "$model_run_path"
     fi
-
-    # 3) If the directory is not owned by the current user, try to chown it
-    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
-        if command -v chown >/dev/null 2>&1; then
-            echo -e "${BYellow}Reclaiming ownership of $dir (sudo may prompt)…${Color_Off}"
-            sudo chown -R "$(id -u):$(id -g)" "$dir"
-        fi
+    
+    # Copy the data
+    if cp -r "$input_path" "$models_dir/"; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully${Color_Off}"
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to copy model data${Color_Off}"
+        return 1
     fi
-
-    # 4) Ensure the current user has rwx on the directory
-    chmod u+rwx "$dir"
+    
+    # Output the directory path
+    echo "$model_run_path"
 }
 
-# Ensure a *regular file* exists (and is writable) without touching siblings
-_ensure_visualizer_conf_host_file() {
-    local file="$1"
-    local dir
-    dir=$(dirname "$file")
-
-    # 1) make sure the directory exists and is writable by the user
-    _ensure_host_dir "$dir" || return 1
+add_model_run() {
+    local input_path="$1"
+    local json_file="$VISUALIZER_CONF"
 
-    # 2) create the file if it doesn't exist, and initialise it
-    if [ ! -f "$file" ]; then
-        echo -e "${BRed}File $file does not exist. Creating it...${Color_Off}"
-        echo '{"model_runs":[]}' > "$file"
+    # Ensure JSON file exists
+    if ! ensure_visualizer_conf_host_file "$json_file"; then
+        echo "Failed to create config file"
+        return 1
     fi
 
-    # 3) ensure *you* can read/write the file
-    chmod u+rw "$file"
-}
+    # Extract the basename for label
+    local base_name
+    base_name=$(basename "$input_path")
 
+    # Generate a new UUID for the id field - simplified
+    local new_uuid="ngiab-$(date +%Y%m%d%H%M%S)-$(( RANDOM % 1000 ))"
 
-_run_tethys() {
+    # Current date/time
+    local current_time
+    current_time=$(date +"%Y-%m-%d:%H:%M:%S")
 
-    _ensure_host_dir  "$MODELS_RUNS_DIRECTORY"
-    _ensure_host_dir  "$DATASTREAM_DIRECTORY"
-    _ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    # Path for Tethys container
+    local final_path="$TETHYS_PERSIST_PATH/ngiab_visualizer/$base_name"
+    
+    echo -e "${INFO_MARK} ${BWhite}Registering model run in visualization system...${Color_Off}"
+    
+    # Simplified approach - create a new file
+    echo '{"model_runs":[{"label":"'"$base_name"'","path":"'"$final_path"'","date":"'"$current_time"'","id":"'"$new_uuid"'","subset":"","tags":[]}]}' > "$json_file"
+    
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model run registered successfully${Color_Off}"
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to register model run${Color_Off}"
+        return 1
+    fi
+}
 
-    _execute_command docker run --rm -it -d \
+run_tethys() {
+    ensure_host_dir "$MODELS_RUNS_DIRECTORY"
+    ensure_host_dir "$DATASTREAM_DIRECTORY"
+    ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    
+    echo -e "${ARROW} ${BWhite}Launching Tethys container...${Color_Off}"
+    
+    # First, make sure any existing Tethys containers are stopped
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys container is already running. Stopping it first...${Color_Off}"
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 3
+    fi
+    
+    # Final check - if container still exists, force removal
+    if docker ps -a -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${WARNING_MARK} ${BYellow}Forcibly removing container...${Color_Off}"
+        docker rm -f "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1 || true
+        sleep 2
+    fi
+    
+    # Create new network
+    create_tethys_docker_network
+    
+    # Brief delay before starting
+    sleep 1
+    echo -e "  ${INFO_MARK} ${BYellow}Starting Tethys container...${Color_Off}"
+    
+    # Launch container with explicit error handling
+    echo -e "  ${INFO_MARK} Running docker command..."
+    docker run --rm -d \
         -v "$MODELS_RUNS_DIRECTORY:$TETHYS_PERSIST_PATH/ngiab_visualizer" \
         -v "$DATASTREAM_DIRECTORY:$TETHYS_PERSIST_PATH/.datastream_ngiab" \
-        -p $NGINX_TETHYS_PORT:$NGINX_TETHYS_PORT \
-        --platform "$PLATFORM" \
+        -p "$NGINX_TETHYS_PORT:$NGINX_TETHYS_PORT" \
         --network "$DOCKER_NETWORK" \
         --name "$TETHYS_CONTAINER_NAME" \
         --env MEDIA_ROOT="$TETHYS_PERSIST_PATH/media" \
         --env MEDIA_URL="/media/" \
         --env SKIP_DB_SETUP="$SKIP_DB_SETUP" \
         --env DATASTREAM_CONF="$TETHYS_PERSIST_PATH/.datastream_ngiab" \
         --env VISUALIZER_CONF="$TETHYS_PERSIST_PATH/ngiab_visualizer/ngiab_visualizer.json" \
-        --env NGINX_PORT=$NGINX_TETHYS_PORT \
-        --env CSRF_TRUSTED_ORIGINS=$CSRF_TRUSTED_ORIGINS \
-        "$TETHYS_IMAGE_NAME" \
-        > /dev/null 2>&1
-}
-
-
-_copy_models_run() {
-    local input_path="$1"
-    local models_dir="$HOME/ngiab_visualizer"
-    # 1) make sure ~/ngiab_visualizer exists and you own it
-    _ensure_host_dir "$models_dir" || {
-        echo -e "${BRed}Failed to create or fix permissions on $models_dir${Color_Off}" >&2
-        return 1
-    }
-
-    # 2) derive the target path
-    local base_name
-    base_name="$(basename "$input_path")"
-    local model_run_path="$models_dir/$base_name"
-    local final_copied_path="$model_run_path"
-
-    # 3) copy logic
-    if [ ! -e "$model_run_path" ]; then
-        cp -r "$input_path" "$models_dir" || {
-            echo -e "${BRed}Error: Could not copy $input_path → $models_dir${Color_Off}" >&2
-            return 1
-        }
-        echo -e "${BCyan}Copied: $input_path → $model_run_path${Color_Off}" >&2
+        --env NGINX_PORT="$NGINX_TETHYS_PORT" \
+        --env CSRF_TRUSTED_ORIGINS="$CSRF_TRUSTED_ORIGINS" \
+        "${TETHYS_REPO}:${TETHYS_TAG}"
+        
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys container started successfully${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CHECK_MARK} ${BGreen}Tethys container started successfully.${Color_Off}"
```
created_at: 2025-05-14T17:39:26Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
+        return 1
     fi
 
-    # 2) Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
-    local owner_uid=""
-    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
-        :  # GNU stat (Linux)
-    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
-        :  # BSD stat (macOS, Git-Bash)
+    # Derive the target path
+    local base_name
+    base_name="$(basename "$input_path")"
+    local model_run_path="$models_dir/$base_name"
+    
+    # Copy logic - simplified to reduce errors
+    echo -e "${INFO_MARK} ${BWhite}Copying model data to visualization directory...${Color_Off}"
+    
+    # Remove existing directory if it exists
+    if [ -e "$model_run_path" ]; then
+        echo -e "  ${INFO_MARK} ${BYellow}Directory already exists, overwriting...${Color_Off}"
+        rm -rf "$model_run_path"
     fi
-
-    # 3) If the directory is not owned by the current user, try to chown it
-    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
-        if command -v chown >/dev/null 2>&1; then
-            echo -e "${BYellow}Reclaiming ownership of $dir (sudo may prompt)…${Color_Off}"
-            sudo chown -R "$(id -u):$(id -g)" "$dir"
-        fi
+    
+    # Copy the data
+    if cp -r "$input_path" "$models_dir/"; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully${Color_Off}"
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to copy model data${Color_Off}"
+        return 1
     fi
-
-    # 4) Ensure the current user has rwx on the directory
-    chmod u+rwx "$dir"
+    
+    # Output the directory path
+    echo "$model_run_path"
 }
 
-# Ensure a *regular file* exists (and is writable) without touching siblings
-_ensure_visualizer_conf_host_file() {
-    local file="$1"
-    local dir
-    dir=$(dirname "$file")
-
-    # 1) make sure the directory exists and is writable by the user
-    _ensure_host_dir "$dir" || return 1
+add_model_run() {
+    local input_path="$1"
+    local json_file="$VISUALIZER_CONF"
 
-    # 2) create the file if it doesn't exist, and initialise it
-    if [ ! -f "$file" ]; then
-        echo -e "${BRed}File $file does not exist. Creating it...${Color_Off}"
-        echo '{"model_runs":[]}' > "$file"
+    # Ensure JSON file exists
+    if ! ensure_visualizer_conf_host_file "$json_file"; then
+        echo "Failed to create config file"
+        return 1
     fi
 
-    # 3) ensure *you* can read/write the file
-    chmod u+rw "$file"
-}
+    # Extract the basename for label
+    local base_name
+    base_name=$(basename "$input_path")
 
+    # Generate a new UUID for the id field - simplified
+    local new_uuid="ngiab-$(date +%Y%m%d%H%M%S)-$(( RANDOM % 1000 ))"
 
-_run_tethys() {
+    # Current date/time
+    local current_time
+    current_time=$(date +"%Y-%m-%d:%H:%M:%S")
 
-    _ensure_host_dir  "$MODELS_RUNS_DIRECTORY"
-    _ensure_host_dir  "$DATASTREAM_DIRECTORY"
-    _ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    # Path for Tethys container
+    local final_path="$TETHYS_PERSIST_PATH/ngiab_visualizer/$base_name"
+    
+    echo -e "${INFO_MARK} ${BWhite}Registering model run in visualization system...${Color_Off}"
+    
+    # Simplified approach - create a new file
+    echo '{"model_runs":[{"label":"'"$base_name"'","path":"'"$final_path"'","date":"'"$current_time"'","id":"'"$new_uuid"'","subset":"","tags":[]}]}' > "$json_file"
+    
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model run registered successfully${Color_Off}"
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to register model run${Color_Off}"
+        return 1
+    fi
+}
 
-    _execute_command docker run --rm -it -d \
+run_tethys() {
+    ensure_host_dir "$MODELS_RUNS_DIRECTORY"
+    ensure_host_dir "$DATASTREAM_DIRECTORY"
+    ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    
+    echo -e "${ARROW} ${BWhite}Launching Tethys container...${Color_Off}"
+    
+    # First, make sure any existing Tethys containers are stopped
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys container is already running. Stopping it first...${Color_Off}"
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 3
+    fi
+    
+    # Final check - if container still exists, force removal
+    if docker ps -a -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${WARNING_MARK} ${BYellow}Forcibly removing container...${Color_Off}"
+        docker rm -f "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1 || true
+        sleep 2
+    fi
+    
+    # Create new network
+    create_tethys_docker_network
+    
+    # Brief delay before starting
+    sleep 1
+    echo -e "  ${INFO_MARK} ${BYellow}Starting Tethys container...${Color_Off}"
+    
+    # Launch container with explicit error handling
+    echo -e "  ${INFO_MARK} Running docker command..."
+    docker run --rm -d \
         -v "$MODELS_RUNS_DIRECTORY:$TETHYS_PERSIST_PATH/ngiab_visualizer" \
         -v "$DATASTREAM_DIRECTORY:$TETHYS_PERSIST_PATH/.datastream_ngiab" \
-        -p $NGINX_TETHYS_PORT:$NGINX_TETHYS_PORT \
-        --platform "$PLATFORM" \
+        -p "$NGINX_TETHYS_PORT:$NGINX_TETHYS_PORT" \
         --network "$DOCKER_NETWORK" \
         --name "$TETHYS_CONTAINER_NAME" \
         --env MEDIA_ROOT="$TETHYS_PERSIST_PATH/media" \
         --env MEDIA_URL="/media/" \
         --env SKIP_DB_SETUP="$SKIP_DB_SETUP" \
         --env DATASTREAM_CONF="$TETHYS_PERSIST_PATH/.datastream_ngiab" \
         --env VISUALIZER_CONF="$TETHYS_PERSIST_PATH/ngiab_visualizer/ngiab_visualizer.json" \
-        --env NGINX_PORT=$NGINX_TETHYS_PORT \
-        --env CSRF_TRUSTED_ORIGINS=$CSRF_TRUSTED_ORIGINS \
-        "$TETHYS_IMAGE_NAME" \
-        > /dev/null 2>&1
-}
-
-
-_copy_models_run() {
-    local input_path="$1"
-    local models_dir="$HOME/ngiab_visualizer"
-    # 1) make sure ~/ngiab_visualizer exists and you own it
-    _ensure_host_dir "$models_dir" || {
-        echo -e "${BRed}Failed to create or fix permissions on $models_dir${Color_Off}" >&2
-        return 1
-    }
-
-    # 2) derive the target path
-    local base_name
-    base_name="$(basename "$input_path")"
-    local model_run_path="$models_dir/$base_name"
-    local final_copied_path="$model_run_path"
-
-    # 3) copy logic
-    if [ ! -e "$model_run_path" ]; then
-        cp -r "$input_path" "$models_dir" || {
-            echo -e "${BRed}Error: Could not copy $input_path → $models_dir${Color_Off}" >&2
-            return 1
-        }
-        echo -e "${BCyan}Copied: $input_path → $model_run_path${Color_Off}" >&2
+        --env NGINX_PORT="$NGINX_TETHYS_PORT" \
+        --env CSRF_TRUSTED_ORIGINS="$CSRF_TRUSTED_ORIGINS" \
+        "${TETHYS_REPO}:${TETHYS_TAG}"
+        
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys container started successfully${Color_Off}"
+        return 0
     else
-        echo -e "${BYellow}Directory '$model_run_path' already exists.${Color_Off}" >&2
-        while true; do
-            echo -ne "${BYellow}Overwrite (O) or copy with different name (D)? [O/D]: ${Color_Off}" >&2
-            read -r choice < /dev/tty
-            case "$choice" in
-                [Oo]* )
-                    rm -rf "$model_run_path"
-                    cp -r "$input_path" "$models_dir" || {
-                        echo -e "${BRed}Error: Could not overwrite $model_run_path${Color_Off}" >&2
-                        return 1
-                    }
-                    echo -e "${BCyan}Overwritten with: $input_path → $model_run_path${Color_Off}" >&2
-                    break
-                    ;;
-                [Dd]* )
-                    echo -ne "${BBlue}Enter a new directory name: ${Color_Off}" >&2
-                    read -r new_name < /dev/tty
-                    if [ -z "$new_name" ]; then
-                        echo -e "${BRed}No name entered. Try again.${Color_Off}" >&2
-                        continue
-                    fi
-                    local new_path="$models_dir/$new_name"
-                    if [ -e "$new_path" ]; then
-                        echo -e "${BRed}'$new_name' already exists. Choose another name.${Color_Off}" >&2
-                        continue
-                    fi
-                    cp -r "$input_path" "$new_path" || {
-                        echo -e "${BRed}Error: Could not copy to $new_path${Color_Off}" >&2
-                        return 1
-                    }
-                    echo -e "${BPurple}Copied to: $new_path${Color_Off}" >&2
-                    final_copied_path="$new_path"
-                    break
-                    ;;
-                * )
-                    echo -e "${BRed}Invalid choice. Enter 'O' or 'D'.${Color_Off}" >&2
-                    ;;
-            esac
-        done
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to start Tethys container${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "  ${CROSS_MARK} ${BRed}Failed to start Tethys container.${Color_Off}"
```
created_at: 2025-05-14T17:39:40Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
+        return 1
     fi
 
-    # 2) Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
-    local owner_uid=""
-    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
-        :  # GNU stat (Linux)
-    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
-        :  # BSD stat (macOS, Git-Bash)
+    # Derive the target path
+    local base_name
+    base_name="$(basename "$input_path")"
+    local model_run_path="$models_dir/$base_name"
+    
+    # Copy logic - simplified to reduce errors
+    echo -e "${INFO_MARK} ${BWhite}Copying model data to visualization directory...${Color_Off}"
+    
+    # Remove existing directory if it exists
+    if [ -e "$model_run_path" ]; then
+        echo -e "  ${INFO_MARK} ${BYellow}Directory already exists, overwriting...${Color_Off}"
+        rm -rf "$model_run_path"
     fi
-
-    # 3) If the directory is not owned by the current user, try to chown it
-    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
-        if command -v chown >/dev/null 2>&1; then
-            echo -e "${BYellow}Reclaiming ownership of $dir (sudo may prompt)…${Color_Off}"
-            sudo chown -R "$(id -u):$(id -g)" "$dir"
-        fi
+    
+    # Copy the data
+    if cp -r "$input_path" "$models_dir/"; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully${Color_Off}"
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to copy model data${Color_Off}"
+        return 1
     fi
-
-    # 4) Ensure the current user has rwx on the directory
-    chmod u+rwx "$dir"
+    
+    # Output the directory path
+    echo "$model_run_path"
 }
 
-# Ensure a *regular file* exists (and is writable) without touching siblings
-_ensure_visualizer_conf_host_file() {
-    local file="$1"
-    local dir
-    dir=$(dirname "$file")
-
-    # 1) make sure the directory exists and is writable by the user
-    _ensure_host_dir "$dir" || return 1
+add_model_run() {
+    local input_path="$1"
+    local json_file="$VISUALIZER_CONF"
 
-    # 2) create the file if it doesn't exist, and initialise it
-    if [ ! -f "$file" ]; then
-        echo -e "${BRed}File $file does not exist. Creating it...${Color_Off}"
-        echo '{"model_runs":[]}' > "$file"
+    # Ensure JSON file exists
+    if ! ensure_visualizer_conf_host_file "$json_file"; then
+        echo "Failed to create config file"
+        return 1
     fi
 
-    # 3) ensure *you* can read/write the file
-    chmod u+rw "$file"
-}
+    # Extract the basename for label
+    local base_name
+    base_name=$(basename "$input_path")
 
+    # Generate a new UUID for the id field - simplified
+    local new_uuid="ngiab-$(date +%Y%m%d%H%M%S)-$(( RANDOM % 1000 ))"
 
-_run_tethys() {
+    # Current date/time
+    local current_time
+    current_time=$(date +"%Y-%m-%d:%H:%M:%S")
 
-    _ensure_host_dir  "$MODELS_RUNS_DIRECTORY"
-    _ensure_host_dir  "$DATASTREAM_DIRECTORY"
-    _ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    # Path for Tethys container
+    local final_path="$TETHYS_PERSIST_PATH/ngiab_visualizer/$base_name"
+    
+    echo -e "${INFO_MARK} ${BWhite}Registering model run in visualization system...${Color_Off}"
+    
+    # Simplified approach - create a new file
+    echo '{"model_runs":[{"label":"'"$base_name"'","path":"'"$final_path"'","date":"'"$current_time"'","id":"'"$new_uuid"'","subset":"","tags":[]}]}' > "$json_file"
+    
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model run registered successfully${Color_Off}"
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to register model run${Color_Off}"
+        return 1
+    fi
+}
 
-    _execute_command docker run --rm -it -d \
+run_tethys() {
+    ensure_host_dir "$MODELS_RUNS_DIRECTORY"
+    ensure_host_dir "$DATASTREAM_DIRECTORY"
+    ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    
+    echo -e "${ARROW} ${BWhite}Launching Tethys container...${Color_Off}"
+    
+    # First, make sure any existing Tethys containers are stopped
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys container is already running. Stopping it first...${Color_Off}"
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 3
+    fi
+    
+    # Final check - if container still exists, force removal
+    if docker ps -a -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${WARNING_MARK} ${BYellow}Forcibly removing container...${Color_Off}"
+        docker rm -f "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1 || true
+        sleep 2
+    fi
+    
+    # Create new network
+    create_tethys_docker_network
+    
+    # Brief delay before starting
+    sleep 1
+    echo -e "  ${INFO_MARK} ${BYellow}Starting Tethys container...${Color_Off}"
+    
+    # Launch container with explicit error handling
+    echo -e "  ${INFO_MARK} Running docker command..."
+    docker run --rm -d \
         -v "$MODELS_RUNS_DIRECTORY:$TETHYS_PERSIST_PATH/ngiab_visualizer" \
         -v "$DATASTREAM_DIRECTORY:$TETHYS_PERSIST_PATH/.datastream_ngiab" \
-        -p $NGINX_TETHYS_PORT:$NGINX_TETHYS_PORT \
-        --platform "$PLATFORM" \
+        -p "$NGINX_TETHYS_PORT:$NGINX_TETHYS_PORT" \
         --network "$DOCKER_NETWORK" \
         --name "$TETHYS_CONTAINER_NAME" \
         --env MEDIA_ROOT="$TETHYS_PERSIST_PATH/media" \
         --env MEDIA_URL="/media/" \
         --env SKIP_DB_SETUP="$SKIP_DB_SETUP" \
         --env DATASTREAM_CONF="$TETHYS_PERSIST_PATH/.datastream_ngiab" \
         --env VISUALIZER_CONF="$TETHYS_PERSIST_PATH/ngiab_visualizer/ngiab_visualizer.json" \
-        --env NGINX_PORT=$NGINX_TETHYS_PORT \
-        --env CSRF_TRUSTED_ORIGINS=$CSRF_TRUSTED_ORIGINS \
-        "$TETHYS_IMAGE_NAME" \
-        > /dev/null 2>&1
-}
-
-
-_copy_models_run() {
-    local input_path="$1"
-    local models_dir="$HOME/ngiab_visualizer"
-    # 1) make sure ~/ngiab_visualizer exists and you own it
-    _ensure_host_dir "$models_dir" || {
-        echo -e "${BRed}Failed to create or fix permissions on $models_dir${Color_Off}" >&2
-        return 1
-    }
-
-    # 2) derive the target path
-    local base_name
-    base_name="$(basename "$input_path")"
-    local model_run_path="$models_dir/$base_name"
-    local final_copied_path="$model_run_path"
-
-    # 3) copy logic
-    if [ ! -e "$model_run_path" ]; then
-        cp -r "$input_path" "$models_dir" || {
-            echo -e "${BRed}Error: Could not copy $input_path → $models_dir${Color_Off}" >&2
-            return 1
-        }
-        echo -e "${BCyan}Copied: $input_path → $model_run_path${Color_Off}" >&2
+        --env NGINX_PORT="$NGINX_TETHYS_PORT" \
+        --env CSRF_TRUSTED_ORIGINS="$CSRF_TRUSTED_ORIGINS" \
+        "${TETHYS_REPO}:${TETHYS_TAG}"
+        
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys container started successfully${Color_Off}"
+        return 0
     else
-        echo -e "${BYellow}Directory '$model_run_path' already exists.${Color_Off}" >&2
-        while true; do
-            echo -ne "${BYellow}Overwrite (O) or copy with different name (D)? [O/D]: ${Color_Off}" >&2
-            read -r choice < /dev/tty
-            case "$choice" in
-                [Oo]* )
-                    rm -rf "$model_run_path"
-                    cp -r "$input_path" "$models_dir" || {
-                        echo -e "${BRed}Error: Could not overwrite $model_run_path${Color_Off}" >&2
-                        return 1
-                    }
-                    echo -e "${BCyan}Overwritten with: $input_path → $model_run_path${Color_Off}" >&2
-                    break
-                    ;;
-                [Dd]* )
-                    echo -ne "${BBlue}Enter a new directory name: ${Color_Off}" >&2
-                    read -r new_name < /dev/tty
-                    if [ -z "$new_name" ]; then
-                        echo -e "${BRed}No name entered. Try again.${Color_Off}" >&2
-                        continue
-                    fi
-                    local new_path="$models_dir/$new_name"
-                    if [ -e "$new_path" ]; then
-                        echo -e "${BRed}'$new_name' already exists. Choose another name.${Color_Off}" >&2
-                        continue
-                    fi
-                    cp -r "$input_path" "$new_path" || {
-                        echo -e "${BRed}Error: Could not copy to $new_path${Color_Off}" >&2
-                        return 1
-                    }
-                    echo -e "${BPurple}Copied to: $new_path${Color_Off}" >&2
-                    final_copied_path="$new_path"
-                    break
-                    ;;
-                * )
-                    echo -e "${BRed}Invalid choice. Enter 'O' or 'D'.${Color_Off}" >&2
-                    ;;
-            esac
-        done
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to start Tethys container${Color_Off}"
+        return 1
     fi
-
-    # 4) output the directory the caller should register
-    echo "$final_copied_path"
 }
 
-_add_model_run() {
-  local input_path="$1"
-  local json_file="$VISUALIZER_CONF"
-
-  # 1) Ensure $json_file exists
-  echo -e "${BGreen}Checking for $json_file...${Color_Off}"
-  if [ ! -f "$json_file" ]; then
-    echo '{"model_runs":[]}' > "$json_file"
-  fi
-
-  # 2) Extract the basename for label
-  local base_name
-  base_name=$(basename "$input_path")
-
-  # Generate a new UUID for the id field
-  local new_uuid
-  new_uuid=$(uuidgen)
-
-  # Current date/time (adjust format as needed)
-  local current_time
-  current_time=$(date +"%Y-%m-%d:%H:%M:%S")
-
-  # Always use /var/lib/tethys_persist/ngiab_visualizer as the base directory
-  local final_path="/var/lib/tethys_persist/ngiab_visualizer/$base_name"
-  jq --arg base_name "$base_name" \
-     --arg final_path  "$final_path" \
-     --arg current_time  "$current_time" \
-     --arg uuid    "$new_uuid" \
-     '.model_runs += [ 
-       { 
-         "label": $base_name, 
-         "path": $final_path, 
-         "date": $current_time, 
-         "id": $uuid, 
-         "subset": "", 
-         "tags": [] 
-       }
-     ]' \
-     "$json_file" > "${json_file}.tmp" && mv -f "${json_file}.tmp" "$json_file"
+pause_script_execution() {
+    echo -e "\n${BG_Blue}${BWhite} Tethys is now running ${Color_Off}"
+    echo -e "${INFO_MARK} Access the visualization at: ${UBlue}http://localhost:$NGINX_TETHYS_PORT/apps/ngiab${Color_Off}"
+    echo -e "${INFO_MARK} Press ${BWhite}Ctrl+C${Color_Off} to stop Tethys when you're done."
+    
+    # Keep script running until user interrupts
+    while true; do
+        sleep 10
+    done
 }
 
-create_tethys_portal(){
-    while true; do
-        echo -e "${BYellow}Visualize outputs using the Tethys Platform (https://www.tethysplatform.org/)? (Y/n, default: n):${Color_Off}"
-        read -r visualization_choice
-        
-        # Default to 'n' if input is empty
-        if [[ -z "$visualization_choice" ]]; then
-            visualization_choice="n"
-        fi
+# Main script execution
+print_welcome_banner
 
-        # Check for valid input
-        if [[ "$visualization_choice" =~ ^[YyNn]$ ]]; then
-            break
-        else
-            echo -e "${BRed}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (no).${Color_Off}"
-        fi
-    done
-    
-    echo -e "${BYellow}Specify the Tethys image tag to use: ${Color_Off}"
-    read -erp "Tag (e.g. v0.2.1, default: latest): " TETHYS_TAG
-    if [[ -z "$TETHYS_TAG" ]]; then
-        TETHYS_TAG="latest"
-    fi
+# Check if data path is provided as argument
+DATA_FOLDER_PATH="$1"
 
-    # Build the full image reference
-    TETHYS_IMAGE_NAME="${TETHYS_REPO}:${TETHYS_TAG}"    
-
-
-    # Execute the command
-    if [[ "$visualization_choice" =~ ^[Yy]$ ]]; then
-        echo -e "${BGreen}Setting up Tethys Portal image...${Color_Off}"
-        _create_tethys_docker_network
-        if _check_for_existing_tethys_image; then
-            _choose_port_to_run_tethys
-            _execute_command _run_containers
-            _wait_container $TETHYS_CONTAINER_NAME
-            echo -e "${BGreen}Your outputs are ready to be visualized at http://localhost:$NGINX_TETHYS_PORT/apps/ngiab ${Color_Off}"
-            echo -e "${UPurple}You can use the following to login: ${Color_Off}"
-            echo -e "${BCyan}user: admin${Color_Off}"
-            echo -e "${BCyan}password: pass${Color_Off}"
-            echo -e "${UPurple}Check the App source code: https://github.com/CIROH-UA/ngiab-client ${Color_Off}"
-            _pause_script_execution
+if [[ -z "$DATA_FOLDER_PATH" ]]; then
+    # If no path provided, check if we have a saved path
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
         else
-            echo -e "${BRed}Failed to prepare Tethys portal.\n${Color_Off}"
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
         fi
     else
-        echo -e "${BCyan}Skipping Tethys visualization setup.\n${Color_Off}"
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
        echo -e "${INFO_MARK} ${BYellow}No previous configuration found.${Color_Off}"
```
created_at: 2025-05-14T17:40:09Z
author_association: COLLABORATOR
diff_hunk: @@ -17,496 +26,507 @@ UCyan='\033[4;36m'
 UWhite='\033[4;37m'
 Color_Off='\033[0m'
 
+# Extended color palette with 256-color support
+LBLUE='\033[38;5;39m'  # Light blue
+LGREEN='\033[38;5;83m' # Light green 
+LPURPLE='\033[38;5;171m' # Light purple
+LORANGE='\033[38;5;215m' # Light orange
+LTEAL='\033[38;5;87m'  # Light teal
+
+# Background colors for highlighting important messages
+BG_Green='\033[42m'
+BG_Blue='\033[44m'
+BG_Red='\033[41m'
+BG_LBLUE='\033[48;5;117m' # Light blue background
+
+# Symbols for better UI
+CHECK_MARK="${BGreen}✓${Color_Off}"
+CROSS_MARK="${BRed}✗${Color_Off}"
+ARROW="${LORANGE}→${Color_Off}"
+INFO_MARK="${LBLUE}ℹ${Color_Off}"
+WARNING_MARK="${BYellow}⚠${Color_Off}"
+
+# Fix for missing environment variables that might cause display issues
+export TERM=xterm-256color
+
+# Constants
+CONFIG_FILE="$HOME/.host_data_path.conf"
+DOCKER_NETWORK="tethys-network"
+TETHYS_CONTAINER_NAME="tethys-ngen-portal"
+TETHYS_REPO="awiciroh/tethys-ngiab"
+TETHYS_TAG="latest"
+MODELS_RUNS_DIRECTORY="$HOME/ngiab_visualizer"
+DATASTREAM_DIRECTORY="$HOME/.datastream_ngiab"
+VISUALIZER_CONF="$MODELS_RUNS_DIRECTORY/ngiab_visualizer.json"
+TETHYS_PERSIST_PATH="/var/lib/tethys_persist"
+SKIP_DB_SETUP=false
+NGINX_TETHYS_PORT=80
+
+# Disable error trapping initially so we can catch and report errors
+set +e
 
-################################################
-###############HELPER FUNCTIONS#################
-################################################
-# Function to automatically select file if only one is found
-_auto_select_file() {
-  local files=("$@")  # Correct the handling of arguments as an array
-  if [ "${#files[@]}" -eq 1 ]; then
-    echo "${files[0]}"
-  else
-    echo ""
-  fi
+# Function for animated loading with gradient colors
+show_loading() {
+    local message=$1
+    local duration=${2:-3}
+    local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+    local colors=("\033[38;5;39m" "\033[38;5;45m" "\033[38;5;51m" "\033[38;5;87m")
+    local end_time=$((SECONDS + duration))
+    
+    while [ $SECONDS -lt $end_time ]; do
+        for (( i=0; i<${#chars}; i++ )); do
+            color_index=$((i % ${#colors[@]}))
+            echo -ne "\r${colors[$color_index]}${chars:$i:1}${Color_Off} $message"
+            sleep 0.1
+        done
+    done
+    echo -ne "\r${CHECK_MARK} $message - Complete!   \n"
 }
-_check_if_data_folder_exits(){
-    # Check the directory exists
-    if [ ! -d "$DATA_FOLDER_PATH" ]; then
-        echo -e "${BRed}Directory does not exist. Exiting the program.${Color_Off}"
-        exit 0
-    fi
+
+# Function for section headers
+print_section_header() {
+    local title=$1
+    local width=70
+    local padding=$(( (width - ${#title}) / 2 ))
+    
+    # Create a more visually appealing section header with light blue background
+    echo -e "\n\033[48;5;117m$(printf "%${width}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${padding}s" " ")${BWhite}${title}$(printf "%${padding}s" " ")\033[0m"
+    echo -e "\033[48;5;117m$(printf "%${width}s" " ")\033[0m\n"
 }
 
-# Check if the config file exists and read from it
-_check_and_read_config() {
-    local config_file="$1"
-    if [ -f "$config_file" ]; then
-        local last_path=$(cat "$config_file")
-        echo -e "Last used data directory path: %s\n" "$last_path${Color_Off}"
-        read -erp "Do you want to use the same path? (Y/n): " use_last_path
-        
-        if [[ "$use_last_path" =~ ^[Yy] ]]; then
-            DATA_FOLDER_PATH="$last_path"
-            _check_if_data_folder_exits
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            return 0
-        elif [[ "$use_last_path" =~ ^[Nn] ]]; then
-            read -erp "Enter your input data directory path (use absolute path): " DATA_FOLDER_PATH
-            _check_if_data_folder_exits
-            # Save the new path to the config file
-            echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
-            final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-            _add_model_run "$final_dir"
-            echo -e "The Directory you've given is:\n$DATA_FOLDER_PATH\n${Color_Off}"   
-        else
-            echo -e "Invalid input. Exiting.\n${Color_Off}" >&2
-            return 1
-        fi
-    fi
+# Simple banner without complex formatting
+print_welcome_banner() {
+    clear
+    echo -e "\n"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "${BBlue}|  CIROH: NextGen In A Box (NGIAB) - Tethys     |${Color_Off}"
+    echo -e "${BBlue}|  Interactive Model Output Visualization       |${Color_Off}"
+    echo -e "${BBlue}=================================================${Color_Off}"
+    echo -e "\n${INFO_MARK} ${BWhite}Developed by CIROH${Color_Off}\n"
+    sleep 1
 }
 
-_execute_command() {
-  "$@"
-  local status=$?
-  if [ $status -ne 0 ]; then
-    echo -e "${BRed}Error executing command: $1${Color_Off}"
-    _tear_down
+# Function for error handling
+handle_error() {
+    echo -e "\n${BG_Red}${BWhite} ERROR: $1 ${Color_Off}"
+    # Save error to log file
+    echo "$(date): ERROR: $1" >> ~/ngiab_tethys_error.log
+    
+    # Be sure to clean up resources even on error
+    tear_down
     exit 1
-  fi
-  return $status
 }
 
-_tear_down(){
-    _tear_down_tethys
-    docker network rm $DOCKER_NETWORK > /dev/null 2>&1
+# Function to handle the SIGINT (Ctrl-C)
+handle_sigint() {
+    echo -e "\n${BG_Red}${BWhite} Operation cancelled by user. Cleaning up... ${Color_Off}"
+    tear_down
+    exit 1
 }
 
-_run_containers(){
-    _run_tethys
-}
+# Set up trap for signal handlers
+trap handle_sigint INT TERM
+trap 'handle_error "Unexpected error occurred at line $LINENO: $BASH_COMMAND"' ERR
 
-_choose_port_to_run_tethys() {
-    while true; do
-        echo -e "${BBlue}Select a port to run Tethys (default 80): ${Color_Off}"
-        read -erp "Port: " NGINX_TETHYS_PORT
+# Detect platform
+if uname -a | grep -q 'arm64\|aarch64'; then
+    PLATFORM="linux/arm64"
+else
+    PLATFORM="linux/amd64"
+fi
 
-        # Default to 80 if the user just hits <Enter>
-        if [[ -z "$NGINX_TETHYS_PORT" ]]; then
-            NGINX_TETHYS_PORT=80
-        fi
+# Main functions
+ensure_host_dir() {
+    local dir="$1"
 
-        # Validate numeric port 1-65535
-        if ! [[ "$NGINX_TETHYS_PORT" =~ ^[0-9]+$ ]] || \
-           [ "$NGINX_TETHYS_PORT" -lt 1 ] || [ "$NGINX_TETHYS_PORT" -gt 65535 ]; then
-            echo -e "${BRed}Invalid port number. Please enter 1-65535.${Color_Off}"
-            continue
-        fi
+    # Create the directory if it doesn't exist
+    if [ ! -d "$dir" ]; then
+        echo -e "${INFO_MARK} Directory ${BWhite}$dir${Color_Off} doesn't exist — creating it..."
+        mkdir -p "$dir" || { echo "Could not create directory $dir"; return 1; }
+    fi
 
-        # Check if the port is already in use (skip check if lsof not present)
-        if command -v lsof >/dev/null && lsof -i:"$NGINX_TETHYS_PORT" >/dev/null 2>&1; then
-            echo -e "${BRed}Port $NGINX_TETHYS_PORT is already in use. Choose another.${Color_Off}"
-            continue
+    # Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
+    local owner_uid=""
+    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
+        :  # GNU stat (Linux)
+    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
+        :  # BSD stat (macOS, Git-Bash)
+    fi
+
+    # If the directory is not owned by the current user, try to chown it
+    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
+        if command -v chown >/dev/null 2>&1; then
+            echo -e "${INFO_MARK} ${BYellow}Reclaiming ownership of $dir (sudo may prompt)...${Color_Off}"
+            sudo chown -R "$(id -u):$(id -g)" "$dir" || echo -e "${WARNING_MARK} Could not change directory ownership."
         fi
-        CSRF_TRUSTED_ORIGINS="[http://localhost:${NGINX_TETHYS_PORT},http://127.0.0.1:${NGINX_TETHYS_PORT}]"
+    fi
 
-        break
-    done
+    # Ensure the current user has rwx on the directory
+    chmod u+rwx "$dir" || { echo "Could not set directory permissions on $dir"; return 1; }
+    return 0
 }
 
-# Wait for a Docker container to become healthy
-_wait_container() {
-    local container_name=$1
-    local container_health_status=""
-    local attempt_counter=0
-
-    echo -e "${UPurple}Waiting for container: $container_name to become healthy. This can take a couple of minutes...\n${Color_Off}"
-
-    while true; do
-        # Update the health status
-        container_health_status=$(docker inspect -f '{{.State.Health.Status}}' "$container_name" 2>/dev/null)
-
-        if [ $? -ne 0 ]; then
-            echo -e "${BRed}Failed to get health status for container $container_name. Ensure the container exists and has a health check.\n${Color_Off}" >&2
-            return 1
-        fi
-
-        if [[ "$container_health_status" == "healthy" ]]; then
-            echo -e "${BCyan}Container $container_name is now healthy.\n${Color_Off}"
-            return 0
-        elif [[ "$container_health_status" == "unhealthy" ]]; then
-            echo -e "${BRed}Container $container_name is unhealthy.\n${Color_Off}" >&2
-            return 1
-        elif [[ -z "$container_health_status" ]]; then
-            echo -e "${BRed}No health status available for container $container_name. Ensure the container has a health check configured.\n${Color_Off}" >&2
-            return 1
-        fi
+ensure_visualizer_conf_host_file() {
+    local file="$1"
+    local dir
+    dir=$(dirname "$file")
 
-        ((attempt_counter++))
-        sleep 2  # Adjust the sleep time as needed
-    done
-}
+    # Make sure the directory exists and is writable by the user
+    if ! ensure_host_dir "$dir"; then
+        echo "Failed to ensure directory for config file"
+        return 1
+    fi
 
-_pause_script_execution() {
-    while true; do
-        echo -e "${BYellow}Press q to exit the visualization (default: q/Q):\n${Color_Off}"
-        read -r exit_choice
+    # Create the file if it doesn't exist, and initialize it
+    if [ ! -f "$file" ]; then
+        echo -e "${INFO_MARK} Creating configuration file ${BWhite}$file${Color_Off}..."
+        echo '{"model_runs":[]}' > "$file" || { echo "Could not create file $file"; return 1; }
+    fi
 
-        if [[ "$exit_choice" =~ ^[qQ]$ ]]; then
-            echo -e "${BRed}Cleaning up Tethys ...\n${Color_Off}"
-            _tear_down
-            exit 0
-        else
-            echo -e "${BRed}Invalid input. Please press 'q' or 'Q' to exit.\n${Color_Off}"
-        fi
-    done
+    # Ensure the user can read/write the file
+    chmod u+rw "$file" || { echo "Could not set file permissions on $file"; return 1; }
+    return 0
 }
 
-# Function to handle the SIGINT (Ctrl-C)
-handle_sigint() {
-    echo -e "${BRed}Cleaning up . . .${Color_Off}"
-    _tear_down
-    exit 1
+create_tethys_docker_network() {
+    echo -e "${INFO_MARK} Setting up Docker network for Tethys..."
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if network already exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} already exists."
+        return 0
+    fi
+    
+    # Create the network
+    if docker network create -d bridge "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${CHECK_MARK} Network ${BCyan}$DOCKER_NETWORK${Color_Off} created successfully."
+        # Add a small delay to ensure network is fully created
+        sleep 1
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to create Docker network.${Color_Off}"
+        return 1
+    fi
 }
 
-check_last_path() {
-    if [[ -z "$1" ]]; then
-        _check_and_read_config "$CONFIG_FILE"
-     
+check_for_existing_tethys_image() {
+    # First check if Docker is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "${BRed}Docker daemon is not running or accessible.${Color_Off}"
+        return 1
+    fi
+    
+    # Check if the image exists locally
+    local image_exists=false
+    if docker image inspect "${TETHYS_REPO}:${TETHYS_TAG}" >/dev/null 2>&1; then
+        image_exists=true
+    fi
+    
+    if [ "$image_exists" = true ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Using local Tethys image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+        return 0
     else
-        DATA_FOLDER_PATH="$1"
-        _check_if_data_folder_exits
-        final_dir=$(_copy_models_run "$DATA_FOLDER_PATH")
-        _add_model_run "$final_dir"
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys image not found locally. Pulling from registry...${Color_Off}"
+        show_loading "Downloading Tethys image" 3
+        if ! docker pull "${TETHYS_REPO}:${TETHYS_TAG}"; then
+            echo -e "  ${CROSS_MARK} ${BRed}Failed to pull Docker image: ${TETHYS_REPO}:${TETHYS_TAG}${Color_Off}"
+            return 1
+        fi
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys image downloaded successfully${Color_Off}"
         return 0
     fi
 }
-_get_filename() {
-  local full_path="$1"
-  local filename="${full_path##*/}"
-  echo "$filename"
-}
 
-
-################################################
-###############TETHYS FUNCTIONS#################
-################################################
-
-#create the docker network to communicate between tethys and geoserver
-_create_tethys_docker_network(){
-    network_result=$(_execute_command docker network create -d bridge tethys-network 2>&1)
-    if grep -i "Error" <<< "$network_result"; then
-        echo -e "${BRed}Error while attempting to create Docker network. (Is Docker running?)${Color_Off}"
-        _tear_down
-        exit 1
-    fi
+choose_port_to_run_tethys() {
+    NGINX_TETHYS_PORT=80
+    echo -e "${ARROW} ${BWhite}Using default port 80 for Tethys${Color_Off}"
+    CSRF_TRUSTED_ORIGINS="[\"http://localhost:${NGINX_TETHYS_PORT}\",\"http://127.0.0.1:${NGINX_TETHYS_PORT}\"]"
+    echo -e "  ${CHECK_MARK} ${BGreen}Port $NGINX_TETHYS_PORT selected${Color_Off}"
+    return 0
 }
 
-_check_for_existing_tethys_image() {
-    echo -e "${BYellow}Select an option (type a number): ${Color_Off}\n"
-    options=("Run Tethys using existing local docker image" "Run Tethys after updating to latest docker image" "Exit")
-    select option in "${options[@]}"; do
-        case $option in
-            "Run Tethys using existing local docker image")
-                echo -e "${BGreen}Using local image of the Tethys platform\n${Color_Off}"
-                return 0
-                ;;
-            "Run Tethys after updating to latest docker image")
-                echo -e "${BGreen}Pulling container...${Color_Off}\n"
-                if ! docker pull "$TETHYS_IMAGE_NAME"; then
-                    echo -e "${BRed}Failed to pull Docker image: $TETHYS_IMAGE_NAME\n${Color_Off}" >&2
-                    return 1
-                fi
-                return 0
-                ;;
-            "Exit")
-                echo -e "${BCyan}Have a nice day!${Color_Off}\n"
-                _tear_down
-                exit 0
-                ;;
-            *)
-                echo -e "${BRed}Invalid option $REPLY, 1 to continue with existing local image, 2 to update and run, and 3 to exit\n${Color_Off}"
-                ;;
-        esac
-    done
+tear_down() {
+    echo -e "\n${ARROW} ${BYellow}Cleaning up resources...${Color_Off}"
+    
+    # Check if Docker daemon is running
+    if ! docker info >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Docker daemon is not running, cannot clean up containers.${Color_Off}"
+        return 1
+    fi
+    
+    # Stop the Tethys container if it's running
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Stopping Tethys container..."
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 2
+    fi
+    
+    # Remove the Docker network if it exists
+    if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} Removing Docker network..."
+        docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 || true
+    fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Cleanup completed${Color_Off}"
+    return 0
 }
 
+wait_container() {
+    local container_name=$1
+    local max_attempts=10
+    local attempt_counter=0
 
-_tear_down_tethys(){
-    if [ "$(docker ps -aq -f name=$TETHYS_CONTAINER_NAME)" ]; then
-        docker stop $TETHYS_CONTAINER_NAME > /dev/null 2>&1
+    echo -e "\n${ARROW} ${BWhite}Waiting for Tethys container to start...${Color_Off}"
+    echo -e "  ${INFO_MARK} This may take a few moments."
+    
+    # First check if the container is running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name is not running${Color_Off}"
+        return 1
+    fi
+    
+    # Simple wait to give the container time to initialize
+    sleep 5
+    
+    # Check again if container is still running
+    if ! docker ps -q -f name="$container_name" >/dev/null 2>&1; then
+        echo -e "  ${CROSS_MARK} ${BRed}Container $container_name stopped unexpectedly${Color_Off}"
+        return 1
     fi
+    
+    echo -e "  ${CHECK_MARK} ${BGreen}Tethys is now running${Color_Off}"
+    return 0
 }
 
-
-_ensure_host_dir() {
-    local dir="$1"
-
-    # 1) Create the directory (and parents) if it does not exist
-    if [ ! -d "$dir" ]; then
-        echo -e "${BYellow}Directory $dir doesn’t exist — creating it…${Color_Off}"
-        mkdir -p "$dir"
+copy_models_run() {
+    local input_path="$1"
+    local models_dir="$MODELS_RUNS_DIRECTORY"
+    
+    # Ensure directory exists with correct permissions
+    if ! ensure_host_dir "$models_dir"; then
+        echo "Failed to create models directory"
+        return 1
     fi
 
-    # 2) Get owner UID (portable: Linux uses -c, macOS/BSD uses -f)
-    local owner_uid=""
-    if owner_uid=$(stat -c '%u' "$dir" 2>/dev/null); then
-        :  # GNU stat (Linux)
-    elif owner_uid=$(stat -f '%u' "$dir" 2>/dev/null); then
-        :  # BSD stat (macOS, Git-Bash)
+    # Derive the target path
+    local base_name
+    base_name="$(basename "$input_path")"
+    local model_run_path="$models_dir/$base_name"
+    
+    # Copy logic - simplified to reduce errors
+    echo -e "${INFO_MARK} ${BWhite}Copying model data to visualization directory...${Color_Off}"
+    
+    # Remove existing directory if it exists
+    if [ -e "$model_run_path" ]; then
+        echo -e "  ${INFO_MARK} ${BYellow}Directory already exists, overwriting...${Color_Off}"
+        rm -rf "$model_run_path"
     fi
-
-    # 3) If the directory is not owned by the current user, try to chown it
-    if [[ -n "$owner_uid" && "$owner_uid" != "$(id -u)" ]]; then
-        if command -v chown >/dev/null 2>&1; then
-            echo -e "${BYellow}Reclaiming ownership of $dir (sudo may prompt)…${Color_Off}"
-            sudo chown -R "$(id -u):$(id -g)" "$dir"
-        fi
+    
+    # Copy the data
+    if cp -r "$input_path" "$models_dir/"; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model data copied successfully${Color_Off}"
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to copy model data${Color_Off}"
+        return 1
     fi
-
-    # 4) Ensure the current user has rwx on the directory
-    chmod u+rwx "$dir"
+    
+    # Output the directory path
+    echo "$model_run_path"
 }
 
-# Ensure a *regular file* exists (and is writable) without touching siblings
-_ensure_visualizer_conf_host_file() {
-    local file="$1"
-    local dir
-    dir=$(dirname "$file")
-
-    # 1) make sure the directory exists and is writable by the user
-    _ensure_host_dir "$dir" || return 1
+add_model_run() {
+    local input_path="$1"
+    local json_file="$VISUALIZER_CONF"
 
-    # 2) create the file if it doesn't exist, and initialise it
-    if [ ! -f "$file" ]; then
-        echo -e "${BRed}File $file does not exist. Creating it...${Color_Off}"
-        echo '{"model_runs":[]}' > "$file"
+    # Ensure JSON file exists
+    if ! ensure_visualizer_conf_host_file "$json_file"; then
+        echo "Failed to create config file"
+        return 1
     fi
 
-    # 3) ensure *you* can read/write the file
-    chmod u+rw "$file"
-}
+    # Extract the basename for label
+    local base_name
+    base_name=$(basename "$input_path")
 
+    # Generate a new UUID for the id field - simplified
+    local new_uuid="ngiab-$(date +%Y%m%d%H%M%S)-$(( RANDOM % 1000 ))"
 
-_run_tethys() {
+    # Current date/time
+    local current_time
+    current_time=$(date +"%Y-%m-%d:%H:%M:%S")
 
-    _ensure_host_dir  "$MODELS_RUNS_DIRECTORY"
-    _ensure_host_dir  "$DATASTREAM_DIRECTORY"
-    _ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    # Path for Tethys container
+    local final_path="$TETHYS_PERSIST_PATH/ngiab_visualizer/$base_name"
+    
+    echo -e "${INFO_MARK} ${BWhite}Registering model run in visualization system...${Color_Off}"
+    
+    # Simplified approach - create a new file
+    echo '{"model_runs":[{"label":"'"$base_name"'","path":"'"$final_path"'","date":"'"$current_time"'","id":"'"$new_uuid"'","subset":"","tags":[]}]}' > "$json_file"
+    
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Model run registered successfully${Color_Off}"
+        return 0
+    else
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to register model run${Color_Off}"
+        return 1
+    fi
+}
 
-    _execute_command docker run --rm -it -d \
+run_tethys() {
+    ensure_host_dir "$MODELS_RUNS_DIRECTORY"
+    ensure_host_dir "$DATASTREAM_DIRECTORY"
+    ensure_visualizer_conf_host_file "$VISUALIZER_CONF"
+    
+    echo -e "${ARROW} ${BWhite}Launching Tethys container...${Color_Off}"
+    
+    # First, make sure any existing Tethys containers are stopped
+    if docker ps -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${INFO_MARK} ${BYellow}Tethys container is already running. Stopping it first...${Color_Off}"
+        docker stop "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1
+        sleep 3
+    fi
+    
+    # Final check - if container still exists, force removal
+    if docker ps -a -q -f name="$TETHYS_CONTAINER_NAME" >/dev/null 2>&1; then
+        echo -e "  ${WARNING_MARK} ${BYellow}Forcibly removing container...${Color_Off}"
+        docker rm -f "$TETHYS_CONTAINER_NAME" >/dev/null 2>&1 || true
+        sleep 2
+    fi
+    
+    # Create new network
+    create_tethys_docker_network
+    
+    # Brief delay before starting
+    sleep 1
+    echo -e "  ${INFO_MARK} ${BYellow}Starting Tethys container...${Color_Off}"
+    
+    # Launch container with explicit error handling
+    echo -e "  ${INFO_MARK} Running docker command..."
+    docker run --rm -d \
         -v "$MODELS_RUNS_DIRECTORY:$TETHYS_PERSIST_PATH/ngiab_visualizer" \
         -v "$DATASTREAM_DIRECTORY:$TETHYS_PERSIST_PATH/.datastream_ngiab" \
-        -p $NGINX_TETHYS_PORT:$NGINX_TETHYS_PORT \
-        --platform "$PLATFORM" \
+        -p "$NGINX_TETHYS_PORT:$NGINX_TETHYS_PORT" \
         --network "$DOCKER_NETWORK" \
         --name "$TETHYS_CONTAINER_NAME" \
         --env MEDIA_ROOT="$TETHYS_PERSIST_PATH/media" \
         --env MEDIA_URL="/media/" \
         --env SKIP_DB_SETUP="$SKIP_DB_SETUP" \
         --env DATASTREAM_CONF="$TETHYS_PERSIST_PATH/.datastream_ngiab" \
         --env VISUALIZER_CONF="$TETHYS_PERSIST_PATH/ngiab_visualizer/ngiab_visualizer.json" \
-        --env NGINX_PORT=$NGINX_TETHYS_PORT \
-        --env CSRF_TRUSTED_ORIGINS=$CSRF_TRUSTED_ORIGINS \
-        "$TETHYS_IMAGE_NAME" \
-        > /dev/null 2>&1
-}
-
-
-_copy_models_run() {
-    local input_path="$1"
-    local models_dir="$HOME/ngiab_visualizer"
-    # 1) make sure ~/ngiab_visualizer exists and you own it
-    _ensure_host_dir "$models_dir" || {
-        echo -e "${BRed}Failed to create or fix permissions on $models_dir${Color_Off}" >&2
-        return 1
-    }
-
-    # 2) derive the target path
-    local base_name
-    base_name="$(basename "$input_path")"
-    local model_run_path="$models_dir/$base_name"
-    local final_copied_path="$model_run_path"
-
-    # 3) copy logic
-    if [ ! -e "$model_run_path" ]; then
-        cp -r "$input_path" "$models_dir" || {
-            echo -e "${BRed}Error: Could not copy $input_path → $models_dir${Color_Off}" >&2
-            return 1
-        }
-        echo -e "${BCyan}Copied: $input_path → $model_run_path${Color_Off}" >&2
+        --env NGINX_PORT="$NGINX_TETHYS_PORT" \
+        --env CSRF_TRUSTED_ORIGINS="$CSRF_TRUSTED_ORIGINS" \
+        "${TETHYS_REPO}:${TETHYS_TAG}"
+        
+    if [ $? -eq 0 ]; then
+        echo -e "  ${CHECK_MARK} ${BGreen}Tethys container started successfully${Color_Off}"
+        return 0
     else
-        echo -e "${BYellow}Directory '$model_run_path' already exists.${Color_Off}" >&2
-        while true; do
-            echo -ne "${BYellow}Overwrite (O) or copy with different name (D)? [O/D]: ${Color_Off}" >&2
-            read -r choice < /dev/tty
-            case "$choice" in
-                [Oo]* )
-                    rm -rf "$model_run_path"
-                    cp -r "$input_path" "$models_dir" || {
-                        echo -e "${BRed}Error: Could not overwrite $model_run_path${Color_Off}" >&2
-                        return 1
-                    }
-                    echo -e "${BCyan}Overwritten with: $input_path → $model_run_path${Color_Off}" >&2
-                    break
-                    ;;
-                [Dd]* )
-                    echo -ne "${BBlue}Enter a new directory name: ${Color_Off}" >&2
-                    read -r new_name < /dev/tty
-                    if [ -z "$new_name" ]; then
-                        echo -e "${BRed}No name entered. Try again.${Color_Off}" >&2
-                        continue
-                    fi
-                    local new_path="$models_dir/$new_name"
-                    if [ -e "$new_path" ]; then
-                        echo -e "${BRed}'$new_name' already exists. Choose another name.${Color_Off}" >&2
-                        continue
-                    fi
-                    cp -r "$input_path" "$new_path" || {
-                        echo -e "${BRed}Error: Could not copy to $new_path${Color_Off}" >&2
-                        return 1
-                    }
-                    echo -e "${BPurple}Copied to: $new_path${Color_Off}" >&2
-                    final_copied_path="$new_path"
-                    break
-                    ;;
-                * )
-                    echo -e "${BRed}Invalid choice. Enter 'O' or 'D'.${Color_Off}" >&2
-                    ;;
-            esac
-        done
+        echo -e "  ${CROSS_MARK} ${BRed}Failed to start Tethys container${Color_Off}"
+        return 1
     fi
-
-    # 4) output the directory the caller should register
-    echo "$final_copied_path"
 }
 
-_add_model_run() {
-  local input_path="$1"
-  local json_file="$VISUALIZER_CONF"
-
-  # 1) Ensure $json_file exists
-  echo -e "${BGreen}Checking for $json_file...${Color_Off}"
-  if [ ! -f "$json_file" ]; then
-    echo '{"model_runs":[]}' > "$json_file"
-  fi
-
-  # 2) Extract the basename for label
-  local base_name
-  base_name=$(basename "$input_path")
-
-  # Generate a new UUID for the id field
-  local new_uuid
-  new_uuid=$(uuidgen)
-
-  # Current date/time (adjust format as needed)
-  local current_time
-  current_time=$(date +"%Y-%m-%d:%H:%M:%S")
-
-  # Always use /var/lib/tethys_persist/ngiab_visualizer as the base directory
-  local final_path="/var/lib/tethys_persist/ngiab_visualizer/$base_name"
-  jq --arg base_name "$base_name" \
-     --arg final_path  "$final_path" \
-     --arg current_time  "$current_time" \
-     --arg uuid    "$new_uuid" \
-     '.model_runs += [ 
-       { 
-         "label": $base_name, 
-         "path": $final_path, 
-         "date": $current_time, 
-         "id": $uuid, 
-         "subset": "", 
-         "tags": [] 
-       }
-     ]' \
-     "$json_file" > "${json_file}.tmp" && mv -f "${json_file}.tmp" "$json_file"
+pause_script_execution() {
+    echo -e "\n${BG_Blue}${BWhite} Tethys is now running ${Color_Off}"
+    echo -e "${INFO_MARK} Access the visualization at: ${UBlue}http://localhost:$NGINX_TETHYS_PORT/apps/ngiab${Color_Off}"
+    echo -e "${INFO_MARK} Press ${BWhite}Ctrl+C${Color_Off} to stop Tethys when you're done."
+    
+    # Keep script running until user interrupts
+    while true; do
+        sleep 10
+    done
 }
 
-create_tethys_portal(){
-    while true; do
-        echo -e "${BYellow}Visualize outputs using the Tethys Platform (https://www.tethysplatform.org/)? (Y/n, default: n):${Color_Off}"
-        read -r visualization_choice
-        
-        # Default to 'n' if input is empty
-        if [[ -z "$visualization_choice" ]]; then
-            visualization_choice="n"
-        fi
+# Main script execution
+print_welcome_banner
 
-        # Check for valid input
-        if [[ "$visualization_choice" =~ ^[YyNn]$ ]]; then
-            break
-        else
-            echo -e "${BRed}Invalid choice. Please enter 'y' for yes, 'n' for no, or press Enter for default (no).${Color_Off}"
-        fi
-    done
-    
-    echo -e "${BYellow}Specify the Tethys image tag to use: ${Color_Off}"
-    read -erp "Tag (e.g. v0.2.1, default: latest): " TETHYS_TAG
-    if [[ -z "$TETHYS_TAG" ]]; then
-        TETHYS_TAG="latest"
-    fi
+# Check if data path is provided as argument
+DATA_FOLDER_PATH="$1"
 
-    # Build the full image reference
-    TETHYS_IMAGE_NAME="${TETHYS_REPO}:${TETHYS_TAG}"    
-
-
-    # Execute the command
-    if [[ "$visualization_choice" =~ ^[Yy]$ ]]; then
-        echo -e "${BGreen}Setting up Tethys Portal image...${Color_Off}"
-        _create_tethys_docker_network
-        if _check_for_existing_tethys_image; then
-            _choose_port_to_run_tethys
-            _execute_command _run_containers
-            _wait_container $TETHYS_CONTAINER_NAME
-            echo -e "${BGreen}Your outputs are ready to be visualized at http://localhost:$NGINX_TETHYS_PORT/apps/ngiab ${Color_Off}"
-            echo -e "${UPurple}You can use the following to login: ${Color_Off}"
-            echo -e "${BCyan}user: admin${Color_Off}"
-            echo -e "${BCyan}password: pass${Color_Off}"
-            echo -e "${UPurple}Check the App source code: https://github.com/CIROH-UA/ngiab-client ${Color_Off}"
-            _pause_script_execution
+if [[ -z "$DATA_FOLDER_PATH" ]]; then
+    # If no path provided, check if we have a saved path
+    if [ -f "$CONFIG_FILE" ]; then
+        LAST_PATH=$(cat "$CONFIG_FILE")
+        echo -e "${INFO_MARK} Last used data directory: ${BBlue}$LAST_PATH${Color_Off}"
+        echo -e "  ${ARROW} Use this path? [Y/n]: "
+        echo -ne "\r\033[2A"  # Move up 2 lines
+        read -e use_last_path
+        echo -e "\033[2B"  # Move down 2 lines
+        
+        if [[ -z "$use_last_path" || "$use_last_path" =~ ^[Yy] ]]; then
+            DATA_FOLDER_PATH="$LAST_PATH"
+            echo -e "  ${CHECK_MARK} ${BGreen}Using previously configured path${Color_Off}"
         else
-            echo -e "${BRed}Failed to prepare Tethys portal.\n${Color_Off}"
+            echo -ne "  ${ARROW} Enter your input data directory path: "
+            read -e DATA_FOLDER_PATH
         fi
     else
-        echo -e "${BCyan}Skipping Tethys visualization setup.\n${Color_Off}"
+        echo -e "${INFO_MARK} ${BYellow}No previous configuration found${Color_Off}"
+        echo -ne "  ${ARROW} Enter your input data directory path: "
+        read -e DATA_FOLDER_PATH
     fi
-}
+    
+    # Save the new path
+    echo "$DATA_FOLDER_PATH" > "$CONFIG_FILE"
+    echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use${Color_Off}"
path: viewOnTethys.sh
user: login: Sheargrub
body: ```suggestion
    echo -e "  ${CHECK_MARK} ${BGreen}Path saved for future use.${Color_Off}"
```
created_at: 2025-05-14T17:40:19Z
author_association: COLLABORATOR

PR comments:
user: login: benlee0423
created_at: 2025-05-14T15:52:34Z
body: Last used data directory: /Users/benjaminlee/workspace/awi/input/AWI_16_2863657_007
 \033[38;5;215m→\033[0m Use the same path? [Y/n]: 

System architecture detected: arm64
 Recommended image tag: latest
 \033[38;5;215m→\033[0m Specify TEEHR image tag [default: latest]: 

I can't access visualizer.
author_association: CONTRIBUTOR
user: login: romer8
created_at: 2025-05-14T15:58:39Z
body: @benlee0423 waht is te `viewOnTethys.sh` output?

author_association: COLLABORATOR
user: login: benlee0423
created_at: 2025-05-14T17:44:51Z
body: @romer8 
It works now.
author_association: CONTRIBUTOR
user: login: benlee0423
created_at: 2025-05-14T17:45:05Z
body: @arpita0911patel 
Works great for me!
author_association: CONTRIBUTOR