Files
lidar_rendu/lidar_pipeline/tests/test_quality.py
2026-09-27 15:11:47 +02:00

92 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Tests de la mesure de qualité des dalles (densité sol, date d'acquisition)."""
BOUNDS = (652000.0, 6861000.0, 653000.0, 6862000.0)
def _gps_seconds(year, month, day):
"""Temps GPS ajusté standard (secondes GPS − 1e9) d'un midi UTC."""
from datetime import datetime, timezone
epoch = datetime(1980, 1, 6, tzinfo=timezone.utc)
return (datetime(year, month, day, 12, tzinfo=timezone.utc) - epoch).total_seconds() - 1e9
def test_gps_adjusted_to_date():
from lidar_pipeline.quality import gps_adjusted_to_date
assert gps_adjusted_to_date(_gps_seconds(2023, 3, 15)) == "2023-03-15"
def test_compute_quality_density_grid_and_dates():
import numpy as np
from lidar_pipeline.quality import compute_quality
# 1 point par m² sur la moitié nord, rien au sud ; 2 dates de vol.
xs, ys = np.meshgrid(np.arange(652000.5, 653000.0, 1.0),
np.arange(6861500.5, 6862000.0, 1.0))
x, y = xs.ravel(), ys.ravel()
t = np.where(x < 652500, _gps_seconds(2023, 3, 15), _gps_seconds(2023, 3, 17))
q = compute_quality(x, y, t, BOUNDS)
assert q["version"] == 1
assert abs(q["ground_density"] - 0.5) < 1e-6
grid = q["density_grid"]
assert len(grid) == 20 and all(len(r) == 20 for r in grid)
assert grid[0][0] == 1.0 # ligne 0 = nord : couverte
assert grid[19][0] == 0.0 # sud : vide
assert q["acq_start"] == "2023-03-15" and q["acq_end"] == "2023-03-17"
assert q["acq_source"] == "gps"
# 1 point par m² : 1 pixel 0,2 m sur 25 occupé au nord, aucun au sud.
assert abs(q["empty_fraction"] - (1 - 0.5 / 25)) < 1e-3
def test_compute_quality_ignores_points_outside_bounds():
import numpy as np
from lidar_pipeline.quality import compute_quality
x = np.array([652500.0, 660000.0]); y = np.array([6861500.0, 6861500.0])
q = compute_quality(x, y, None, BOUNDS, header_date="2024-05-03")
assert abs(q["ground_density"] - 1e-6) < 1e-9
assert q["acq_start"] == q["acq_end"] == "2024-05-03"
assert q["acq_source"] == "header"
def test_compute_quality_week_time_falls_back_to_header():
import numpy as np
from lidar_pipeline.quality import compute_quality
x = np.array([652500.0]); y = np.array([6861500.0])
q = compute_quality(x, y, np.array([345600.0]), BOUNDS, gps_adjusted=False,
header_date="2024-05-03")
assert q["acq_source"] == "header" and q["acq_start"] == "2024-05-03"
def test_compute_quality_empty_tile():
import numpy as np
from lidar_pipeline.quality import compute_quality
q = compute_quality(np.array([]), np.array([]), np.array([]), BOUNDS)
assert q["ground_density"] == 0.0 and q["empty_fraction"] == 1.0
assert q["acq_start"] is None and q["acq_end"] is None and q["acq_source"] is None
def test_sidecar_roundtrip_and_table(tmp_path):
from lidar_pipeline.quality import (load_quality_table, quality_path,
read_quality, write_quality)
base = "LHD_FXX_0652_6862_PTS_LAMB93_IGN69"
data = {"version": 1, "ground_density": 4.2}
assert write_quality(tmp_path, base, data) is True
assert write_quality(tmp_path, base, data) is False # contenu identique : pas réécrit
assert quality_path(tmp_path, base).is_file()
assert read_quality(tmp_path, base) == data
assert load_quality_table(tmp_path) == {base: data}
def test_read_quality_rejects_other_version(tmp_path):
from lidar_pipeline.quality import read_quality, write_quality
base = "LHD_FXX_0652_6862_PTS_LAMB93_IGN69"
write_quality(tmp_path, base, {"version": 0})
assert read_quality(tmp_path, base) is None
def test_quality_module_imports_without_numpy():
"""L'image légère n'a pas numpy : le module ne doit pas l'importer au chargement."""
import subprocess, sys
code = ("import sys; sys.modules['numpy'] = None; "
"import lidar_pipeline.quality as q; print(q.QUALITY_VERSION)")
r = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True)
assert r.returncode == 0, r.stderr