AbdullahImran commited on
Commit
c347529
·
verified ·
1 Parent(s): ec1da24

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -70
app.py CHANGED
@@ -11,6 +11,7 @@ from tensorflow.keras.applications.vgg16 import preprocess_input as vgg_preproce
11
  from tensorflow.keras.applications.xception import preprocess_input as xce_preprocess
12
  from tensorflow.keras.losses import BinaryFocalCrossentropy
13
  from PIL import Image
 
14
 
15
  # --- CONFIGURATION ---
16
  FOREST_COORDS = {'Pakistan Forest': (34.0, 73.0)}
@@ -18,8 +19,8 @@ API_URL = (
18
  "https://archive-api.open-meteo.com/v1/archive"
19
  "?latitude={lat}&longitude={lon}"
20
  "&start_date={start}&end_date={end}"
21
- "&daily=temperature_2m_max,temperature_2m_min,"
22
- "precipitation_sum,windspeed_10m_max,"
23
  "relative_humidity_2m_max,relative_humidity_2m_min"
24
  "&timezone=UTC"
25
  )
@@ -44,15 +45,19 @@ def load_models():
44
  'severity_post_tta.keras',
45
  custom_objects={'focal_loss_fixed': focal_loss_fixed()}
46
  )
 
 
 
47
  rf_model = joblib.load('ensemble_rf_model.pkl')
48
- xgb_model = joblib.load('ensemble_xgb_model.pkl')
49
  lr_model = joblib.load('wildfire_logistic_model_synthetic.joblib')
50
  return vgg_model, xce_model, rf_model, xgb_model, lr_model
51
  except Exception as e:
52
  print(f"Error loading models: {e}")
53
  return None, None, None, None, None
54
 
55
- # --- RULES & TEMPLATES ---
 
 
56
  target_map = {0: 'mild', 1: 'moderate', 2: 'severe'}
57
  trend_map = {1: 'increase', 0: 'same', -1: 'decrease'}
