""" config.py — Single source of truth for all hyperparameters, paths, and API keys. All configurable values live here. Import this module anywhere you need a path, a training parameter, or an API endpoint. """ import os from pathlib import Path from dotenv import load_dotenv # --------------------------------------------------------------------------- # Load .env file (if present) for API keys # --------------------------------------------------------------------------- load_dotenv() # --------------------------------------------------------------------------- # Project Root — resolved relative to this file's location # --------------------------------------------------------------------------- PROJECT_ROOT = Path(__file__).resolve().parents[2] # multi-hazard-warning-system/ # --------------------------------------------------------------------------- # Directory Structure # --------------------------------------------------------------------------- DATA_DIR = PROJECT_ROOT / "data" RAW_DIR = DATA_DIR / "raw" FIRMS_RAW_DIR = RAW_DIR / "firms" WEATHER_RAW_DIR = RAW_DIR / "weather" AQI_RAW_DIR = RAW_DIR / "aqi" PROCESSED_DIR = DATA_DIR / "processed" IMAGE_PATCHES_DIR = PROCESSED_DIR / "image_patches" TIMESERIES_DIR = PROCESSED_DIR / "timeseries" SPLITS_DIR = DATA_DIR / "splits" CHECKPOINTS_DIR = PROJECT_ROOT / "checkpoints" OUTPUTS_DIR = PROJECT_ROOT / "outputs" NOTEBOOKS_DIR = PROJECT_ROOT / "notebooks" # Auto-create directories for _dir in [ FIRMS_RAW_DIR, WEATHER_RAW_DIR, AQI_RAW_DIR, IMAGE_PATCHES_DIR, TIMESERIES_DIR, SPLITS_DIR, CHECKPOINTS_DIR, OUTPUTS_DIR, NOTEBOOKS_DIR, ]: _dir.mkdir(parents=True, exist_ok=True) # --------------------------------------------------------------------------- # API Keys & Endpoints # --------------------------------------------------------------------------- NASA_FIRMS_API_KEY = os.getenv("NASA_FIRMS_API_KEY", "") OPENAQ_API_KEY = os.getenv("OPENAQ_API_KEY", "") FIRMS_BASE_URL = "https://firms.modaps.eosdis.nasa.gov/api/area/csv" OPEN_METEO_URL = "https://archive-api.open-meteo.com/v1/archive" OPENAQ_BASE_URL = "https://api.openaq.org/v2" # --------------------------------------------------------------------------- # Geographic Defaults (California wildfire region) # --------------------------------------------------------------------------- DEFAULT_LATITUDE = 37.5 DEFAULT_LONGITUDE = -120.3 DEFAULT_BBOX = "-122.0,36.0,-118.0,39.0" # west, south, east, north PATCH_SIZE = 128 # spatial resolution of image patches # --------------------------------------------------------------------------- # Data Pipeline # --------------------------------------------------------------------------- TIMESERIES_WINDOW = 7 # days of weather/AQI history per sample TIMESERIES_FEATURES = 6 # temp, humidity, wind_speed, wind_dir, precip, PM2.5 IMAGE_CHANNELS = 4 # RGB + Near-Infrared FIRE_CONFIDENCE_THRESHOLD = 80 # minimum FIRMS confidence score NUM_SYNTHETIC_SAMPLES = 500 # fallback sample count when APIs are unavailable # --------------------------------------------------------------------------- # Model Architecture # --------------------------------------------------------------------------- CNN_FEATURE_DIM = 2048 # ResNet-50 output features LSTM_HIDDEN_SIZE = 128 # per-direction hidden size LSTM_NUM_LAYERS = 2 LSTM_BIDIRECTIONAL = True LSTM_FEATURE_DIM = LSTM_HIDDEN_SIZE * (2 if LSTM_BIDIRECTIONAL else 1) # 256 FUSION_DIM = CNN_FEATURE_DIM + LSTM_FEATURE_DIM # 2304 SHARED_FC_DIMS = [512, 256] DROPOUT_RATE = 0.3 # Task 1: Wildfire Risk Heatmap HEATMAP_SIZE = (PATCH_SIZE, PATCH_SIZE) # 128×128 # Task 2: AQI Forecast AQI_FORECAST_HOURS = 72 # predict 72 hourly values (24–72 hrs) # --------------------------------------------------------------------------- # Training Hyperparameters # --------------------------------------------------------------------------- BATCH_SIZE = 16 LEARNING_RATE = 1e-4 WEIGHT_DECAY = 1e-5 NUM_EPOCHS = 50 EARLY_STOP_PATIENCE = 10 LAMBDA_AQI = 0.5 # weighting factor for AQI loss in combined loss TRAIN_RATIO = 0.70 VAL_RATIO = 0.15 TEST_RATIO = 0.15 # --------------------------------------------------------------------------- # Device # --------------------------------------------------------------------------- import torch DEVICE = "cpu" # HF Spaces free tier: CPU only # --------------------------------------------------------------------------- # Weights & Biases # --------------------------------------------------------------------------- WANDB_PROJECT = "multi-hazard-mtl" WANDB_ENTITY = os.getenv("WANDB_ENTITY", None) USE_WANDB = False # Disabled for deployment # --------------------------------------------------------------------------- # Checkpoint naming # --------------------------------------------------------------------------- BEST_MODEL_NAME = "best_mtl_model.pth" BEST_MODEL_PATH = CHECKPOINTS_DIR / BEST_MODEL_NAME # --------------------------------------------------------------------------- # Inference # --------------------------------------------------------------------------- RISK_THRESHOLDS = { "Low": (0.0, 0.25), "Medium": (0.25, 0.50), "High": (0.50, 0.75), "Extreme": (0.75, 1.0), } # AQI categories (WHO / US EPA aligned) AQI_CATEGORIES = { "Good": (0, 50), "Moderate": (51, 100), "Unhealthy (Sensitive)": (101, 150), "Unhealthy": (151, 200), "Very Unhealthy": (201, 300), "Hazardous": (301, 500), }