Spaces:
Sleeping
Sleeping
File size: 6,792 Bytes
6fde63f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | import os
import random
import numpy as np
import matplotlib.pyplot as plt
from openai import OpenAI
from Sim_Engine import simulate_period
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
def summarize_initial_conditions(n_rows, n_cols):
num_parcels = n_rows * n_cols
avg_forage = round(random.uniform(6.5, 8.0), 1)
degraded_pct = round(random.uniform(0.0, 2.0), 1)
riparian_health = random.choice(["excellent", "moderate", "fragile"])
elk_corridor_status = random.choice([
"completely intact and lightly used",
"intact but under slight pressure from cattle movement",
"showing signs of fragmentation near key crossings"
])
rainfall_outlook = random.choice(["normal", "below average", "above average"])
return (
f"There are {num_parcels} parcels in total. Grazing has not yet occurred.\n"
f"Average forage availability is {avg_forage} AUMs per parcel, with about {degraded_pct}% of land already degraded due to prior conditions.\n"
f"Riparian zone condition is {riparian_health}, and the elk movement corridor is {elk_corridor_status}.\n"
f"The seasonal rainfall outlook is {rainfall_outlook}."
)
def plot_forage_map_to_file(parcel_dict, n_rows, n_cols, title="Forage Map", save_path="forage_map.png"):
forage_map = np.array([
[parcel_dict[(i, j)]["forage"] for j in range(n_cols)]
for i in range(n_rows)
])
fig, ax = plt.subplots(figsize=(8, 6))
cax = ax.imshow(forage_map, cmap='YlGn', origin='upper')
fig.colorbar(cax, label="Forage AUMs")
ax.set_title(title)
ax.axis('off')
plt.tight_layout()
plt.savefig(save_path)
plt.close(fig)
def elk_feedback(plan_choice, current_summary):
prompt = f"""
You represent a coalition of elk-related interests: conservationists, hunting advocates, and the hospitality/lodging industry.
A student has selected the **'{plan_choice}'** cattle grazing strategy. Below are the current ecological conditions:
-----
{current_summary}
-----
Please do the following:
- Explicitly choose **one elk management strategy** from the list:
- **Preserve**: strict elk protections, no hunting, unrestricted movement
- **Cooperate**: shared use corridor, some riparian restrictions, sustainable elk population
- **Exploit**: prioritize hunting/tourism, tolerate reduced elk numbers and access
- Reflect each group's view briefly, but unify the final position.
- Justify your strategy choice based on the above ecological indicators.
"""
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.8
)
return response.choices[0].message.content
def usfs_feedback(plan_choice, student_essay, current_summary):
# Extract the AUM line from the summary
aum_line = ""
for line in current_summary.split("\n"):
if "Average forage availability" in line:
aum_line = line.strip()
break
prompt = f"""
You are a USFS land management agent evaluating a student’s cattle grazing proposal.
The student selected the **'{plan_choice}'** strategy and submitted this justification:
-----
{student_essay}
-----
Here are the current rangeland conditions:
-----
{current_summary}
-----
🚨 **Must Include Block**:
You must include this sentence exactly in your response:
→ "{aum_line}"
Then provide your evaluation:
- Comment on forage, degradation, riparian and corridor health
- State whether the plan is ecologically sound
- Suggest improvements if needed
- Keep the tone professional, clear, and grounded in the data
"""
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.7
)
return response.choices[0].message.content
def simulate_and_summarizeold(plan_choice, round_counter, parcel_dict, parcel_map, cluster_labels, n_rows, n_cols, elk_pressure):
# Interpret strategy
strategy_map = {
"conservative": "conservative",
"normal": "moderate",
"aggressive": "aggressive"
}
strategy = strategy_map.get(plan_choice.lower(), "moderate")
# ✅ Reuse incoming parcel_dict — do not reset
simulate_period(parcel_dict, grazing_strategy=strategy, elk_pressure=elk_pressure)
# Extract summary
forage_vals = [p["forage"] for p in parcel_dict.values()]
avg_forage = sum(forage_vals) / len(forage_vals)
degraded_pct = 100 * sum(p["health"] < 0.5 for p in parcel_dict.values()) / len(parcel_dict)
summary = (
f"After Round {round_counter} with the '{plan_choice}' plan:\n"
f"Avg forage: {avg_forage:.1f} AUMs, Parcels with low health (<0.5): {degraded_pct:.1f}%"
)
# Generate map visuals
from Sim_Engine import get_forage_map, get_health_map, plot_forage_map, plot_health_map
forage_map = get_forage_map(parcel_dict, n_rows, n_cols)
health_map = get_health_map(parcel_dict, n_rows, n_cols)
plot_forage_map(forage_map, title=f"Forage Map (Round {round_counter})", save_path="forage_map.png")
plot_health_map(health_map, title=f"Health Map (Round {round_counter})", save_path="health_map.png")
return summary, "forage_map.png", "health_map.png", round_counter + 1, parcel_dict
def simulate_and_summarize(plan_choice, round_counter, parcel_map, cluster_labels, n_rows, n_cols, run_full_simulation, history):
strategy_map = {
"conservative": "conservative",
"normal": "moderate",
"aggressive": "aggressive"
}
strategy = strategy_map.get(plan_choice.lower())
parcel_dict = run_full_simulation(parcel_map, cluster_labels, n_rows, n_cols, strategy=strategy)
plot_forage_map_to_file(parcel_dict, n_rows, n_cols, title=f"Round {round_counter} Forage Map")
# ✅ ADD THIS BLOCK
from Sim_Engine import get_health_map, plot_health_map
health_map = get_health_map(parcel_dict, n_rows, n_cols)
plot_health_map(health_map, title=f"Round {round_counter} Health Map", save_path="health_map.png")
forage_vals = [p["forage"] for p in parcel_dict.values()]
avg_forage = sum(forage_vals) / len(forage_vals)
degraded_pct = 100 * sum(p["degraded"] for p in parcel_dict.values()) / len(parcel_dict)
summary = (
f"After Round {round_counter} with the '{plan_choice}' plan:\n"
f"Avg forage: {avg_forage:.1f} AUMs, Degraded parcels: {degraded_pct:.1f}%"
)
return summary, "forage_map.png", "health_map.png", round_counter + 1
def full_response(plan_choice, essay_text, current_summary):
elk_resp = elk_feedback(plan_choice, current_summary)
usfs_resp = usfs_feedback(plan_choice, essay_text, current_summary)
return elk_resp, usfs_resp
|