"""Feature identities use effective measurement settings, never display metadata.""" from copy import deepcopy import json import numpy as np import pytest from orisys.calibration_context import build_context, domain_fingerprint def config(): return {"camera": {"resolution_raw": [1280, 720], "resolution_stitch": [700, 750]}, "tracker": {"dis_mode": 4}} @pytest.mark.parametrize("raw,expected", [(None, 1), ("bad", 1), (0, 1), (-3, 1), ("3", 3), (3.7, 3)]) def test_hhd_uses_actual_sensor_normalization(raw, expected): data = config() data["tracker"]["hhd_downsample"] = raw assert build_context(data)["hhd_downsample"] == expected def test_default_values_equal_explicit_effective_settings(): implicit = build_context(config()) data = config() data["tracker"]["hhd_downsample"] = 1 explicit = build_context(data, {"flow_ema_alpha": 1.0}) assert implicit["hhd_downsample"] == 1 assert implicit["filters"]["measurement"] == {"flow_ema_alpha": 1.0} assert implicit["feature_signature_sha256"] == explicit["feature_signature_sha256"] def test_measurement_filters_change_identity_but_readout_and_paths_do_not(): data = config() original = build_context(data) assert build_context(data, {"flow_ema_alpha": 0.5})["feature_signature_sha256"] != original["feature_signature_sha256"] data.update(name="other", video="D:/other.mp4", cal_path="E:/calibration.json") assert build_context(data, {"force_median_window": 7, "force_lowpass_cutoff_hz": 2}) == original def test_explicit_empty_filter_mapping_overrides_config_defaults(): data = config() data["filters"] = {"flow_ema_alpha": 0.5} assert build_context(data, {})["filters"]["measurement"] == {"flow_ema_alpha": 1.0} def test_source_scale_numeric_types_have_identical_identity(): assert build_context(config(), source_scale=1) == build_context(config(), source_scale=1.0) def test_domain_fingerprint_binds_map_content_not_only_dimensions(): domain = {"map_x": np.zeros((2, 3)), "map_y": np.zeros((2, 3)), "valid_mask": np.ones((2, 3), dtype=bool), "world_xyz": np.zeros((2, 3, 3))} original = domain_fingerprint(domain) for key in domain: changed = deepcopy(domain) changed[key].flat[0] = not changed[key].flat[0] if key == "valid_mask" else 1 assert domain_fingerprint(changed) != original assert domain_fingerprint({key: value.copy() for key, value in domain.items()}) == original def _model(data): from orisys.calibration import parse return parse({ "schema_version": 3, "unit": "N", "identity": {"sensor_type": "box", "sn": "A1"}, "pipeline": build_context(data), "model": { "type": "global_gain/1", "input_profile": "force_delta/1", "output_frame": "sdk_force/1", "outputs": ["fn"], "params": {"gains_N_per_raw": {"fn": .001}, "valid_force_range_N": [0, 3]}, }, }) @pytest.mark.parametrize("downsample", [1, 2, 4]) def test_downsample_only_difference_accepts_existing_model_without_rewriting_it(downsample): from orisys.calibration import validate_for_device data = config() data["tracker"]["hhd_downsample"] = 3 model = _model(data) original = model.to_dict() fingerprint = model.fingerprint data["tracker"]["hhd_downsample"] = downsample actual = build_context(data) assert json.loads(json.dumps(actual)) == actual assert actual["feature_signature_sha256"] != model.pipeline["feature_signature_sha256"] validate_for_device(model, "box", "A1", pipeline=actual) model.validate_for_context(actual) assert model.to_dict() == original assert model.fingerprint == fingerprint assert actual["hhd_downsample"] == downsample def test_runtime_context_binds_a_different_downsample_model_and_predicts(): from orisys.force_readout import ForceReadout from orisys.sensor import Sensor data = config() data["tracker"]["hhd_downsample"] = 3 sensor = Sensor.__new__(Sensor) sensor._config = data sensor.calibration = _model(data) sensor._force_raw = (100.0, 0.0, 0.0) sensor._force_readout = ForceReadout({}) sensor._model_readouts = {} sensor._reset_calibration_session() data["tracker"]["hhd_downsample"] = 2 sensor.bind_calibration_context(build_context(data)) sensor.set_calibration_reference({"fn": 100.0}, reference_id="unloaded") result = sensor.apply_calibration_frame( frame_id=1, timestamp_s=0.1, raw=(120.0, 0.0, 0.0), contact_found=True, ) assert result.values_N["fn"] == pytest.approx(.02) @pytest.mark.parametrize("section,key,value", [ ("camera", "resolution_raw", [640, 480]), ("tracker", "dis_mode", 1), ("tracker", "flow_iterations", 99), ("contact", "threshold", .9), ("filters", "flow_ema_alpha", .5), ]) def test_downsample_tolerance_does_not_hide_other_pipeline_changes(section, key, value): data = config() data["tracker"]["hhd_downsample"] = 3 model = _model(data) data["tracker"]["hhd_downsample"] = 2 data.setdefault(section, {})[key] = value with pytest.raises(ValueError, match="pipeline mismatch"): model.validate_for_context(build_context(data))