58
  task_rules = {
@@ -60,29 +65,7 @@ task_rules = {
60
  'moderate':{'decrease':'mild','same':'moderate','increase':'severe'},
61
  'severe': {'decrease':'moderate','same':'severe','increase':'severe'}
62
  }
63
- recommendations = {
64
- 'mild': {
65
- 'immediate': "Deploy spot crews for initial attack. Establish command post. Monitor fire behavior with drones or aircraft. Alert local fire stations.",
66
- 'evacuation': "No mass evacuation needed. Notify nearby communities of potential risk. Prepare evacuation routes if conditions change.",
67
- 'containment': "Establish initial fire lines. Use hand crews for direct attack. Position water resources. Clear fuel breaks where feasible.",
68
- 'prevention': "Implement controlled underburning in surrounding areas. Manage vegetation density. Create defensible spaces around structures.",
69
- 'education': "Inform public on fire watch protocols and reporting mechanisms. Train local volunteers in basic firefighting techniques."
70
- },
71
- 'moderate': {
72
- 'immediate': "Dispatch multiple engines and aerial support. Establish unified command system. Deploy heavy equipment. Request additional resources.",
73
- 'evacuation': "Prepare evacuation zones and staging areas. Advise voluntary evacuation for vulnerable populations. Alert emergency shelters.",
74
- 'containment': "Build substantial fire breaks. Conduct water drops from helicopters. Implement indirect attack strategies. Protect critical infrastructure.",
75
- 'prevention': "Initiate fuel reduction programs in adjacent areas. Create wider buffer zones. Assess watershed protection needs.",
76
- 'education': "Conduct community emergency drills. Launch awareness campaigns on evacuation procedures. Distribute preparedness materials."
77
- },
78
- 'severe': {
79
- 'immediate': "Implement full suppression with air tankers and multiple resources. Establish incident management team. Request state/federal assistance. Deploy specialized teams.",
80
- 'evacuation': "Issue mandatory evacuation orders. Open multiple emergency shelters. Implement traffic control measures. Assist vulnerable populations.",
81
- 'containment': "Deploy fire retardant lines from aircraft. Consider backfires and burnout operations. Protect critical infrastructure. Establish multiple control lines.",
82
- 'prevention': "Plan for reforestation and erosion control. Harden infrastructure against future fires. Implement watershed protection measures.",
83
- 'education': "Conduct comprehensive emergency response training. Implement risk communication strategies. Develop long-term community resilience programs."
84
- }
85
- }
86
 
87
  # --- PIPELINE FUNCTIONS ---
88
  def detect_fire(img):
@@ -123,7 +106,6 @@ def fetch_weather_trend(lat, lon):
123
  response.raise_for_status()
124
  df = pd.DataFrame(response.json().get('daily', {}))
125
  except Exception:
126
- # Fallback sample data
127
  df = pd.DataFrame({
128
  'date': [(datetime.utcnow() - timedelta(days=i)).strftime('%Y-%m-%d') for i in range(1,-1,-1)],
129
  'precipitation_sum': [5, 2],
@@ -133,15 +115,13 @@ def fetch_weather_trend(lat, lon):
133
  'relative_humidity_2m_min': [40, 35],
134
  'windspeed_10m_max': [15, 18]
135
  })
136
- # Numeric conversions
137
  for c in ['precipitation_sum','temperature_2m_max','temperature_2m_min',
138
  'relative_humidity_2m_max','relative_humidity_2m_min','windspeed_10m_max']:
139
  df[c] = pd.to_numeric(df[c], errors='coerce')
140
- # Feature engineering
141
- df['precipitation'] = df['precipitation_sum']
142
  df['temperature'] = (df['temperature_2m_max'] + df['temperature_2m_min']) / 2
143
  df['humidity'] = (df['relative_humidity_2m_max'] + df['relative_humidity_2m_min']) / 2
144
  df['wind_speed'] = df['windspeed_10m_max']
 
145
  df['fire_risk_score'] = (
146
  0.4 * (df['temperature'] / 55) +
147
  0.2 * (1 - df['humidity'] / 100) +
@@ -157,19 +137,16 @@ def fetch_weather_trend(lat, lon):
157
  def generate_recommendations(original_severity, weather_trend):
158
  projected = task_rules[original_severity][weather_trend]
159
  rec = recommendations[projected]
160
- return (f"**Original Severity:** {original_severity.title()} \
161
- " \
162
- f"**Weather Trend:** {weather_trend.title()} \
163
- " \
164
- f"**Projected Severity:** {projected.title()}\n\n" \
165
- "### Management Recommendations:\n" \
166
- f"**Immediate:** {rec['immediate']}\n\n" \
167
- f"**Evacuation:** {rec['evacuation']}\n\n" \
168
- f"**Containment:** {rec['containment']}\n\n" \
169
- f"**Prevention:** {rec['prevention']}\n\n" \
170
- f"**Education:** {rec['education']}")
171
 
172
- # --- MAIN PIPELINE ---
173
  def pipeline(image):
174
  if image is None:
175
  return "No image provided","N/A","N/A","**Please upload an image to analyze**"
@@ -191,7 +168,6 @@ def pipeline(image):
191
  recs
192
  )
193
 
194
- # --- SAFE WRAPPER FOR UI ---
195
  def safe_pipeline(image):
196
  try:
197
  return pipeline(image)
@@ -199,32 +175,19 @@ def safe_pipeline(image):
199
  print(f"Error in pipeline: {e}")
200
  return "Error during analysis","N/A","N/A", f"**Error: {e}**"
201
 
202
- # --- GLOBAL MODEL LOADING ---
203
- vgg_model, xce_model, rf_model, xgb_model, lr_model = load_models()
204
-
205
- # --- UI: CUSTOM CSS & GRADIO LAYOUT ---
206
  custom_css = '''
207
- #header { text-align: center; margin: 0 0 1rem; }
208
- #header img { height: 4rem; margin-right: 1rem; }
209
- #main-title { font-size: 2.75rem; margin: 0.5rem 0; }
210
- #sub-title { font-size: 1.25rem; color: #555; }
211
- .gr-button.primary { background: #ff7043 !important; }
212
- .output-card { background: #f7f7f7; border-radius: 0.75rem; padding: 1rem;
213
- box-shadow: 0 1px 6px rgba(0,0,0,0.1); margin-bottom: 1rem; }
214
  '''
215
-
216
  with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
217
- # Header (add your logo.png in working directory or adjust path)
218
  with gr.Row(elem_id="header"):
219
  try:
220
  gr.Image(value="logo.png", show_label=False)
221
  except:
222
  pass
223
  with gr.Column():
224
- gr.Markdown("# 🔥 Wildfire Command Center", elem_id="main-title")
225
- gr.Markdown("Upload a forest image to detect wildfire, classify severity, and get actionable recommendations.", elem_id="sub-title")
226
-
227
- # Tabs: Analyze & Last Analysis
228
  with gr.Tabs():
229
  with gr.TabItem("Analyze 🔍"):
230
  with gr.Row():
@@ -232,19 +195,15 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
232
  image_input = gr.Image(type="numpy", label="Forest Image", tool="editor")
233
  run_btn = gr.Button("Analyze Now", variant="primary")
234
  with gr.Column(scale=1):
235
- with gr.Spinner():
236
- status_out = gr.Markdown("*Status will appear here*", label="Status")
237
- severity_out = gr.Markdown("---", label="Severity")
238
- trend_out = gr.Markdown("---", label="Weather Trend")
239
- recs_out = gr.Markdown("---", label="Recommendations")
240
-
241
  with gr.TabItem("Last Analysis 📊"):
242
  last_status = gr.Markdown("*No analysis yet*", elem_classes="output-card")
243
  last_severity = gr.Markdown("---", elem_classes="output-card")
244
  last_trend = gr.Markdown("---", elem_classes="output-card")
245
  last_recs = gr.Markdown("---", elem_classes="output-card")
246
-
247
- # Bind actions: analyze then archive outputs
248
  run_btn.click(
249
  fn=safe_pipeline,
250
  inputs=image_input,
@@ -254,6 +213,5 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
254
  inputs=[status_out, severity_out, trend_out, recs_out],
255
  outputs=[last_status, last_severity, last_trend, last_recs]
256
  )
257
-
258
  if __name__ == '__main__':
259
  demo.queue(api_open=True).launch()
 
11
  from tensorflow.keras.applications.xception import preprocess_input as xce_preprocess
12
  from tensorflow.keras.losses import BinaryFocalCrossentropy
13
  from PIL import Image
14
+ from xgboost import XGBClassifier
15
 
16
  # --- CONFIGURATION ---
17
  FOREST_COORDS = {'Pakistan Forest': (34.0, 73.0)}
 
19
  "https://archive-api.open-meteo.com/v1/archive"
20
  "?latitude={lat}&longitude={lon}"
21
  "&start_date={start}&end_date={end}"
22
+ "&daily=temperature_2m_max,temperature_2m_min,"
23
+ "precipitation_sum,windspeed_10m_max,"
24
  "relative_humidity_2m_max,relative_humidity_2m_min"
25
  "&timezone=UTC"
26
  )
 
