"""Tests for cross-indicator compound signal detection.""" import numpy as np import pytest def test_compute_overlap_pct(): from app.analysis.compound import compute_overlap_pct a = np.array([[True, True, False], [False, False, True]], dtype=bool) b = np.array([[True, False, False], [False, False, True]], dtype=bool) pct = compute_overlap_pct(a, b) assert pct > 0 def test_detect_land_conversion(): from app.analysis.compound import detect_compound_signals ndvi_z = np.full((10, 10), -2.5, dtype=np.float32) buildup_z = np.full((10, 10), 2.5, dtype=np.float32) water_z = np.zeros((10, 10), dtype=np.float32) sar_z = np.zeros((10, 10), dtype=np.float32) signals = detect_compound_signals( zscore_rasters={"ndvi": ndvi_z, "water": water_z, "sar": sar_z, "buildup": buildup_z}, pixel_area_ha=0.04, threshold=2.0, ) land_conv = [s for s in signals if s.name == "land_conversion"] assert len(land_conv) == 1 assert land_conv[0].triggered is True assert "ndvi" in land_conv[0].indicators assert "buildup" in land_conv[0].indicators def test_no_signals_when_all_normal(): from app.analysis.compound import detect_compound_signals normal = np.zeros((10, 10), dtype=np.float32) signals = detect_compound_signals( zscore_rasters={"ndvi": normal, "water": normal, "sar": normal, "buildup": normal}, pixel_area_ha=0.04, threshold=2.0, ) triggered = [s for s in signals if s.triggered] assert len(triggered) == 0 def test_flood_signal(): from app.analysis.compound import detect_compound_signals sar_z = np.full((10, 10), -2.5, dtype=np.float32) water_z = np.full((10, 10), 2.5, dtype=np.float32) ndvi_z = np.zeros((10, 10), dtype=np.float32) buildup_z = np.zeros((10, 10), dtype=np.float32) signals = detect_compound_signals( zscore_rasters={"ndvi": ndvi_z, "water": water_z, "sar": sar_z, "buildup": buildup_z}, pixel_area_ha=0.04, threshold=2.0, ) flood = [s for s in signals if s.name == "flood_event"] assert len(flood) == 1 assert flood[0].triggered is True