broadfield-dev commited on
Commit
d0aac58
·
verified ·
1 Parent(s): 86f8031

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -29
app.py CHANGED
@@ -30,12 +30,10 @@ def fetch_sdo_images(start_date, end_date, ident="0171", size="1024", tool="hmii
30
  frames = []
31
  current = start
32
  while current <= end:
33
- # Format URL: https://sdo.gsfc.nasa.gov/assets/img/browse/YEAR/MONTH/DAY/DATE_IDENT_SIZE_TOOL.jpg
34
  date_str = current.strftime("%Y%m%d_%H%M%S")
35
  year, month, day = current.strftime("%Y"), current.strftime("%m"), current.strftime("%d")
36
  url = urljoin(base_url, f"{year}/{month}/{day}/{date_str}_{ident}_{size}_{tool}.jpg")
37
 
38
- # Fetch image
39
  try:
40
  response = requests.get(url, timeout=5)
41
  if response.status_code == 200:
@@ -112,6 +110,15 @@ def create_gif(frames, output_path, duration=0.5):
112
  )
113
  return output_path
114
 
 
 
 
 
 
 
 
 
 
115
  def analyze_images(frames, lower_bound, upper_bound, param1, param2, center_tolerance, morph_iterations, min_rad, display_mode):
116
  """Analyze frames for concentric circles, highlighting growing series."""
117
  try:
@@ -164,31 +171,30 @@ def analyze_images(frames, lower_bound, upper_bound, param1, param2, center_tole
164
 
165
  # Prepare output based on display mode
166
  if display_mode == "All Frames":
167
- for i, frame in enumerate(frames):
168
- output_frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB)
169
- if i + 1 in growing_frames:
170
- for c in all_circle_data:
171
- if c["frame"] == i + 1:
172
- cv2.circle(output_frame, c["center"], c["radius"], (0, 255, 0), 2)
173
- cv2.circle(output_frame, c["center"], c["radius"] + 2, (255, 0, 0), 2)
174
- results.append(Image.fromarray(output_frame))
175
  elif display_mode == "Detected Frames":
 
176
  for c in all_circle_data:
177
  output_frame = cv2.cvtColor(c["output_frame"], cv2.COLOR_GRAY2RGB)
178
- cv2.circle(output_frame, c["center"], c["radius"], (0, 255, 0), 2)
179
  if c["frame"] in growing_frames:
180
- cv2.circle(output_frame, c["center"], c["radius"] + 2, (255, 0, 0), 2)
181
  results.append(Image.fromarray(output_frame))
182
  elif display_mode == "Both (Detected Replaces Original)":
 
183
  for i, frame in enumerate(frames):
184
- output_frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB)
185
- if i + 1 in growing_frames:
186
  for c in all_circle_data:
187
  if c["frame"] == i + 1:
188
  output_frame = cv2.cvtColor(c["output_frame"], cv2.COLOR_GRAY2RGB)
189
- cv2.circle(output_frame, c["center"], c["radius"], (0, 255, 0), 2)
190
- cv2.circle(output_frame, c["center"], c["radius"] + 2, (255, 0, 0), 2)
191
- results.append(Image.fromarray(output_frame))
 
 
 
 
192
 
193
  # Generate report
194
  if all_circle_data:
@@ -217,19 +223,19 @@ def analyze_images(frames, lower_bound, upper_bound, param1, param2, center_tole
217
  except Exception as e:
218
  return f"Error during analysis: {str(e)}", [], None
219
 
220
- def process_input(gif_file, start_date, end_date, ident, size, tool, lower_bound, upper_bound, param1, param2, center_tolerance, morph_iterations, min_rad, display_mode):
221
  """Process either uploaded GIF or fetched SDO images."""
222
  if gif_file:
223
  frames, error = extract_frames(gif_file.name)
224
  if error:
225
- return error, [], None
226
  else:
227
- frames, error = fetch_sdo_images(start_date, end_date, ident, size, tool)
228
- if error:
229
- return error, [], None
230
 
231
- # Preview first frame if available
232
- preview = Image.fromarray(frames[0]) if frames else None
233
 
234
  # Analyze frames
235
  report, results, gif_path = analyze_images(
@@ -242,10 +248,13 @@ def process_input(gif_file, start_date, end_date, ident, size, tool, lower_bound
242
  with gr.Blocks(title="Solar CME Detection") as demo:
243
  gr.Markdown("""
244
  # Solar CME Detection
245
- Upload a GIF or specify a date range to fetch SDO images and detect concentric circles indicative of coronal mass ejections (CMEs).
246
- Green circles mark detected features; red circles highlight growing series (potential Earth-directed CMEs).
247
  """)
248
 
 
 
 
249
  with gr.Row():
250
  with gr.Column():
251
  gr.Markdown("### Input Options")
@@ -255,6 +264,7 @@ with gr.Blocks(title="Solar CME Detection") as demo:
255
  ident = gr.Textbox(label="Image Identifier", value="0171")
256
  size = gr.Textbox(label="Image Size", value="1024")
257
  tool = gr.Textbox(label="Instrument", value="hmiigr")
 
258
 
259
  gr.Markdown("### Analysis Parameters")
260
  lower_bound = gr.Slider(minimum=0, maximum=255, value=low_int, step=1, label="Lower Intensity Bound (0-255)")
@@ -275,15 +285,28 @@ with gr.Blocks(title="Solar CME Detection") as demo:
275
  with gr.Column():
276
  gr.Markdown("### Outputs")
277
  report = gr.Textbox(label="Analysis Report", lines=10)
278
- preview = gr.Image(label="Input Preview (First Frame)")
279
- gallery = gr.Gallery(label="Frames with Detected Circles (Green: Detected, Red: Growing Series)")
280
  gif_output = gr.File(label="Download Resulting GIF")
281
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
  analyze_button.click(
283
  fn=process_input,
284
  inputs=[
285
  gif_input, start_date, end_date, ident, size, tool,
286
- lower_bound, upper_bound, param1, param2, center_tolerance, morph_iterations, min_rad, display_mode
287
  ],
288
  outputs=[report, gallery, gif_output, preview]
289
  )
 
30
  frames = []
31
  current = start
32
  while current <= end:
 
33
  date_str = current.strftime("%Y%m%d_%H%M%S")
34
  year, month, day = current.strftime("%Y"), current.strftime("%m"), current.strftime("%d")
35
  url = urljoin(base_url, f"{year}/{month}/{day}/{date_str}_{ident}_{size}_{tool}.jpg")
36
 
 
37
  try:
38
  response = requests.get(url, timeout=5)
39
  if response.status_code == 200:
 
110
  )
111
  return output_path
112
 
113
+ def handle_fetch(start_date, end_date, ident, size, tool):
114
+ """Fetch SDO images and return frames for preview."""
115
+ frames, error = fetch_sdo_images(start_date, end_date, ident, size, tool)
116
+ if error:
117
+ return error, []
118
+ # Convert frames to PIL Images for preview
119
+ preview_frames = [Image.fromarray(frame) for frame in frames]
120
+ return "Fetched {} images successfully.".format(len(frames)), preview_frames
121
+
122
  def analyze_images(frames, lower_bound, upper_bound, param1, param2, center_tolerance, morph_iterations, min_rad, display_mode):
123
  """Analyze frames for concentric circles, highlighting growing series."""
124
  try:
 
171
 
172
  # Prepare output based on display mode
173
  if display_mode == "All Frames":
174
+ # Show pure, unprocessed frames
175
+ results = [Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB)) for frame in frames]
 
 
 
 
 
 
176
  elif display_mode == "Detected Frames":
177
+ # Show only frames with detected circles
178
  for c in all_circle_data:
179
  output_frame = cv2.cvtColor(c["output_frame"], cv2.COLOR_GRAY2RGB)
180
+ cv2.circle(output_frame, c["center"], c["radius"], (0, 255, 0), 2) # Green for detected
181
  if c["frame"] in growing_frames:
182
+ cv2.circle(output_frame, c["center"], c["radius"] + 2, (255, 165, 0), 2) # Orange for growing
183
  results.append(Image.fromarray(output_frame))