45
  'severity_post_tta.keras',
46
  custom_objects={'focal_loss_fixed': focal_loss_fixed()}
47
  )
48
+ # Reload XGBoost from JSON to avoid pickle warnings
49
+ xgb_model = XGBClassifier()
50
+ xgb_model.load_model('ensemble_xgb_model.json')
51
  rf_model = joblib.load('ensemble_rf_model.pkl')
 
52
  lr_model = joblib.load('wildfire_logistic_model_synthetic.joblib')
53
  return vgg_model, xce_model, rf_model, xgb_model, lr_model
54
  except Exception as e:
55
  print(f"Error loading models: {e}")
56
  return None, None, None, None, None
57
 
58
+ # Load models once
59
+ vgg_model, xce_model, rf_model, xgb_model, lr_model = load_models()
60
+
61
  target_map = {0: 'mild', 1: 'moderate', 2: 'severe'}
62
  trend_map = {1: 'increase', 0: 'same', -1: 'decrease'}
63
  task_rules = {
 
65
  'moderate':{'decrease':'mild','same':'moderate','increase':'severe'},
66
  'severe': {'decrease':'moderate','same':'severe','increase':'severe'}
67
  }
68
+ recommendations = { ... } # (keep your existing recommendations dict here)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  # --- PIPELINE FUNCTIONS ---
71
  def detect_fire(img):
 
106
  response.raise_for_status()
107
  df = pd.DataFrame(response.json().get('daily', {}))
108
  except Exception:
 
