"""Tests for pixel-level change detection.""" import numpy as np import pytest def test_compute_zscore_raster(): from app.analysis.change import compute_zscore_raster current = np.array([[0.5, 0.3], [0.7, 0.4]], dtype=np.float32) baseline_mean = np.array([[0.6, 0.6], [0.6, 0.6]], dtype=np.float32) baseline_std = np.array([[0.05, 0.05], [0.05, 0.05]], dtype=np.float32) z = compute_zscore_raster(current, baseline_mean, baseline_std, min_std=0.02) expected = np.array([[-2.0, -6.0], [2.0, -4.0]], dtype=np.float32) np.testing.assert_array_almost_equal(z, expected, decimal=1) def test_compute_zscore_raster_clamps_std(): from app.analysis.change import compute_zscore_raster current = np.array([[0.5]], dtype=np.float32) baseline_mean = np.array([[0.5]], dtype=np.float32) baseline_std = np.array([[0.001]], dtype=np.float32) z = compute_zscore_raster(current, baseline_mean, baseline_std, min_std=0.02) assert z[0, 0] == pytest.approx(0.0, abs=0.01) def test_detect_hotspots(): from app.analysis.change import detect_hotspots z = np.array([[-3.0, 0.5, 2.5], [1.0, -0.3, -2.1]], dtype=np.float32) mask, pct = detect_hotspots(z, threshold=2.0) assert mask[0, 0] == True assert mask[0, 1] == False assert mask[0, 2] == True assert mask[1, 2] == True assert pct == pytest.approx(50.0, abs=0.1) def test_cluster_hotspots(): from app.analysis.change import cluster_hotspots mask = np.array([ [True, True, False, False, False], [True, True, False, False, False], [False, False, False, True, True], [False, False, False, True, True], ], dtype=bool) z = np.array([ [-2.5, -2.3, 0.0, 0.0, 0.0], [-2.1, -2.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 2.5, 2.3], [0.0, 0.0, 0.0, 2.1, 2.8], ], dtype=np.float32) clusters = cluster_hotspots(mask, z, pixel_area_ha=1.0, min_pixels=2) assert len(clusters) == 2 assert clusters[0]["area_ha"] == 4.0 assert clusters[1]["area_ha"] == 4.0 def test_cluster_hotspots_filters_small(): from app.analysis.change import cluster_hotspots mask = np.array([[True, False, False], [False, False, True]], dtype=bool) z = np.full((2, 3), -2.5, dtype=np.float32) clusters = cluster_hotspots(mask, z, pixel_area_ha=1.0, min_pixels=2) assert len(clusters) == 0