Add MITC4 drilling diagnostics output and comparison contract
This commit is contained in:
@@ -349,3 +349,88 @@ def test_cli_writes_json_and_exit_two_for_missing_results(tmp_path, artifacts):
|
||||
evidence = json.loads(report.read_text())
|
||||
assert not evidence["precheck"]["passed"]
|
||||
assert evidence["families"] == []
|
||||
|
||||
|
||||
DRILLING_MODES = ("direct-initial-director-spring", "legacy-corotated-twist")
|
||||
|
||||
|
||||
def drilling_result(tmp_path, artifacts, mode=DRILLING_MODES[0]):
|
||||
path = changed_result(tmp_path, artifacts)
|
||||
with h5py.File(path, "r+") as file:
|
||||
file["metadata"].attrs["mitc4_drilling_formulation"] = mode
|
||||
file["metadata"].attrs["drilling_diagnostics_version"] = np.uint64(1)
|
||||
for frame in range(101):
|
||||
root = file.require_group(f"steps/Step-1/frames/{frame}/global")
|
||||
raw = np.array([1., 2., 3., 4., 5., 6.], dtype="<f8")
|
||||
moment = np.array([4., 5., 6.], dtype="<f8")
|
||||
corrected = raw.copy()
|
||||
corrected[3:] -= moment
|
||||
root.create_dataset("equilibrium", data=raw)
|
||||
root.create_dataset("drilling_moment", data=moment)
|
||||
root.create_dataset("equilibrium_with_drilling", data=corrected)
|
||||
return path
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode", DRILLING_MODES)
|
||||
def test_drilling_diagnostics_are_precheck_and_report_all_frames(tmp_path, artifacts, mode):
|
||||
result = comparator.compare(artifacts[0], artifacts[1], drilling_result(tmp_path, artifacts, mode))
|
||||
assert result["precheck"]["passed"], result["precheck"]
|
||||
assert result["verdict"] == "passed"
|
||||
assert len(result["families"]) == 202
|
||||
diagnostics = result["drilling_diagnostics"]
|
||||
assert diagnostics["formulation"] == mode
|
||||
assert diagnostics["version"] == 1
|
||||
assert [frame["frame_index"] for frame in diagnostics["frames"]] == list(range(101))
|
||||
assert diagnostics["frames"][0] == {
|
||||
"storage_step": "Step-1", "frame_index": 0,
|
||||
"raw_equilibrium": [1., 2., 3., 4., 5., 6.],
|
||||
"drilling_moment": [4., 5., 6.],
|
||||
"equilibrium_with_drilling": [1., 2., 3., 0., 0., 0.]}
|
||||
|
||||
|
||||
def test_markerless_drilling_report_is_null(artifacts):
|
||||
assert comparator.compare(*artifacts)["drilling_diagnostics"] is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mutation", ["mode_missing", "version_missing", "unknown_mode", "unknown_version",
|
||||
"version_type", "mode_type", "initial_missing", "intermediate_missing", "both_missing",
|
||||
"wrong_shape", "wrong_type", "big_endian", "nan", "inf", "wrong_algebra", "wrong_force"])
|
||||
def test_drilling_diagnostics_rejected_before_displacement_tolerance(tmp_path, artifacts, mutation):
|
||||
path = drilling_result(tmp_path, artifacts)
|
||||
with h5py.File(path, "r+") as file:
|
||||
metadata = file["metadata"]
|
||||
root = file["steps/Step-1/frames/50/global"]
|
||||
if mutation == "mode_missing":
|
||||
del metadata.attrs["mitc4_drilling_formulation"]
|
||||
elif mutation == "version_missing":
|
||||
del metadata.attrs["drilling_diagnostics_version"]
|
||||
elif mutation == "unknown_mode":
|
||||
metadata.attrs["mitc4_drilling_formulation"] = "unknown"
|
||||
elif mutation == "unknown_version":
|
||||
metadata.attrs["drilling_diagnostics_version"] = np.uint64(2)
|
||||
elif mutation == "version_type":
|
||||
del metadata.attrs["drilling_diagnostics_version"]
|
||||
metadata.attrs["drilling_diagnostics_version"] = np.uint32(1)
|
||||
elif mutation == "mode_type":
|
||||
del metadata.attrs["mitc4_drilling_formulation"]
|
||||
metadata.attrs["mitc4_drilling_formulation"] = np.bytes_(DRILLING_MODES[0])
|
||||
elif mutation == "initial_missing":
|
||||
del file["steps/Step-1/frames/0/global/drilling_moment"]
|
||||
elif mutation == "intermediate_missing":
|
||||
del root["equilibrium_with_drilling"]
|
||||
elif mutation == "both_missing":
|
||||
del root["drilling_moment"]
|
||||
del root["equilibrium_with_drilling"]
|
||||
elif mutation in {"wrong_shape", "wrong_type", "big_endian"}:
|
||||
del root["drilling_moment"]
|
||||
root.create_dataset("drilling_moment", data=np.zeros(2 if mutation == "wrong_shape" else 3,
|
||||
dtype=">f8" if mutation == "big_endian" else ("<f4" if mutation == "wrong_type" else "<f8")))
|
||||
elif mutation == "nan":
|
||||
root["drilling_moment"][0] = np.nan
|
||||
elif mutation == "inf":
|
||||
root["equilibrium"][0] = np.inf
|
||||
else:
|
||||
root["equilibrium_with_drilling"][0 if mutation == "wrong_force" else 3] = 1e-100
|
||||
result = comparator.compare(artifacts[0], artifacts[1], path)
|
||||
assert not result["precheck"]["passed"]
|
||||
assert result["families"] == []
|
||||
|
||||
Reference in New Issue
Block a user