jeffrey1963's picture
Update app.py
0af71f6 verified
import os
import gradio as gr
import numpy as np
from openai import OpenAI
from Sim_Setup_Fcns import (
load_and_crop_image, cluster_image, build_parcel_map,
get_cluster_labels, get_land_colors, plot_parcel_map_to_file
)
from Sim_Engine import run_full_simulation
from feedback_fcns import (
summarize_initial_conditions, plot_forage_map_to_file,
elk_feedback, usfs_feedback, simulate_and_summarize, full_response
)
from zone_utils import (
identify_zones, plot_labeled_zones,
assign_zone_labels, save_zone_info_to_excel,override_zone_id_and_label
)
# === Setup on Launch ===
img = load_and_crop_image("Carson_map.png")
clustered_img = cluster_image(img)
parcel_map, n_rows, n_cols = build_parcel_map(clustered_img)
cluster_labels = get_cluster_labels()
land_colors = get_land_colors()
plot_parcel_map_to_file(parcel_map, cluster_labels, land_colors, save_path="clustered_map.png")
# === Zoning ===
# 1. Identify contiguous zones
zone_map, zone_to_cluster = identify_zones(parcel_map, connectivity="queen")
# 2. Assign human-readable labels (before override)
zone_labels = assign_zone_labels(zone_to_cluster)
# === Manual override for mislabeled riparian zone ===
# First, update the zone label once
for zid, lbl in zone_labels.items():
if lbl == "A" and zone_to_cluster[zid] == 1:
zone_labels[zid] = "Riparian A1"
if lbl == "M" and zone_to_cluster[zid] == 1:
zone_labels[zid] = "Riparian A2"
# Then update all matching parcels
for i in range(n_rows):
for j in range(n_cols):
zone_id = zone_map[i, j]
if zone_labels.get(zone_id) == "Riparian A1":
parcel_map[i, j] = 2
if zone_labels.get(zone_id) == "Riparian A2":
parcel_map[i, j] = 2
#
# ⬇️ Add this block right after the override
zone_to_cluster = {}
for zone_id in np.unique(zone_map):
indices = np.argwhere(zone_map == zone_id)
if len(indices) > 0:
i, j = indices[0]
zone_to_cluster[zone_id] = parcel_map[i, j]
# 6. Plot labeled zones after override and mapping
plot_labeled_zones(zone_map, zone_labels, zone_to_cluster, save_path="zones_labeled.png")
# 5. Define cluster-to-class mapping (should stay after override)
cluster_to_class = {
0: "desert",
1: "pasture",
2: "riparain",
3: "sensitive riparian",
4: "wetland",
5: "water"
}
# 7. Save zone info to Excel
zone_excel_path = "zone_info.xlsx"
save_zone_info_to_excel(
parcel_map, zone_map, zone_labels, zone_to_cluster, cluster_to_class,
save_path=zone_excel_path
)
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
# === Gradio App ===
with gr.Blocks() as demo:
gr.Markdown("# AGEC 3052 — Grazing Strategy Simulation")
gr.Image(value="clustered_map.png", label="Initial 25×25 Parcel Layout")
gr.Image(value="zones_labeled.png", label="Labeled Pasture & Riparian Zones")
# ✅ Downloadable Excel
gr.File(value=zone_excel_path, label="Download Zone Info (Excel)")
plan = gr.Radio(["Conservative", "Normal", "Aggressive"], label="Grazing Plan")
essay = gr.Textbox(lines=8, label="Your Essay Justifying the Plan")
elk_output = gr.Textbox(label="Elk Stakeholder Feedback")
usfs_output = gr.Textbox(label="USFS Feedback")
sim_output = gr.Textbox(label="Simulation Results", lines=2)
sim_image = gr.Image(label="Forage Map After Simulation", type="filepath")
round_counter = gr.State(value=1)
history = gr.State(value=[summarize_initial_conditions(n_rows, n_cols)])
def submit_handler(plan_choice, essay_text, history_val):
return full_response(plan_choice, essay_text, history_val[-1])
def sim_handler(plan_choice, round_val, history_val):
summary, map_path, new_round = simulate_and_summarize(
plan_choice, round_val, parcel_map, cluster_labels, n_rows, n_cols,
run_full_simulation, history_val
)
history_val.append(summary)
return summary, map_path, new_round, history_val
submit_btn = gr.Button("Submit Grazing Plan")
sim_btn = gr.Button("Run Simulation")
submit_btn.click(fn=submit_handler, inputs=[plan, essay, history], outputs=[elk_output, usfs_output])
sim_btn.click(fn=sim_handler, inputs=[plan, round_counter, history], outputs=[sim_output, sim_image, round_counter, history])
demo.launch()