Update docs for GPU selection, fix test assertions + test_pipeline
This commit is contained in:
@ -69,35 +69,6 @@ class TestSMRFPipeline:
|
||||
assert writer["filename"] == "/output/a_ground.las"
|
||||
|
||||
|
||||
class TestPMFPipeline:
|
||||
def test_pipeline_json_valid(self):
|
||||
"""create_pmf_pipeline produces valid JSON with PMF filter."""
|
||||
from lidar_pipeline.dtm import create_pmf_pipeline
|
||||
result = create_pmf_pipeline("/data/input/test.laz", "/data/output/test_ground.las")
|
||||
pipeline = json.loads(result)
|
||||
|
||||
assert "pipeline" in pipeline
|
||||
stages = pipeline["pipeline"]
|
||||
stage_types = [s.get("type") if isinstance(s, dict) else None for s in stages]
|
||||
|
||||
# Must contain PMF filter
|
||||
assert "filters.pmf" in stage_types
|
||||
|
||||
# Must contain ReturnNumber filter
|
||||
range_stages = [s for s in stages if isinstance(s, dict) and s.get("type") == "filters.range"]
|
||||
assert any("ReturnNumber" in str(s.get("limits", "")) for s in range_stages)
|
||||
|
||||
def test_pmf_parameters(self):
|
||||
"""PMF pipeline has expected parameters."""
|
||||
from lidar_pipeline.dtm import create_pmf_pipeline
|
||||
result = create_pmf_pipeline("/input/a.laz", "/output/a_ground.las")
|
||||
pipeline = json.loads(result)
|
||||
|
||||
pmf_stage = [s for s in pipeline["pipeline"] if isinstance(s, dict) and s.get("type") == "filters.pmf"][0]
|
||||
assert pmf_stage["max_window"] == 33
|
||||
assert pmf_stage["slope"] == 0.15
|
||||
|
||||
|
||||
class TestCSFPipeline:
|
||||
def test_pipeline_json_valid(self):
|
||||
"""create_csf_pipeline produces valid JSON with CSF filter."""
|
||||
@ -140,8 +111,8 @@ class TestDetectGroundMethod:
|
||||
return mock_las
|
||||
|
||||
@patch('lidar_pipeline.dtm.laspy')
|
||||
def test_urban_terrain_returns_pmf(self, mock_laspy):
|
||||
"""High single-return ratio (>0.6) should select PMF."""
|
||||
def test_urban_terrain_returns_csf(self, mock_laspy):
|
||||
"""High single-return ratio (>0.6) should select CSF."""
|
||||
from lidar_pipeline.dtm import detect_ground_method
|
||||
|
||||
# 70% single returns = urban
|
||||
@ -153,7 +124,7 @@ class TestDetectGroundMethod:
|
||||
mock_laspy.read.return_value = self._make_mock_las(num_returns, z_values)
|
||||
|
||||
result = detect_ground_method(Path("/data/input/test.laz"))
|
||||
assert result == 'pmf'
|
||||
assert result == 'csf'
|
||||
|
||||
@patch('lidar_pipeline.dtm.laspy')
|
||||
def test_natural_terrain_returns_smrf(self, mock_laspy):
|
||||
@ -172,8 +143,8 @@ class TestDetectGroundMethod:
|
||||
assert result == 'smrf'
|
||||
|
||||
@patch('lidar_pipeline.dtm.laspy')
|
||||
def test_mountainous_terrain_still_defaults_to_smrf(self, mock_laspy):
|
||||
"""High variance terrain defaults to SMRF in auto mode (CSF only via --ground-classification csf)."""
|
||||
def test_mountainous_terrain_returns_csf(self, mock_laspy):
|
||||
"""High variance terrain (>30m std) selects CSF for complex terrain."""
|
||||
from lidar_pipeline.dtm import detect_ground_method
|
||||
|
||||
# Moderate single-return ratio but very high height variance
|
||||
@ -185,7 +156,7 @@ class TestDetectGroundMethod:
|
||||
mock_laspy.read.return_value = self._make_mock_las(num_returns, z_values)
|
||||
|
||||
result = detect_ground_method(Path("/data/input/test.laz"))
|
||||
assert result == 'smrf'
|
||||
assert result == 'csf'
|
||||
|
||||
|
||||
class TestClassifyGroundMethod:
|
||||
@ -195,8 +166,8 @@ class TestClassifyGroundMethod:
|
||||
"""classify_ground with method='auto' should call detect_ground_method."""
|
||||
from lidar_pipeline.dtm import classify_ground
|
||||
|
||||
# Mock detect_ground_method to return 'pmf'
|
||||
with patch('lidar_pipeline.dtm.detect_ground_method', return_value='pmf') as mock_detect:
|
||||
# Mock detect_ground_method to return 'csf'
|
||||
with patch('lidar_pipeline.dtm.detect_ground_method', return_value='csf') as mock_detect:
|
||||
mock_subprocess.run.return_value = MagicMock(returncode=0)
|
||||
result = classify_ground(Path("/data/input/test.laz"), Path("/tmp"), method='auto')
|
||||
|
||||
@ -225,8 +196,8 @@ class TestClassifyGroundMethod:
|
||||
|
||||
@patch('lidar_pipeline.dtm.subprocess')
|
||||
@patch('lidar_pipeline.dtm.laspy')
|
||||
def test_classify_ground_pmf_uses_pmf_pipeline(self, mock_laspy, mock_subprocess):
|
||||
"""classify_ground with method='pmf' should create PMF pipeline."""
|
||||
def test_classify_ground_csf_uses_csf_pipeline(self, mock_laspy, mock_subprocess):
|
||||
"""classify_ground with method='csf' should create CSF pipeline."""
|
||||
from lidar_pipeline.dtm import classify_ground
|
||||
|
||||
mock_subprocess.run.return_value = MagicMock(returncode=0)
|
||||
@ -234,10 +205,10 @@ class TestClassifyGroundMethod:
|
||||
with patch('lidar_pipeline.dtm.detect_ground_method'):
|
||||
import tempfile
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
result = classify_ground(Path("/data/input/test.laz"), Path(tmpdir), method='pmf')
|
||||
result = classify_ground(Path("/data/input/test.laz"), Path(tmpdir), method='csf')
|
||||
|
||||
pipeline_file = Path(tmpdir) / "pipeline_pmf.json"
|
||||
pipeline_file = Path(tmpdir) / "pipeline_csf.json"
|
||||
if pipeline_file.exists():
|
||||
pipeline = json.loads(pipeline_file.read_text())
|
||||
stage_types = [s.get("type") if isinstance(s, dict) else None for s in pipeline["pipeline"]]
|
||||
assert "filters.pmf" in stage_types
|
||||
assert "filters.csf" in stage_types
|
||||
Reference in New Issue
Block a user