From cd5bf540665de906e48265a1aaf7e28279c8acbf Mon Sep 17 00:00:00 2001 From: Antoine Jacquin Date: Mon, 7 Sep 2026 21:21:57 +0200 Subject: [PATCH] Fix dangerous pkill, circular import, and dedup _res_suffix - Scope pkill to 'pdal pipeline' (avoids killing unrelated PDAL jobs) - Inline _strip_lidar_ext in dtm.py to remove circular import from pipeline - _res_suffix_str now delegates to LidarArchaeoPipeline._res_suffix --- lidar_pipeline/cli.py | 4 +++- lidar_pipeline/dtm.py | 13 ++++++++++--- lidar_pipeline/index.py | 7 +++---- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/lidar_pipeline/cli.py b/lidar_pipeline/cli.py index 5c91792..ed934cd 100644 --- a/lidar_pipeline/cli.py +++ b/lidar_pipeline/cli.py @@ -396,8 +396,10 @@ def main(): def _kill_orphan_pdal(signum=None, frame=None): """Kill orphan PDAL processes on interrupt or exit.""" import subprocess + # Belt-and-suspenders: os.killpg below is the primary mechanism. + # This handles the edge case where a child escapes the process group. try: - subprocess.run(["pkill", "-9", "-f", "pdal"], capture_output=True, timeout=3) + subprocess.run(["pkill", "-9", "-f", "pdal pipeline"], capture_output=True, timeout=3) except Exception: pass if signum is not None: diff --git a/lidar_pipeline/dtm.py b/lidar_pipeline/dtm.py index e0f4a74..eb8f4be 100644 --- a/lidar_pipeline/dtm.py +++ b/lidar_pipeline/dtm.py @@ -31,6 +31,15 @@ IGN_CLASS_NAMES = { } +def _strip_lidar_ext(path): + """Extract base name from a LAZ/LAS file (mirrors pipeline._file_basename).""" + name = Path(path).name + for ext in ('.copc.laz', '.copc.las', '.laz', '.las'): + if name.lower().endswith(ext): + return name[:-len(ext)] + return Path(path).stem + + def parse_ign_classes(spec): """Convertit une liste de classes IGN (noms ou codes) en codes LAS triés. @@ -462,9 +471,7 @@ def classify_ground(laz_file, temp_dir, method='auto', force=False, ign_classes= ign_codes = parse_ign_classes(ign_classes) if method == 'ign' else None method_label = ign_method_label(ign_codes) if ign_codes else method - # Use shared basename extraction function - from .pipeline import _file_basename - laz_base = _file_basename(laz_file) + laz_base = _strip_lidar_ext(laz_file) output_las = temp_dir / f"{laz_base}_ground_{method_label}.las" diff --git a/lidar_pipeline/index.py b/lidar_pipeline/index.py index d5d4e9d..7c61c1b 100644 --- a/lidar_pipeline/index.py +++ b/lidar_pipeline/index.py @@ -161,10 +161,9 @@ def _strip_res_suffix(dirname): def _res_suffix_str(resolution): - """Suffixe de nommage d'une résolution (miroir de pipeline._res_suffix).""" - if resolution == 0.5: - return '' - return '_r' + f'{resolution}'.replace('.', 'p') + """Suffixe de nommage d'une résolution (délègue à pipeline._res_suffix).""" + from .pipeline import LidarArchaeoPipeline + return LidarArchaeoPipeline._res_suffix(resolution) def scan_tiles(vis_dir):