pnm 1.0.3
peclet.pnm — pore-network extraction from SDF geometry (Kokkos)
Loading...
Searching...
No Matches
test_packing_ring.py
Go to the documentation of this file.
1"""The 7199-pore release gate on the suite's ring packing (flow/data/packing_ring.vti, 256^3).
2
3Run: PYTHONPATH=<pnm build dir> python tests/python/test_packing_ring.py <packing_ring.vti>
4(registered as the `pnm_python_packing_ring` ctest under PECLET_PNM_BUILD_TESTS).
5
6The data file lives in the suite (../flow/data), not in this repo, so a standalone checkout (CI)
7cannot run it: the test then exits 77 = ctest SKIP_RETURN_CODE and is reported as *skipped*,
8never as passed. The contract (measured, deterministic — the distributed path is bit-exact to
9this): 7199 pores, 53020 connections, and the fused pipeline agrees with the staged one.
10"""
11
12import os
13import sys
14
15import numpy as np
16
17EXPECTED_PORES = 7199
18EXPECTED_CONNECTIONS = 53020
19SKIP = 77
20
21
22def main(path):
23 if not os.path.isfile(path):
24 print(f"SKIP: {path} not present (suite data file, not shipped with the repo)")
25 return SKIP
26 import peclet.pnm as pnm
27
28 print("peclet.pnm on", pnm.execution_space)
29 sdf, origin_zyx, spacing_zyx = pnm.SDFReader.read_vti(path)
30 assert sdf.shape == (256, 256, 256) and sdf.dtype == np.float32, (sdf.shape, sdf.dtype)
31 pores = pnm.extract_pores(sdf, origin_zyx, spacing_zyx)
32 print(f"extract_pores: {len(pores)} pores")
33 assert len(pores) == EXPECTED_PORES, len(pores)
34 fused, seg, conns = pnm.extract_pore_network(sdf, origin_zyx, spacing_zyx)
35 assert seg.shape == sdf.shape and seg.dtype == np.int32, (seg.shape, seg.dtype)
36 assert conns.shape[1:] == (2,) and conns.dtype == np.int32, (conns.shape, conns.dtype)
37 print(f"extract_pore_network: {len(fused)} pores, {len(conns)} connections, "
38 f"{seg.max()} pore labels, {-seg.min()} solid labels")
39 assert len(fused) == EXPECTED_PORES, len(fused)
40 assert len(conns) == EXPECTED_CONNECTIONS, len(conns)
41 assert seg.max() == EXPECTED_PORES, seg.max()
42 # the pore set is identical between the staged and the fused path
43 key = lambda p: (p.x, p.y, p.z, p.radius) # noqa: E731
44 assert sorted(map(key, pores)) == sorted(map(key, fused))
45 print("packing_ring ok")
46 return 0
47
48
49if __name__ == "__main__":
50 if len(sys.argv) != 2:
51 print(f"usage: {sys.argv[0]} <packing_ring.vti>")
52 sys.exit(2)
53 sys.exit(main(sys.argv[1]))