184
  elif display_mode == "Both (Detected Replaces Original)":
185
+ # Show all frames, replacing detected frames with circles
186
  for i, frame in enumerate(frames):
187
+ if i + 1 in [c["frame"] for c in all_circle_data]:
 
188
  for c in all_circle_data:
189
  if c["frame"] == i + 1:
190
  output_frame = cv2.cvtColor(c["output_frame"], cv2.COLOR_GRAY2RGB)
191
+ cv2.circle(output_frame, c["center"], c["radius"], (0, 255, 0), 2) # Green
192
+ if c["frame"] in growing_frames:
193
+ cv2.circle(output_frame, c["center"], c["radius"] + 2, (255, 165, 0), 2) # Orange
194
+ results.append(Image.fromarray(output_frame))
195
+ break
196
+ else:
197
+ results.append(Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB)))
198
 
199
  # Generate report
200
  if all_circle_data:
 
223
  except Exception as e:
224
  return f"Error during analysis: {str(e)}", [], None
225
 
226
+ def process_input(gif_file, start_date, end_date, ident, size, tool, lower_bound, upper_bound, param1, param2, center_tolerance, morph_iterations, min_rad, display_mode, fetched_frames_state):
227
  """Process either uploaded GIF or fetched SDO images."""
228
  if gif_file:
229
  frames, error = extract_frames(gif_file.name)
230
  if error:
231
+ return error, [], None, []
232
  else:
233
+ frames = fetched_frames_state
234
+ if not frames:
235
+ return "No fetched frames available. Please fetch images first.", [], None, []
236
 
237
+ # Preview all frames
238
+ preview = [Image.fromarray(frame) for frame in frames] if frames else []
239
 
240
  # Analyze frames
241
  report, results, gif_path = analyze_images(
 
248
  with gr.Blocks(title="Solar CME Detection") as demo:
249
  gr.Markdown("""
250
  # Solar CME Detection
251
+ Upload a GIF or fetch SDO images by date range to detect concentric circles indicative of coronal mass ejections (CMEs).
252
+ Green circles mark detected features; orange circles highlight growing series (potential Earth-directed CMEs).
253
  """)
254
 
255
+ # State to store fetched frames
256
+ fetched_frames_state = gr.State(value=[])
257
+
258
  with gr.Row():
259
  with gr.Column():
260
  gr.Markdown("### Input Options")
 
264
  ident = gr.Textbox(label="Image Identifier", value="0171")
265
  size = gr.Textbox(label="Image Size", value="1024")
266
  tool = gr.Textbox(label="Instrument", value="hmiigr")
267
+ fetch_button = gr.Button("Fetch Images from URL")
268
 
269
  gr.Markdown("### Analysis Parameters")
270
  lower_bound = gr.Slider(minimum=0, maximum=255, value=low_int, step=1, label="Lower Intensity Bound (0-255)")
 
285
  with gr.Column():
286
  gr.Markdown("### Outputs")
287
  report = gr.Textbox(label="Analysis Report", lines=10)
288
+ preview = gr.Gallery(label="Input Preview (All Frames)")
289
+ gallery = gr.Gallery(label="Frames with Detected Circles (Green: Detected, Orange: Growing Series)")
290
  gif_output = gr.File(label="Download Resulting GIF")
291
 
292
+ # Fetch button action
293
+ fetch_button.click(
294
+ fn=handle_fetch,
295
+ inputs=[start_date, end_date, ident, size, tool],
296
+ outputs=[report, preview],
297
+ _js="() => {return {fetched_frames_state: []}}"
298
+ ).then(
299
+ fn=lambda report, preview_frames: (preview_frames, report),
300
+ inputs=[report, preview],
301
+ outputs=[fetched_frames_state, report]
302
+ )
303
+
304
+ # Analyze button action
305
  analyze_button.click(
306
  fn=process_input,
307
  inputs=[
308
  gif_input, start_date, end_date, ident, size, tool,
309
+ lower_bound, upper_bound, param1, param2, center_tolerance, morph_iterations, min_rad, display_mode, fetched_frames_state
310
  ],
311
  outputs=[report, gallery, gif_output, preview]
312
  )