Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1388,15 +1388,30 @@ def categorize_typhoon_by_standard(wind_speed, standard='atlantic'):
|
|
| 1388 |
# -----------------------------
|
| 1389 |
|
| 1390 |
def get_available_years(typhoon_data):
|
| 1391 |
-
"""Get all available years including 2025"""
|
| 1392 |
-
|
| 1393 |
-
|
| 1394 |
-
|
| 1395 |
-
|
| 1396 |
-
|
| 1397 |
-
|
| 1398 |
-
|
| 1399 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1400 |
|
| 1401 |
def update_typhoon_options_enhanced(year, basin):
|
| 1402 |
"""Enhanced typhoon options with TD support and 2025 data"""
|
|
@@ -1663,8 +1678,24 @@ initialize_data()
|
|
| 1663 |
# -----------------------------
|
| 1664 |
|
| 1665 |
def create_interface():
|
| 1666 |
-
"""Create the enhanced Gradio interface"""
|
| 1667 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1668 |
with gr.Blocks(title="Enhanced Typhoon Analysis Platform", theme=gr.themes.Soft()) as demo:
|
| 1669 |
gr.Markdown("# πͺοΈ Enhanced Typhoon Analysis Platform")
|
| 1670 |
gr.Markdown("Advanced ML clustering, CNN predictions, and comprehensive tropical cyclone analysis including Tropical Depressions")
|
|
@@ -1684,9 +1715,9 @@ def create_interface():
|
|
| 1684 |
|
| 1685 |
### π Data Status:
|
| 1686 |
- **ONI Data**: {len(oni_data)} years loaded
|
| 1687 |
-
- **Typhoon Data**: {
|
| 1688 |
- **Merged Data**: {len(merged_data)} typhoons with ONI values
|
| 1689 |
-
- **Available Years**: {
|
| 1690 |
|
| 1691 |
### π§ Technical Capabilities:
|
| 1692 |
- **UMAP Clustering**: {"β
Available" if UMAP_AVAILABLE else "β Limited to t-SNE/PCA"}
|
|
@@ -1871,8 +1902,8 @@ def create_interface():
|
|
| 1871 |
with gr.Row():
|
| 1872 |
year_dropdown = gr.Dropdown(
|
| 1873 |
label="Year",
|
| 1874 |
-
choices=
|
| 1875 |
-
value="2024"
|
| 1876 |
)
|
| 1877 |
basin_dropdown = gr.Dropdown(
|
| 1878 |
label="Basin",
|
|
@@ -1984,26 +2015,41 @@ def create_interface():
|
|
| 1984 |
total_records = len(typhoon_data)
|
| 1985 |
|
| 1986 |
if 'SEASON' in typhoon_data.columns:
|
| 1987 |
-
|
| 1988 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1989 |
else:
|
| 1990 |
year_range = "Unknown"
|
| 1991 |
years_covered = 0
|
| 1992 |
|
| 1993 |
if 'SID' in typhoon_data.columns:
|
| 1994 |
-
|
| 1995 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1996 |
else:
|
| 1997 |
basins_available = "Unknown"
|
| 1998 |
avg_storms_per_year = 0
|
| 1999 |
|
| 2000 |
# TD specific statistics
|
| 2001 |
-
|
| 2002 |
-
|
| 2003 |
-
|
| 2004 |
-
|
| 2005 |
-
|
| 2006 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2007 |
td_storms = ts_storms = typhoon_storms = 0
|
| 2008 |
td_percentage = 0
|
| 2009 |
|
|
@@ -2039,12 +2085,66 @@ def create_interface():
|
|
| 2039 |
return demo
|
| 2040 |
except Exception as e:
|
| 2041 |
logging.error(f"Error creating Gradio interface: {e}")
|
|
|
|
|
|
|
| 2042 |
# Create a minimal fallback interface
|
| 2043 |
-
|
| 2044 |
-
|
| 2045 |
-
|
| 2046 |
-
|
| 2047 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2048 |
|
| 2049 |
# -----------------------------
|
| 2050 |
# Color Test Functions (Optional)
|
|
|
|
| 1388 |
# -----------------------------
|
| 1389 |
|
| 1390 |
def get_available_years(typhoon_data):
|
| 1391 |
+
"""Get all available years including 2025 - with error handling"""
|
| 1392 |
+
try:
|
| 1393 |
+
if typhoon_data is None or typhoon_data.empty:
|
| 1394 |
+
return [str(year) for year in range(2000, 2026)]
|
| 1395 |
+
|
| 1396 |
+
if 'ISO_TIME' in typhoon_data.columns:
|
| 1397 |
+
years = typhoon_data['ISO_TIME'].dt.year.dropna().unique()
|
| 1398 |
+
elif 'SEASON' in typhoon_data.columns:
|
| 1399 |
+
years = typhoon_data['SEASON'].dropna().unique()
|
| 1400 |
+
else:
|
| 1401 |
+
years = range(2000, 2026) # Default range including 2025
|
| 1402 |
+
|
| 1403 |
+
# Convert to strings and sort
|
| 1404 |
+
year_strings = sorted([str(int(year)) for year in years if not pd.isna(year)])
|
| 1405 |
+
|
| 1406 |
+
# Ensure we have at least some years
|
| 1407 |
+
if not year_strings:
|
| 1408 |
+
return [str(year) for year in range(2000, 2026)]
|
| 1409 |
+
|
| 1410 |
+
return year_strings
|
| 1411 |
+
|
| 1412 |
+
except Exception as e:
|
| 1413 |
+
print(f"Error in get_available_years: {e}")
|
| 1414 |
+
return [str(year) for year in range(2000, 2026)]
|
| 1415 |
|
| 1416 |
def update_typhoon_options_enhanced(year, basin):
|
| 1417 |
"""Enhanced typhoon options with TD support and 2025 data"""
|
|
|
|
| 1678 |
# -----------------------------
|
| 1679 |
|
| 1680 |
def create_interface():
|
| 1681 |
+
"""Create the enhanced Gradio interface with robust error handling"""
|
| 1682 |
try:
|
| 1683 |
+
# Ensure data is available
|
| 1684 |
+
if oni_data is None or typhoon_data is None or merged_data is None:
|
| 1685 |
+
logging.warning("Data not properly loaded, creating minimal interface")
|
| 1686 |
+
return create_minimal_fallback_interface()
|
| 1687 |
+
|
| 1688 |
+
# Get safe data statistics
|
| 1689 |
+
try:
|
| 1690 |
+
total_storms = len(typhoon_data['SID'].unique()) if 'SID' in typhoon_data.columns else 0
|
| 1691 |
+
total_records = len(typhoon_data)
|
| 1692 |
+
available_years = get_available_years(typhoon_data)
|
| 1693 |
+
year_range_display = f"{available_years[0]} - {available_years[-1]}" if available_years else "Unknown"
|
| 1694 |
+
except Exception as e:
|
| 1695 |
+
logging.error(f"Error getting data statistics: {e}")
|
| 1696 |
+
total_storms = 0
|
| 1697 |
+
total_records = 0
|
| 1698 |
+
year_range_display = "Unknown"
|
| 1699 |
with gr.Blocks(title="Enhanced Typhoon Analysis Platform", theme=gr.themes.Soft()) as demo:
|
| 1700 |
gr.Markdown("# πͺοΈ Enhanced Typhoon Analysis Platform")
|
| 1701 |
gr.Markdown("Advanced ML clustering, CNN predictions, and comprehensive tropical cyclone analysis including Tropical Depressions")
|
|
|
|
| 1715 |
|
| 1716 |
### π Data Status:
|
| 1717 |
- **ONI Data**: {len(oni_data)} years loaded
|
| 1718 |
+
- **Typhoon Data**: {total_records} records loaded
|
| 1719 |
- **Merged Data**: {len(merged_data)} typhoons with ONI values
|
| 1720 |
+
- **Available Years**: {year_range_display}
|
| 1721 |
|
| 1722 |
### π§ Technical Capabilities:
|
| 1723 |
- **UMAP Clustering**: {"β
Available" if UMAP_AVAILABLE else "β Limited to t-SNE/PCA"}
|
|
|
|
| 1902 |
with gr.Row():
|
| 1903 |
year_dropdown = gr.Dropdown(
|
| 1904 |
label="Year",
|
| 1905 |
+
choices=available_years,
|
| 1906 |
+
value=available_years[-1] if available_years else "2024"
|
| 1907 |
)
|
| 1908 |
basin_dropdown = gr.Dropdown(
|
| 1909 |
label="Basin",
|
|
|
|
| 2015 |
total_records = len(typhoon_data)
|
| 2016 |
|
| 2017 |
if 'SEASON' in typhoon_data.columns:
|
| 2018 |
+
try:
|
| 2019 |
+
min_year = int(typhoon_data['SEASON'].min())
|
| 2020 |
+
max_year = int(typhoon_data['SEASON'].max())
|
| 2021 |
+
year_range = f"{min_year}-{max_year}"
|
| 2022 |
+
years_covered = typhoon_data['SEASON'].nunique()
|
| 2023 |
+
except (ValueError, TypeError):
|
| 2024 |
+
year_range = "Unknown"
|
| 2025 |
+
years_covered = 0
|
| 2026 |
else:
|
| 2027 |
year_range = "Unknown"
|
| 2028 |
years_covered = 0
|
| 2029 |
|
| 2030 |
if 'SID' in typhoon_data.columns:
|
| 2031 |
+
try:
|
| 2032 |
+
basins_available = ', '.join(sorted(typhoon_data['SID'].str[:2].unique()))
|
| 2033 |
+
avg_storms_per_year = total_storms / max(years_covered, 1)
|
| 2034 |
+
except Exception:
|
| 2035 |
+
basins_available = "Unknown"
|
| 2036 |
+
avg_storms_per_year = 0
|
| 2037 |
else:
|
| 2038 |
basins_available = "Unknown"
|
| 2039 |
avg_storms_per_year = 0
|
| 2040 |
|
| 2041 |
# TD specific statistics
|
| 2042 |
+
try:
|
| 2043 |
+
if 'USA_WIND' in typhoon_data.columns:
|
| 2044 |
+
td_storms = len(typhoon_data[typhoon_data['USA_WIND'] < 34]['SID'].unique())
|
| 2045 |
+
ts_storms = len(typhoon_data[(typhoon_data['USA_WIND'] >= 34) & (typhoon_data['USA_WIND'] < 64)]['SID'].unique())
|
| 2046 |
+
typhoon_storms = len(typhoon_data[typhoon_data['USA_WIND'] >= 64]['SID'].unique())
|
| 2047 |
+
td_percentage = (td_storms / max(total_storms, 1)) * 100
|
| 2048 |
+
else:
|
| 2049 |
+
td_storms = ts_storms = typhoon_storms = 0
|
| 2050 |
+
td_percentage = 0
|
| 2051 |
+
except Exception as e:
|
| 2052 |
+
print(f"Error calculating TD statistics: {e}")
|
| 2053 |
td_storms = ts_storms = typhoon_storms = 0
|
| 2054 |
td_percentage = 0
|
| 2055 |
|
|
|
|
| 2085 |
return demo
|
| 2086 |
except Exception as e:
|
| 2087 |
logging.error(f"Error creating Gradio interface: {e}")
|
| 2088 |
+
import traceback
|
| 2089 |
+
traceback.print_exc()
|
| 2090 |
# Create a minimal fallback interface
|
| 2091 |
+
return create_minimal_fallback_interface()
|
| 2092 |
+
|
| 2093 |
+
def create_minimal_fallback_interface():
|
| 2094 |
+
"""Create a minimal fallback interface when main interface fails"""
|
| 2095 |
+
with gr.Blocks() as demo:
|
| 2096 |
+
gr.Markdown("# πͺοΈ Enhanced Typhoon Analysis Platform")
|
| 2097 |
+
gr.Markdown("**Notice**: Loading with minimal interface due to data issues.")
|
| 2098 |
+
|
| 2099 |
+
with gr.Tab("π Status"):
|
| 2100 |
+
gr.Markdown("""
|
| 2101 |
+
## Platform Status
|
| 2102 |
+
|
| 2103 |
+
The application is running but encountered issues loading the full interface.
|
| 2104 |
+
This could be due to:
|
| 2105 |
+
- Data loading problems
|
| 2106 |
+
- Missing dependencies
|
| 2107 |
+
- Configuration issues
|
| 2108 |
+
|
| 2109 |
+
### Available Features:
|
| 2110 |
+
- Basic interface is functional
|
| 2111 |
+
- Error logs are being generated
|
| 2112 |
+
- System is ready for debugging
|
| 2113 |
+
|
| 2114 |
+
### Next Steps:
|
| 2115 |
+
1. Check the console logs for detailed error information
|
| 2116 |
+
2. Verify all required data files are accessible
|
| 2117 |
+
3. Ensure all dependencies are properly installed
|
| 2118 |
+
4. Try restarting the application
|
| 2119 |
+
""")
|
| 2120 |
+
|
| 2121 |
+
with gr.Tab("π§ Debug"):
|
| 2122 |
+
gr.Markdown("## Debug Information")
|
| 2123 |
+
|
| 2124 |
+
def get_debug_info():
|
| 2125 |
+
debug_text = f"""
|
| 2126 |
+
Python Environment:
|
| 2127 |
+
- Working Directory: {os.getcwd()}
|
| 2128 |
+
- Data Path: {DATA_PATH}
|
| 2129 |
+
- UMAP Available: {UMAP_AVAILABLE}
|
| 2130 |
+
- CNN Available: {CNN_AVAILABLE}
|
| 2131 |
+
|
| 2132 |
+
Data Status:
|
| 2133 |
+
- ONI Data: {'Loaded' if oni_data is not None else 'Failed'}
|
| 2134 |
+
- Typhoon Data: {'Loaded' if typhoon_data is not None else 'Failed'}
|
| 2135 |
+
- Merged Data: {'Loaded' if merged_data is not None else 'Failed'}
|
| 2136 |
+
|
| 2137 |
+
File Checks:
|
| 2138 |
+
- ONI Path Exists: {os.path.exists(ONI_DATA_PATH)}
|
| 2139 |
+
- Typhoon Path Exists: {os.path.exists(TYPHOON_DATA_PATH)}
|
| 2140 |
+
"""
|
| 2141 |
+
return debug_text
|
| 2142 |
+
|
| 2143 |
+
debug_btn = gr.Button("Get Debug Info")
|
| 2144 |
+
debug_output = gr.Textbox(label="Debug Information", lines=15)
|
| 2145 |
+
debug_btn.click(fn=get_debug_info, outputs=debug_output)
|
| 2146 |
+
|
| 2147 |
+
return demo
|
| 2148 |
|
| 2149 |
# -----------------------------
|
| 2150 |
# Color Test Functions (Optional)
|