euler314 commited on
Commit
8c18f53
·
verified ·
1 Parent(s): 063bd99

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -0
app.py CHANGED
@@ -1557,7 +1557,163 @@ def predict_storm_route_and_intensity_with_oceanic_data(
1557
  # -----------------------------
1558
  # FIXED: ADVANCED ML FEATURES WITH ROBUST ERROR HANDLING
1559
  # -----------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1560
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1561
  def extract_storm_features(typhoon_data):
1562
  """Extract comprehensive features for clustering analysis - FIXED VERSION"""
1563
  try:
 
1557
  # -----------------------------
1558
  # FIXED: ADVANCED ML FEATURES WITH ROBUST ERROR HANDLING
1559
  # -----------------------------
1560
+ def calculate_environmental_steering_speed(lat, lon, month, oni_value, slp_data):
1561
+ """Calculate storm forward speed based on environmental steering"""
1562
+ base_speed = 0.15 # Default speed in degrees/hour
1563
+
1564
+ # Latitude effects
1565
+ if lat < 20:
1566
+ speed_factor = 0.8 # Slower in tropics
1567
+ elif lat < 30:
1568
+ speed_factor = 1.2 # Faster in subtropics
1569
+ else:
1570
+ speed_factor = 1.5 # Fast in mid-latitudes
1571
+
1572
+ # Pressure gradient effects (if SLP data available)
1573
+ if slp_data and slp_data['success']:
1574
+ try:
1575
+ # Calculate approximate pressure gradient (simplified)
1576
+ slp_value = oceanic_manager.interpolate_data_to_point(slp_data, lat, lon, 'slp')
1577
+ if not np.isnan(slp_value):
1578
+ slp_hpa = slp_value if slp_value > 500 else slp_value / 100
1579
+ if slp_hpa < 1008: # Low pressure - faster motion
1580
+ speed_factor *= 1.2
1581
+ elif slp_hpa > 1015: # High pressure - slower motion
1582
+ speed_factor *= 0.8
1583
+ except:
1584
+ pass
1585
+
1586
+ return base_speed * speed_factor
1587
+
1588
+ def calculate_motion_tendency(lat, lon, month, oni_value, hour, slp_data):
1589
+ """Calculate motion tendency with environmental steering"""
1590
+ # Base climatological motion
1591
+ ridge_position = 32 + 4 * np.sin(2 * np.pi * (month - 6) / 4)
1592
+
1593
+ if lat < ridge_position - 10:
1594
+ base_lat_tendency = 0.05 # Poleward
1595
+ base_lon_tendency = -0.12 # Westward
1596
+ elif lat > ridge_position - 3:
1597
+ base_lat_tendency = 0.15 # Strong poleward (recurvature)
1598
+ base_lon_tendency = 0.08 # Eastward
1599
+ else:
1600
+ base_lat_tendency = 0.08 # Moderate poleward
1601
+ base_lon_tendency = -0.06 # Moderate westward
1602
+
1603
+ # ENSO steering effects
1604
+ if oni_value > 0.5: # El Niño
1605
+ base_lon_tendency += 0.03 # More eastward
1606
+ base_lat_tendency += 0.01 # Slightly more poleward
1607
+ elif oni_value < -0.5: # La Niña
1608
+ base_lon_tendency -= 0.04 # More westward
1609
+
1610
+ # Add realistic motion uncertainty
1611
+ motion_uncertainty = 0.02 + (hour / 120) * 0.03
1612
+ lat_noise = np.random.normal(0, motion_uncertainty)
1613
+ lon_noise = np.random.normal(0, motion_uncertainty)
1614
+
1615
+ return base_lat_tendency + lat_noise, base_lon_tendency + lon_noise
1616
+
1617
+ def calculate_environmental_intensity_change(
1618
+ current_intensity, environmental_limit, hour, lat, lon, month, oni_value, sst_data
1619
+ ):
1620
+ """Calculate intensity change based on environmental conditions"""
1621
+
1622
+ # Base intensity tendency based on development stage
1623
+ if hour <= 48: # Development phase
1624
+ if current_intensity < environmental_limit * 0.6:
1625
+ base_tendency = 3.5 # Rapid development possible
1626
+ elif current_intensity < environmental_limit * 0.8:
1627
+ base_tendency = 2.0 # Moderate development
1628
+ else:
1629
+ base_tendency = 0.5 # Near limit
1630
+ elif hour <= 120: # Mature phase
1631
+ if current_intensity < environmental_limit:
1632
+ base_tendency = 1.0 # Slow intensification
1633
+ else:
1634
+ base_tendency = -0.5 # Slight weakening
1635
+ else: # Extended phase
1636
+ base_tendency = -2.0 # General weakening trend
1637
+
1638
+ # Environmental limit constraint
1639
+ if current_intensity >= environmental_limit:
1640
+ base_tendency = min(base_tendency, -1.0) # Force weakening if over limit
1641
+
1642
+ # SST effects on development rate
1643
+ if sst_data and sst_data['success']:
1644
+ try:
1645
+ sst_value = oceanic_manager.interpolate_data_to_point(sst_data, lat, lon, 'sst')
1646
+ if not np.isnan(sst_value):
1647
+ sst_celsius = sst_value if sst_value < 50 else sst_value - 273.15
1648
+ if sst_celsius >= 29.5: # Very warm - enhanced development
1649
+ base_tendency += 1.5
1650
+ elif sst_celsius >= 28.0: # Warm - normal development
1651
+ base_tendency += 0.5
1652
+ elif sst_celsius < 26.5: # Cool - inhibited development
1653
+ base_tendency -= 2.0
1654
+ except:
1655
+ pass
1656
+
1657
+ # Land interaction
1658
+ if lon < 110 or (120 < lon < 125 and lat > 20): # Near land masses
1659
+ base_tendency -= 8.0
1660
+
1661
+ # High latitude weakening
1662
+ if lat > 35:
1663
+ base_tendency -= 10.0
1664
+ elif lat > 30:
1665
+ base_tendency -= 4.0
1666
+
1667
+ # Add realistic intensity uncertainty
1668
+ intensity_noise = np.random.normal(0, 1.0)
1669
+
1670
+ return base_tendency + intensity_noise
1671
 
1672
+ def calculate_dynamic_confidence(hour, lat, lon, use_real_data, sst_success, slp_success):
1673
+ """Calculate dynamic confidence based on data availability and conditions"""
1674
+ base_confidence = 0.92
1675
+
1676
+ # Time penalty
1677
+ time_penalty = (hour / 120) * 0.35
1678
+
1679
+ # Data quality bonus
1680
+ data_bonus = 0.0
1681
+ if use_real_data:
1682
+ if sst_success:
1683
+ data_bonus += 0.08
1684
+ if slp_success:
1685
+ data_bonus += 0.05
1686
+
1687
+ # Environmental uncertainty
1688
+ environment_penalty = 0.0
1689
+ if lat > 30 or lon < 115: # Challenging forecast regions
1690
+ environment_penalty = 0.12
1691
+ elif lat > 25:
1692
+ environment_penalty = 0.06
1693
+
1694
+ final_confidence = base_confidence + data_bonus - time_penalty - environment_penalty
1695
+ return max(0.25, min(0.95, final_confidence))
1696
+
1697
+ def get_environmental_development_stage(hour, intensity, environmental_limit):
1698
+ """Determine development stage based on time and environmental context"""
1699
+ intensity_fraction = intensity / max(environmental_limit, 50)
1700
+
1701
+ if hour <= 24:
1702
+ return 'Genesis'
1703
+ elif hour <= 72:
1704
+ if intensity_fraction < 0.3:
1705
+ return 'Early Development'
1706
+ elif intensity_fraction < 0.6:
1707
+ return 'Active Development'
1708
+ else:
1709
+ return 'Rapid Development'
1710
+ elif hour <= 120:
1711
+ if intensity_fraction > 0.8:
1712
+ return 'Peak Intensity'
1713
+ else:
1714
+ return 'Mature Stage'
1715
+ else:
1716
+ return 'Extended Forecast'
1717
  def extract_storm_features(typhoon_data):
1718
  """Extract comprehensive features for clustering analysis - FIXED VERSION"""
1719
  try: