Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-16 08:46:35

0001 #!/usr/bin/env python3
0002 """Offline schema/fixture QA, not a production material reader.
0003 
0004 Requires jsonschema>=4.18. Run from any directory. No network references are used.
0005 Direct execution validates the schema and examples. Run the self-tests with
0006 ``python -m pytest CI/check_material_schema.py`` (also requires pytest).
0007 """
0008 
0009 import copy
0010 import json
0011 from pathlib import Path
0012 
0013 from jsonschema import Draft202012Validator
0014 
0015 ROOT = Path(__file__).resolve().parents[1]
0016 SCHEMA = ROOT / "Plugins/Json/schema/material-map-v1.schema.json"
0017 EXAMPLES = ROOT / "docs/examples/material-map-v1"
0018 ID_COMPONENTS = ("volume", "portal", "layer", "passive", "sensitive", "extra")
0019 
0020 
0021 def load(path):
0022     return json.loads(path.read_text())
0023 
0024 
0025 def changed(document, path, value):
0026     result = copy.deepcopy(document)
0027     cursor = result
0028     for key in path[:-1]:
0029         cursor = cursor[key]
0030     cursor[path[-1]] = value
0031     return result
0032 
0033 
0034 def validation_inputs():
0035     schema = load(SCHEMA)
0036     Draft202012Validator.check_schema(schema)
0037     validator = Draft202012Validator(schema)
0038     examples = {p.stem: load(p) for p in sorted(EXAMPLES.glob("*.json"))}
0039     return validator, examples
0040 
0041 
0042 def main():
0043     validator, examples = validation_inputs()
0044     for name, document in examples.items():
0045         validator.validate(document)
0046         print(f"Validated {name}.json (schema)")
0047 
0048 
0049 def test_schema_and_examples():
0050     main()
0051 
0052 
0053 def test_valid_geometry_ids():
0054     validator, examples = validation_inputs()
0055     m = examples["minimal"]
0056     # All-zero, omitted-zero and full-width component IDs are valid objects.
0057     maxima = dict(zip(ID_COMPONENTS, (255, 255, 4095, 255, 1048575, 255)))
0058     for identifier in ({}, {"volume": 0}, maxima):
0059         document = changed(m, ["surfaces", 0, "target", "geometry_id"], identifier)
0060         validator.validate(document)
0061 
0062 
0063 def test_invalid_structures():
0064     validator, examples = validation_inputs()
0065     m, s = (examples[n] for n in ("minimal", "surfaces"))
0066     maxima = dict(zip(ID_COMPONENTS, (255, 255, 4095, 255, 1048575, 255)))
0067     structural = [
0068         changed(m, ["header", "version"], 2),
0069         changed(m, ["header", "units"], {}),
0070         changed(m, ["header", "units", "length"], "GeV"),
0071         changed(m, ["header", "units", "material_amount"], "mol/mm^3"),
0072         changed(m, ["header"], {}),
0073         changed(m, ["header"], None),
0074         changed(m, ["header", "description"], 42),
0075         changed(m, ["description"], "misplaced"),
0076         changed(m, ["surfaces", 0, "target", "geometry_id"], 72057594037927936),
0077         changed(m, ["surfaces", 0, "target", "geometry_id"], "72057594037927936"),
0078         changed(m, ["surfaces", 0, "target", "geometry_id"], {"volume": -1}),
0079         changed(m, ["surfaces", 0, "target", "geometry_id"], {"volume": 1.5}),
0080         changed(m, ["surfaces", 0, "target", "geometry_id"], {"approach": 1}),
0081         changed(m, ["surfaces", 0, "target", "geometry_id"], {"boundary": 1}),
0082         changed(m, ["surfaces", 0, "material", "kind"], "unknown"),
0083         changed(m, ["surfaces", 0, "material", "slab", "thickness"], -1),
0084         changed(
0085             s,
0086             ["surfaces", 3, "material", "axes"],
0087             [{"kind": "equidistant", "bins": 2}] * 2,
0088         ),
0089         changed(s, ["surfaces", 5, "material"], None),
0090         changed(m, ["volumes"], []),
0091         changed(m, ["volumes"], [{"geometry_id": {"volume": 1}, "material": None}]),
0092         changed(m, ["typo"], True),
0093     ]
0094     for name, maximum in maxima.items():
0095         structural.append(
0096             changed(m, ["surfaces", 0, "target", "geometry_id"], {name: maximum + 1})
0097         )
0098     for document in structural:
0099         assert not validator.is_valid(document), document
0100 
0101 
0102 def test_unit_symbols():
0103     validator, examples = validation_inputs()
0104     for dimension, definition in validator.schema["properties"]["header"]["properties"][
0105         "units"
0106     ]["properties"].items():
0107         for symbol in definition["enum"]:
0108             validator.validate(
0109                 changed(examples["minimal"], ["header", "units", dimension], symbol)
0110             )
0111 
0112 
0113 if __name__ == "__main__":
0114     main()