| """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 |
|
|