File indexing completed on 2026-10-27 08:41:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 import json
0011 import os
0012
0013 import pytest
0014 import uproot
0015
0016 jsonschema = pytest.importorskip("jsonschema")
0017
0018
0019 REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
0020 SCHEMA_FILE = os.path.join(REPO_ROOT, "dex-schema", "firebird-dex-v1.schema.json")
0021
0022 TEST_EDM4EIC_FILE = os.path.join(os.path.dirname(__file__), 'data', 'reco_2024-09_craterlake_2evt.edm4eic.root')
0023 TEST_EDM4HEP_FILE = os.path.join(os.path.dirname(__file__), 'data', 'k_lambda_10x100_2evt.edm4hep.root')
0024
0025 pytestmark = pytest.mark.skipif(
0026 not os.path.isfile(SCHEMA_FILE),
0027 reason="dex-schema/ not present (running outside the monorepo checkout)")
0028
0029
0030 @pytest.fixture(scope="module")
0031 def validator():
0032 with open(SCHEMA_FILE) as f:
0033 schema = json.load(f)
0034
0035
0036 jsonschema.Draft202012Validator.check_schema(schema)
0037 return jsonschema.Draft202012Validator(schema)
0038
0039
0040 def assert_valid(validator, document, what):
0041 errors = sorted(validator.iter_errors(document), key=lambda e: e.json_path)
0042 assert not errors, f"{what} violates the DEX schema:\n" + "\n".join(
0043 f" {error.json_path}: {error.message}" for error in errors[:10])
0044
0045
0046 def test_schema_accepts_edm4eic_converter_output(validator):
0047 from pyrobird.edm4eic import edm4eic_to_dex_dict
0048 tree = uproot.open(TEST_EDM4EIC_FILE)['events']
0049 document = edm4eic_to_dex_dict(tree, [0, 1], origin_info={'file': 'test'})
0050 assert_valid(validator, document, "edm4eic converter output")
0051
0052
0053 def test_schema_accepts_edm4hep_converter_output(validator):
0054 from pyrobird.edm4hep import edm4hep_to_dex_dict
0055 tree = uproot.open(TEST_EDM4HEP_FILE)['events']
0056 document = edm4hep_to_dex_dict(tree, [0, 1], origin_info={'file': 'test'})
0057 assert_valid(validator, document, "edm4hep converter output")
0058
0059
0060 def test_schema_accepts_upgraded_004(validator):
0061 from pyrobird.dex import upgrade_dex
0062 old_document = {
0063 "type": "firebird-dex-json",
0064 "version": "0.04",
0065 "events": [{
0066 "id": "event_0",
0067 "groups": [
0068 {
0069 "name": "Hits", "type": "BoxHit",
0070 "hits": [{"pos": [1, 2, 3], "dim": [1, 1, 1], "t": [4, 0], "ed": [0.001, 0]}],
0071 },
0072 {
0073 "name": "Tracks", "type": "PointTrajectory",
0074 "paramColumns": ["theta"], "pointColumns": ["x", "y", "z", "t"],
0075 "trajectories": [{"points": [[0, 0, 0, 0], [1, 1, 1, 1]], "params": [0.5]}],
0076 },
0077 ],
0078 }],
0079 }
0080 assert_valid(validator, upgrade_dex(old_document), "upgrade_dex output")
0081
0082
0083 @pytest.mark.parametrize("relative_path", [
0084 "firebird-ng/src/assets/data/example-cherenkov.firebird.json",
0085 "dd4hep-plugin/test.edm4eic.firebird.json",
0086 ])
0087 def test_schema_accepts_repo_samples(validator, relative_path):
0088 sample_file = os.path.join(REPO_ROOT, relative_path)
0089 if not os.path.isfile(sample_file):
0090 pytest.skip(f"{relative_path} not present")
0091 with open(sample_file) as f:
0092 assert_valid(validator, json.load(f), relative_path)
0093
0094
0095 def test_schema_rejects_malformed_documents(validator):
0096
0097 assert not validator.is_valid({"type": "firebird-dex-json", "version": "0.04", "events": []})
0098
0099 assert not validator.is_valid({
0100 "type": "firebird-dex-json", "version": "1.0",
0101 "events": [{"id": 0, "pieces": [{"name": "X", "type": "BoxHit", "version": "1.0"}]}],
0102 })
0103
0104 assert not validator.is_valid({
0105 "type": "firebird-dex-json", "version": "1.0",
0106 "events": [{"id": 0, "pieces": [{
0107 "name": "X", "type": "BoxHit", "version": "1.0",
0108 "count": 0, "columns": {},
0109 }]}],
0110 })
0111
0112 assert not validator.is_valid({
0113 "type": "firebird-dex-json", "version": "1.0",
0114 "events": [{"id": 0, "pieces": [{
0115 "name": "X", "type": "PointTrajectory", "version": "1.0",
0116 "count": 0, "columns": {},
0117 }]}],
0118 })