TermPaperCattleElkR3 / Sim_Engine.py
jeffrey1963's picture
Upload 4 files
3875d5c verified
def initialize_parcels(parcel_map, cluster_labels):
parcel_dict = {}
for i in range(parcel_map.shape[0]):
for j in range(parcel_map.shape[1]):
cluster_id = parcel_map[i, j]
land_type = cluster_labels.get(cluster_id, "Unknown")
parcel_dict[(i, j)] = {
"land_type": land_type,
"forage": None,
"health": 1.0,
"degraded": False,
"cattle_grazing": {
"conservative": land_type == "Productive Grass",
"moderate": land_type in ["Productive Grass", "Pasture/Desert"],
"aggressive": land_type not in ["Water"]
},
"elk_grazing": {
"default": land_type in ["Riparian Sensitive Zone", "Productive Grass"]
}
}
return parcel_dict
def get_land_forage_rates():
return {
'Productive Grass': 1.0,
'Pasture/Desert': 0.4,
'Riparian Sensitive Zone': 1.2,
'Rocky Area': 0.2,
'Water': 0.0
}
def assign_initial_forage(parcel_dict, land_forage_rates):
for parcel in parcel_dict.values():
rate = land_forage_rates.get(parcel["land_type"], 0.0)
parcel["forage"] = rate * 100 # initial AUMs
import numpy as np
import numpy as np
import matplotlib.pyplot as plt
from collections import Counter
from matplotlib.colors import ListedColormap
import matplotlib.patches as mpatches
def simulate_period(parcel_dict, grazing_strategy="moderate", cattle_stocking_rate=500, elk_pressure=300):
print(f"\n🟢 Running simulation using cattle grazing strategy: **{grazing_strategy.upper()}**")
# 1. Reset all forage to simulate winter die-off
for parcel in parcel_dict.values():
parcel["forage"] = 0
# 2. Count eligible parcels for cattle grazing
total_grazed_parcels = sum(
1 for parcel in parcel_dict.values() if parcel["cattle_grazing"][grazing_strategy]
)
if total_grazed_parcels == 0:
print("⚠️ No parcels match the selected grazing strategy.")
return
# 3. Calculate AUM pressure per parcel
cattle_grazing_per_parcel = cattle_stocking_rate / total_grazed_parcels
elk_grazing_per_parcel = elk_pressure / len(parcel_dict) # uniform elk pressure
# 4. Simulate forage growth + grazing effects
for parcel in parcel_dict.values():
if not parcel["cattle_grazing"][grazing_strategy]:
continue
# Forage regrowth (8-month season with weather factor)
base_growth = {
'Productive Grass': 1.0,
'Pasture/Desert': 0.4,
'Riparian Sensitive Zone': 1.2,
'Rocky Area': 0.2,
'Water': 0.0
}.get(parcel["land_type"], 0.0)
weather = np.random.normal(1.0, 0.2)
growth = base_growth * weather * 8
parcel["forage"] = growth # no carryover between years
# Total grazing pressure
total_grazing = cattle_grazing_per_parcel + elk_grazing_per_parcel
# Degradation or recovery
if total_grazing > parcel["forage"]:
parcel["degraded"] = True
parcel["health"] -= 0.1
else:
parcel["health"] += 0.02
# Subtract forage
parcel["forage"] = max(parcel["forage"] - total_grazing, 0)
def get_forage_map(parcel_dict, n_rows, n_cols):
return np.array([[parcel_dict[(i, j)]["forage"] for j in range(n_cols)] for i in range(n_rows)])
def plot_forage_map(forage_map, title="Parcel Forage Levels"):
plt.figure(figsize=(8, 6))
plt.imshow(forage_map, cmap='YlGn', origin='upper')
plt.colorbar(label="Forage AUMs")
plt.title(title)
plt.axis('off')
plt.tight_layout()
plt.show()
def run_full_simulation(parcel_map, cluster_labels, n_rows, n_cols, strategy="moderate"):
parcel_dict = initialize_parcels(parcel_map, cluster_labels)
land_forage_rates = get_land_forage_rates()
assign_initial_forage(parcel_dict, land_forage_rates)
simulate_period(parcel_dict, grazing_strategy=strategy)
return parcel_dict