Peano
Loading...
Searching...
No Matches
test_binary_patch_file.py
Go to the documentation of this file.
1import numpy as np
2import pytest
3
4from tarch.plotter.api.input.PatchFileParser import PatchFileParser
5
6
7# ---------------------------------------------------------------------------
8# Writes files like PeanoBinaryPatchFileWriter and PeanoTextPatchFileWriter do.
9# The quantities of the binary file are raw doubles between the "begin ...-values"
10# and "end ...-values" line.
11# ---------------------------------------------------------------------------
12
13DOF = 2
14UNKNOWNS = 3
15DIMENSIONS = 2
16
17# Raw bytes which look like a line break and like the end of a patch. A parser
18# which reads the quantities line by line trips over them.
19EVIL = np.frombuffer(b"\nend pat\n", dtype=np.uint8)[:8].tobytes()
20
21
22def values_of_patch(patch_id, name_offset=0.0, evil=False):
23 result = np.array(
24 [
25 100 * patch_id + 10 * k + u + name_offset
26 for k in range(DOF**DIMENSIONS)
27 for u in range(UNKNOWNS)
28 ]
29 )
30 if evil:
31 # first entry replaced by the bytes in EVIL, as write_file() does
32 result[0] = np.frombuffer(EVIL, dtype=np.float64)[0]
33 return result
34
35
36def write_file(path, binary, patches=2, datasets=("Q",), evil=False):
37 header = ["# ", "# Peano patch file ", "# Version 0.2 ", "# "]
38 header += ["format Binary" if binary else "format ASCII"]
39 header += [f"dimensions {DIMENSIONS}", "", ""]
40 out = ("\n".join(header) + "\n").encode()
41
42 for name in datasets:
43 out += (
44 f'begin cell-metadata "{name}"\n'
45 f" number-of-unknowns {UNKNOWNS}\n"
46 f" number-of-dofs-per-axis {DOF}\n"
47 f" description {name}\n"
48 f"end cell-metadata\n\n"
49 ).encode()
50
51 for patch_id in range(patches):
52 out += (
53 f"begin patch\n offset {0.5 * patch_id} 0.0\n size 0.5 0.5\n"
54 ).encode()
55 for index, name in enumerate(datasets):
56 values = values_of_patch(patch_id, 1000.0 * index)
57 out += f' begin cell-values "{name}"\n'.encode()
58 if binary:
59 raw = values.astype(np.float64).tobytes()
60 if evil:
61 raw = EVIL + raw[8:]
62 out += raw + b"\n"
63 else:
64 out += (" " + " ".join(repr(v) for v in values) + "\n").encode()
65 out += b" end cell-values\n"
66 out += b"end patch\n\n"
67 path.write_bytes(out)
68
69
70def parse(path, identifier="Q", patch_filter=None):
71 parser = PatchFileParser(str(path), identifier, 0, patch_filter=patch_filter)
72 parser.parse_file()
73 assert parser.parsed
74 return parser
75
76
77# ---------------------------------------------------------------------------
78
79
80@pytest.mark.parametrize("binary", [False, True])
82 write_file(tmp_path / "f.peano-patch-file", binary)
83 parser = parse(tmp_path / "f.peano-patch-file")
84
85 assert parser.file_format == ("Binary" if binary else "ASCII")
86 patches = parser.unknown_attributes["Q"].cell_data
87 assert len(patches) == 2
88 for patch_id, patch in enumerate(patches):
89 assert patch.offset == (0.5 * patch_id, 0.0)
90 assert np.array_equal(patch.values, values_of_patch(patch_id))
91
92
94 write_file(tmp_path / "f.peano-patch-file", True, evil=True)
95 parser = parse(tmp_path / "f.peano-patch-file")
96
97 patches = parser.unknown_attributes["Q"].cell_data
98 assert len(patches) == 2
99 assert patches[0].values.tobytes()[:8] == EVIL
100 assert patches[1].values.tobytes() == values_of_patch(1, evil=True).tobytes()
101
102
103@pytest.mark.parametrize("binary", [False, True])
105 write_file(
106 tmp_path / "f.peano-patch-file",
107 binary,
108 datasets=("A", "B", "C"),
109 evil=binary,
110 )
111 parser = parse(tmp_path / "f.peano-patch-file", identifier="B")
112
113 assert list(parser.unknown_attributes.keys()) == ["B"]
114 patches = parser.unknown_attributes["B"].cell_data
115 assert len(patches) == 2
116 assert (
117 patches[1].values.tobytes()
118 == values_of_patch(1, 1000.0, evil=binary).tobytes()
119 )
120
121
122@pytest.mark.parametrize("binary", [False, True])
124 write_file(tmp_path / "f.peano-patch-file", binary, patches=3, evil=binary)
125 parser = parse(
126 tmp_path / "f.peano-patch-file",
127 patch_filter=lambda offset, size: offset[0] >= 1.0,
128 )
129
130 patches = parser.unknown_attributes["Q"].cell_data
131 assert len(patches) == 1
132 assert patches[0].values.tobytes() == values_of_patch(2, evil=binary).tobytes()
parse(path, identifier="Q", patch_filter=None)
test_binary_quantities_may_hold_any_bytes(tmp_path)
test_other_datasets_are_stepped_over(tmp_path, binary)
test_text_and_binary_files_yield_the_same_patches(tmp_path, binary)
test_patch_filter_skips_patches(tmp_path, binary)