fixed calibration data not loading due to path

This commit is contained in:
ykcheungab
2026-09-20 11:00:33 +08:00
parent 14fbfec62e
commit 1cf78c9d71
5 changed files with 448 additions and 25 deletions
+77 -1
View File
@@ -243,8 +243,84 @@ def test_missing_cal_path_raises():
def test_parse_shipped_box_file_directly():
cal = parse(json.loads(_box_cal_path().read_text(encoding="utf-8")), source_path=_box_cal_path())
assert cal.schema_version == 1
assert cal.schema_version == 2
assert cal.convert(10000.0, 36000.0, -36000.0) == pytest.approx((0.377, 1.19, -1.19))
# The shipped file names both shear axes outright: no shared block, no clone.
assert set(cal.channels) == {"fn", "fx", "fy"}
fx, fy = cal.get("FX"), cal.get("FY")
assert fx is not None and fy is not None and fx is not fy
for curve in (fx, fy):
assert curve.signed is True
assert curve.extrapolate is True
assert curve.clamp_output_min == pytest.approx(0.0)
assert len(curve.points) == 3
assert fx.raw_key == "fshearx"
assert fy.raw_key == "fsheary"
def test_the_shipped_box_shear_axes_can_drift_apart(tmp_path: Path):
"""The whole point of the split: FX and FY are independent curves.
A document with the same shape as the shipped one but different per-axis
points must apply each axis's own curve. Re-collapsing the axes into one
shared ``shear`` block makes this fail.
"""
doc = {
"schema_version": 2,
"unit": "N",
"channels": {
"normal": {
"method": "piecewise_linear",
"points": [[0.0, 0.0], [1000.0, 1.0]],
},
"shear_x": {
"method": "piecewise_linear",
"signed": True,
"input": "components",
"extrapolate": True,
"clamp_output_min": 0.0,
"points": [[0.0, 0.0], [500.0, 2.0]],
},
"shear_y": {
"method": "piecewise_linear",
"signed": True,
"input": "components",
"extrapolate": True,
"clamp_output_min": 0.0,
"points": [[0.0, 0.0], [500.0, 3.0]],
},
},
}
path = tmp_path / "split.json"
path.write_text(json.dumps(doc), encoding="utf-8")
cal = load(path)
assert cal is not None
assert cal.convert(0.0, 500.0, 500.0)[1:] == pytest.approx((2.0, 3.0))
assert cal.convert(0.0, -500.0, 500.0)[1:] == pytest.approx((-2.0, 3.0))
def test_out_of_range_readings_extend_instead_of_being_dropped():
"""Outside the calibrated range the nearest segment is extended.
This pins the "extend, never ignore, never reuse a previous coefficient"
behaviour of the shipped box file, so flipping ``extrapolate`` has to be a
deliberate edit that fails this test first.
"""
cal = load(sensor_type="box")
assert cal is not None
fx, fy, fn = cal.get("FX"), cal.get("FY"), cal.get("FN")
assert fx is not None and fy is not None and fn is not None
# 136000 = 2 x the top raw break (68000 -> 2.06): the last segment's slope is
# applied again, so the value keeps growing past the calibrated range.
(r0, n0), (r1, n1) = fx.points[-2], fx.points[-1]
extended = n1 + (n1 - n0) / (r1 - r0) * (136000.0 - r1)
assert extended > n1
assert fx.convert_component(136000.0) == pytest.approx(extended)
assert fy.convert_component(136000.0) == pytest.approx(extended)
# A negative beyond the range keeps its sign.
assert fx.convert_component(-136000.0) == pytest.approx(-extended)
# Below the first point the normal channel floors at clamp_output_min.
assert fn.convert(500.0) == pytest.approx(0.0)
# ------------------------------------------------------- filter fingerprint