Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -985,29 +985,25 @@ def generate_genesis_prediction_monthly(month, oni_value, year=2025):
|
|
| 985 |
# Check for genesis events (GPI > threshold)
|
| 986 |
genesis_threshold = 1.5 # Adjusted threshold
|
| 987 |
if np.max(gpi_field) > genesis_threshold:
|
| 988 |
-
#
|
| 989 |
-
|
| 990 |
-
|
| 991 |
-
|
| 992 |
-
|
| 993 |
-
|
| 994 |
-
|
| 995 |
genesis_lat = lat_range[max_i]
|
| 996 |
genesis_lon = lon_range[max_j]
|
| 997 |
|
| 998 |
-
# Adjust location using
|
| 999 |
-
# model with AI post-processing bias corrections. Real
|
| 1000 |
-
# systems such as IBM's GRAF combine NWP output with
|
| 1001 |
-
# machine learning to refine genesis estimates.
|
| 1002 |
genesis_lat, genesis_lon = adjust_genesis_location_with_nwp_ai(
|
| 1003 |
genesis_lat, genesis_lon, month, oni_value
|
| 1004 |
)
|
| 1005 |
genesis_gpi = gpi_field[max_i, max_j]
|
| 1006 |
-
|
| 1007 |
# Determine probability of actual genesis
|
| 1008 |
-
# Probability influenced by ONI to mimic El Niño/La Niña effects
|
| 1009 |
genesis_prob = np.clip(
|
| 1010 |
-
0.
|
| 1011 |
)
|
| 1012 |
|
| 1013 |
if np.random.random() < genesis_prob:
|
|
@@ -1216,6 +1212,8 @@ def create_predict_animation(prediction_data, enable_animation=True):
|
|
| 1216 |
# figure out map bounds
|
| 1217 |
all_lats = [pt['lat'] for s in storms for pt in s.get('track',[])]
|
| 1218 |
all_lons = [pt['lon'] for s in storms for pt in s.get('track',[])]
|
|
|
|
|
|
|
| 1219 |
mb = {
|
| 1220 |
'lat_min': min(5, min(all_lats)-5) if all_lats else 5,
|
| 1221 |
'lat_max': max(35, max(all_lats)+5) if all_lats else 35,
|
|
@@ -1412,9 +1410,11 @@ def create_genesis_animation(prediction_data, enable_animation=True):
|
|
| 1412 |
|
| 1413 |
# ---- 2) Build animation frames ----
|
| 1414 |
frames = []
|
| 1415 |
-
# determine map bounds from
|
| 1416 |
all_lats = [pt['lat'] for storm in storm_predictions for pt in storm.get('track', [])]
|
| 1417 |
all_lons = [pt['lon'] for storm in storm_predictions for pt in storm.get('track', [])]
|
|
|
|
|
|
|
| 1418 |
map_bounds = {
|
| 1419 |
'lat_min': min(5, min(all_lats) - 5) if all_lats else 5,
|
| 1420 |
'lat_max': max(35, max(all_lats) + 5) if all_lats else 35,
|
|
|
|
| 985 |
# Check for genesis events (GPI > threshold)
|
| 986 |
genesis_threshold = 1.5 # Adjusted threshold
|
| 987 |
if np.max(gpi_field) > genesis_threshold:
|
| 988 |
+
# Consider top candidate locations rather than a single point
|
| 989 |
+
candidate_mask = gpi_field >= np.percentile(gpi_field, 97)
|
| 990 |
+
cand_indices = np.argwhere(candidate_mask)
|
| 991 |
+
np.random.shuffle(cand_indices)
|
| 992 |
+
cand_indices = cand_indices[:3] # up to 3 candidates per day
|
| 993 |
+
|
| 994 |
+
for (max_i, max_j) in cand_indices:
|
| 995 |
genesis_lat = lat_range[max_i]
|
| 996 |
genesis_lon = lon_range[max_j]
|
| 997 |
|
| 998 |
+
# Adjust location using simplified NWP+AI corrections
|
|
|
|
|
|
|
|
|
|
| 999 |
genesis_lat, genesis_lon = adjust_genesis_location_with_nwp_ai(
|
| 1000 |
genesis_lat, genesis_lon, month, oni_value
|
| 1001 |
)
|
| 1002 |
genesis_gpi = gpi_field[max_i, max_j]
|
| 1003 |
+
|
| 1004 |
# Determine probability of actual genesis
|
|
|
|
| 1005 |
genesis_prob = np.clip(
|
| 1006 |
+
0.4 + genesis_gpi / 3.5 + 0.2 * np.tanh(oni_value), 0, 0.95
|
| 1007 |
)
|
| 1008 |
|
| 1009 |
if np.random.random() < genesis_prob:
|
|
|
|
| 1212 |
# figure out map bounds
|
| 1213 |
all_lats = [pt['lat'] for s in storms for pt in s.get('track',[])]
|
| 1214 |
all_lons = [pt['lon'] for s in storms for pt in s.get('track',[])]
|
| 1215 |
+
all_lats += [g['lat'] for g in prediction_data.get('genesis_events', [])]
|
| 1216 |
+
all_lons += [g['lon'] for g in prediction_data.get('genesis_events', [])]
|
| 1217 |
mb = {
|
| 1218 |
'lat_min': min(5, min(all_lats)-5) if all_lats else 5,
|
| 1219 |
'lat_max': max(35, max(all_lats)+5) if all_lats else 35,
|
|
|
|
| 1410 |
|
| 1411 |
# ---- 2) Build animation frames ----
|
| 1412 |
frames = []
|
| 1413 |
+
# determine map bounds from storm tracks and genesis points
|
| 1414 |
all_lats = [pt['lat'] for storm in storm_predictions for pt in storm.get('track', [])]
|
| 1415 |
all_lons = [pt['lon'] for storm in storm_predictions for pt in storm.get('track', [])]
|
| 1416 |
+
all_lats += [g['lat'] for g in prediction_data.get('genesis_events', [])]
|
| 1417 |
+
all_lons += [g['lon'] for g in prediction_data.get('genesis_events', [])]
|
| 1418 |
map_bounds = {
|
| 1419 |
'lat_min': min(5, min(all_lats) - 5) if all_lats else 5,
|
| 1420 |
'lat_max': max(35, max(all_lats) + 5) if all_lats else 35,
|