109
  df = pd.DataFrame({
110
  'date': [(datetime.utcnow() - timedelta(days=i)).strftime('%Y-%m-%d') for i in range(1,-1,-1)],
111
  'precipitation_sum': [5, 2],
 
115
  'relative_humidity_2m_min': [40, 35],
116
  'windspeed_10m_max': [15, 18]
117
  })
 
118
  for c in ['precipitation_sum','temperature_2m_max','temperature_2m_min',
119
  'relative_humidity_2m_max','relative_humidity_2m_min','windspeed_10m_max']:
120
  df[c] = pd.to_numeric(df[c], errors='coerce')
 
 
121
  df['temperature'] = (df['temperature_2m_max'] + df['temperature_2m_min']) / 2
122
  df['humidity'] = (df['relative_humidity_2m_max'] + df['relative_humidity_2m_min']) / 2
123
  df['wind_speed'] = df['windspeed_10m_max']
124
+ df['precipitation'] = df['precipitation_sum']
125
  df['fire_risk_score'] = (
126
  0.4 * (df['temperature'] / 55) +
127
  0.2 * (1 - df['humidity'] / 100) +
 
137
  def generate_recommendations(original_severity, weather_trend):
138
  projected = task_rules[original_severity][weather_trend]
139
  rec = recommendations[projected]
140
+ return (f"**Original Severity:** {original_severity.title()} \" \
141
+ f"**Weather Trend:** {weather_trend.title()} \" \
142
+ f"**Projected Severity:** {projected.title()}\n\n" \
143
+ "### Management Recommendations:\n" \
144
+ f"**Immediate:** {rec['immediate']}\n\n" \
145
+ f"**Evacuation:** {rec['evacuation']}\n\n" \
146
+ f"**Containment:** {rec['containment']}\n\n" \
147
+ f"**Prevention:** {rec['prevention']}\n\n" \
148
+ f"**Education:** {rec['education']}")
 
 
149
 
 
150
  def pipeline(image):
151
  if image is None:
152
  return "No image provided","N/A","N/A","**Please upload an image to analyze**"
 
168
  recs
169
  )
170
 
 
171
  def safe_pipeline(image):
172
  try:
173
  return pipeline(image)
 
175
  print(f"Error in pipeline: {e}")
176
  return "Error during analysis","N/A","N/A", f"**Error: {e}**"
177
 
178
+ # --- GRADIO UI ---
 
 
 
179
  custom_css = '''
180
+ #header { text-align: center; margin-bottom: 1rem; }
 
 
 
 
 
 
181
  '''
 
182
  with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
 
183
  with gr.Row(elem_id="header"):
184
  try:
185
  gr.Image(value="logo.png", show_label=False)
186
  except:
187
  pass
188
  with gr.Column():
189
+ gr.Markdown("# 🔥 Wildfire Command Center")
190
+ gr.Markdown("Upload a forest image to detect wildfire, classify severity, and get actionable recommendations.")
 
 
191
  with gr.Tabs():
192
  with gr.TabItem("Analyze 🔍"):
193
  with gr.Row():
 
195
  image_input = gr.Image(type="numpy", label="Forest Image", tool="editor")
196
  run_btn = gr.Button("Analyze Now", variant="primary")
197
  with gr.Column(scale=1):
198
+ status_out = gr.Markdown("*Status will appear here*", label="Status")
199
+ severity_out = gr.Markdown("---", label="Severity")
200
+ trend_out = gr.Markdown("---", label="Weather Trend")
201
+ recs_out = gr.Markdown("---", label="Recommendations")
 
 
202
  with gr.TabItem("Last Analysis 📊"):
203
  last_status = gr.Markdown("*No analysis yet*", elem_classes="output-card")
204
  last_severity = gr.Markdown("---", elem_classes="output-card")
205
  last_trend = gr.Markdown("---", elem_classes="output-card")
206
  last_recs = gr.Markdown("---", elem_classes="output-card")
 
 
207
  run_btn.click(
208
  fn=safe_pipeline,
209
  inputs=image_input,
 
213
  inputs=[status_out, severity_out, trend_out, recs_out],
214
  outputs=[last_status, last_severity, last_trend, last_recs]
215
  )
 
216
  if __name__ == '__main__':
217
  demo.queue(api_open=True).launch()