"""여러 주행 타일 (nusim.recon.tile) — 자르기·색 맞춤·카메라 번호, CPU.""" from dataclasses import dataclass, field import numpy as np import pytest from nusim.recon.tile import crop_scene, fit_color @dataclass class _F: timestamp: int ego_translation: list @dataclass class _S: frames: dict lidar: list = field(default_factory=list) def _scene(xs): fr = [_F(i * 100_000, [x, 0.0, 0.0]) for i, x in enumerate(xs)] return _S(frames={"CAM_FRONT": fr}, lidar=list(fr)) def test_crop_scene_keeps_time_span_inside_tile(): s = _scene([-100, -50, -30, 0, 30, 50, 100]) c = crop_scene(s, np.array([0.0, 0.0]), 40) xs = [f.ego_translation[0] for f in c.frames["CAM_FRONT"]] assert xs == [-30, 0, 30] and len(c.lidar) == 3 def test_crop_scene_none_when_outside(): assert crop_scene(_scene([100, 200]), np.array([0.0, 0.0]), 40) is None def test_fit_color_recovers_affine_and_ignores_masked(): rng = np.random.default_rng(0) pred = rng.random((20, 30, 3)).astype(np.float32) * 0.5 + 0.2 A = np.array([[0.9, 0.05, 0], [0, 1.1, 0], [0.02, 0, 0.8]], np.float32) gt = np.clip(pred @ A.T + 0.03, 0, 1) keep = np.ones((20, 30), bool) keep[:5] = False gt_bad = gt.copy() gt_bad[:5] = 1.0 # 가린 영역은 맞춤에 안 들어가야 한다 out = fit_color(pred, gt_bad, keep) assert np.allclose(out[keep], gt[keep], atol=1e-4) def test_trainer_names_tile_cameras(): torch = pytest.importorskip("torch") from nusim.recon.train import CameraAdjust adj = CameraAdjust(12) with torch.no_grad(): adj.delta[7, 3] = 0.1 js = adj.to_json() assert "CAM_FRONT" in js and "CAM_FRONT#1" in js and len(js) == 12 assert js["CAM_FRONT#1"]["translation_m"] == pytest.approx(0.1)