Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • roboct-public/roboct-schemas
1 result
Show changes
Commits on Source (2)
Showing
with 92 additions and 71 deletions
...@@ -55,15 +55,25 @@ Python example to validate a projection file: ...@@ -55,15 +55,25 @@ Python example to validate a projection file:
```python:../scripts/validate_file.py ```python:../scripts/validate_file.py
from thd_json.projection import get_projection_validator from thd_json.projection import get_projection_validator
from thd_json.header import get_header_validator
from thd_json.source import get_source_validator
from pathlib import Path from pathlib import Path
FILE = Path("./examples/generated/example_projection.json") FILE_H = Path("./examples/generated/example_header.json")
FILE_P = Path("./examples/generated/example_projection.json")
FILE_S = Path("./examples/generated/example_source.json")
def main(): def main():
source_validator = get_source_validator()
source_validator.file(FILE_S)
projection_validator = get_projection_validator() projection_validator = get_projection_validator()
projection_validator.file(FILE) projection_validator.file(FILE_P)
header_validator = get_header_validator()
header_validator.file(FILE_H)
if __name__ == "__main__": if __name__ == "__main__":
......
{ {
"uuid": "" "uuid": "0060361f-056d-11f0-b60b-f46d3febaf36"
} }
\ No newline at end of file
...@@ -24,13 +24,19 @@ ...@@ -24,13 +24,19 @@
"y": 0.0, "y": 0.0,
"z": 0.0 "z": 0.0
}, },
"focal_spot_orientation_quat": {
"w": 0.0,
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"focal_spot_position_mm": { "focal_spot_position_mm": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 0.0 "z": 0.0
}, },
"header": { "header": {
"uuid": "" "uuid": "005f11bd-056d-11f0-b60b-f46d3febaf36"
} }
} }
} }
\ No newline at end of file
{ {
"header": { "header": {
"uuid": "" "uuid": "00670fe0-056d-11f0-b60b-f46d3febaf36"
}, },
"roi_center_position_mm": [ "roi_center_position_mm": [
0.0, 0.0,
......
[project] [project]
name = "thd-json" name = "thd-json"
version = "0.1.10" version = "0.1.11"
description = "THD JSON schema and validation tools." description = "THD JSON schema and validation tools."
authors = [ authors = [
{ name = "swittl", email = "simon.wittl@th-deg.de" } { name = "swittl", email = "simon.wittl@th-deg.de" }
...@@ -14,6 +14,7 @@ dependencies = [ ...@@ -14,6 +14,7 @@ dependencies = [
"numpy>=2.1.3", "numpy>=2.1.3",
"pillow>=11.0.0", "pillow>=11.0.0",
"hatchling>=1.26.3", "hatchling>=1.26.3",
"jsonref>=1.1.0",
] ]
[project.scripts] [project.scripts]
......
from hypothesis_jsonschema import from_schema from hypothesis_jsonschema import from_schema
from thd_json.projection import get_projection_validator from thd_json.projection import get_projection_validator
from thd_json.header import get_header_validator from thd_json.header import get_header_validator, generate_header
from thd_json.source import get_source_validator from thd_json.source import get_source_validator
from thd_json.detector import get_detector_validator from thd_json.detector import get_detector_validator
from thd_json.roi import get_roi_validator from thd_json.roi import get_roi_validator
...@@ -12,6 +12,16 @@ from pathlib import Path ...@@ -12,6 +12,16 @@ from pathlib import Path
SAVE_FOLDER = Path("./examples/generated") SAVE_FOLDER = Path("./examples/generated")
def set_uuid(src: dict):
for k, v in src.items():
if isinstance(v, dict):
set_uuid(v)
if k == "uuid":
header = generate_header()
src[k] = header.uuid
def main(): def main():
for name, get_validator in [ for name, get_validator in [
("projection", get_projection_validator), ("projection", get_projection_validator),
...@@ -28,6 +38,7 @@ def main(): ...@@ -28,6 +38,7 @@ def main():
@given(strategy) @given(strategy)
def schema(data): def schema(data):
with open(SAVE_FOLDER / f"example_{name}.json", "w") as f: with open(SAVE_FOLDER / f"example_{name}.json", "w") as f:
set_uuid(data)
json.dump(data, f, indent=4) json.dump(data, f, indent=4)
return return
......
from thd_json.projection import get_projection_validator from thd_json.projection import get_projection_validator
from thd_json.header import get_header_validator
from thd_json.source import get_source_validator
from pathlib import Path from pathlib import Path
FILE = Path("./examples/generated/example_projection.json") FILE_H = Path("./examples/generated/example_header.json")
FILE_P = Path("./examples/generated/example_projection.json")
FILE_S = Path("./examples/generated/example_source.json")
def main(): def main():
source_validator = get_source_validator()
source_validator.file(FILE_S)
projection_validator = get_projection_validator() projection_validator = get_projection_validator()
projection_validator.file(FILE) projection_validator.file(FILE_P)
header_validator = get_header_validator()
header_validator.file(FILE_H)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "THD Detector File Schema", "title": "THD Detector File Schema",
"type": "object", "type": "object",
"version": "0.1.9", "version": "0.1.11",
"date": "28.11.2024", "date": "20.03.2025",
"properties": { "properties": {
"pixel_pitch_mm": { "pixel_pitch_mm": {
"type": "object", "type": "object",
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "THD Data Metadata Header File Schema", "title": "THD Data Metadata Header File Schema",
"type": "object", "type": "object",
"version": "0.1.9", "version": "0.1.11",
"date": "28.11.2024", "date": "20.03.2025",
"properties": { "properties": {
"timestamp": { "timestamp": {
"type": "string", "type": "string",
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "THD Projection Image File Schema", "title": "THD Projection Image File Schema",
"type": "object", "type": "object",
"version": "0.1.9", "version": "0.1.11",
"date": "28.11.2024", "date": "20.03.2025",
"properties": { "properties": {
"header": { "header": {
"$ref": "../header/header.json" "$ref": "../header/header.json"
......
...@@ -2,24 +2,23 @@ ...@@ -2,24 +2,23 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "THD Projection File Schema", "title": "THD Projection File Schema",
"type": "object", "type": "object",
"version": "0.1.9", "version": "0.1.11",
"date": "28.11.2024", "date": "20.03.2025",
"properties": { "properties": {
"image": { "image": {
"$ref": "./image/image.json" "$ref": "../image/image.json"
}, },
"projection_geometry": { "projection_geometry": {
"$ref": "./projection_geometry/projection_geometry.json" "$ref": "../projection_geometry/projection_geometry.json"
}, },
"projection_geometry_nominal": "projection_geometry_nominal": {
{ "$ref": "../projection_geometry/projection_geometry.json"
"$ref": "./projection_geometry/projection_geometry.json"
}, },
"detector": { "detector": {
"$ref": "./detector/detector.json" "$ref": "../detector/detector.json"
}, },
"source": { "source": {
"$ref": "./source/source.json" "$ref": "../source/source.json"
} }
}, },
"required": [ "required": [
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "THD Projection Geometry File Schema", "title": "THD Projection Geometry File Schema",
"type": "object", "type": "object",
"version": "0.1.9", "version": "0.1.11",
"date": "28.11.2024", "date": "20.03.2025",
"properties": { "properties": {
"header": { "header": {
"$ref": "../header/header.json" "$ref": "../header/header.json"
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "THD ROI File Schema", "title": "THD ROI File Schema",
"type": "object", "type": "object",
"version": "0.1.9", "version": "0.1.11",
"date": "28.11.2024", "date": "20.03.2025",
"properties": { "properties": {
"header": { "header": {
"$ref": "./header/header.json" "$ref": "../header/header.json"
}, },
"volume": { "volume": {
"$ref": "./volume/volume.json" "$ref": "../volume/volume.json"
}, },
"roi_center_position_mm": { "roi_center_position_mm": {
"type": "array", "type": "array",
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "THD X-Ray Source File Schema", "title": "THD X-Ray Source File Schema",
"type": "object", "type": "object",
"version": "0.1.9", "version": "0.1.11",
"date": "28.11.2024", "date": "20.03.2025",
"properties": { "properties": {
"voltage_kv": { "voltage_kv": {
"type": "number", "type": "number",
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
}, },
"current_ma": { "current_ma": {
"type": "number", "type": "number",
"description": "Source current in µA.", "description": "Source current in \u00c2\u00b5A.",
"minimum": 0.001 "minimum": 0.001
} }
}, },
......
import json import json
from pathlib import Path from pathlib import Path
from jsonschema import ValidationError, RefResolver from jsonschema import ValidationError
from jsonschema.validators import Draft202012Validator from jsonschema.validators import Draft202012Validator
import jsonref
class Validator: class Validator:
...@@ -11,20 +12,14 @@ class Validator: ...@@ -11,20 +12,14 @@ class Validator:
print(f"Validator for schema: {json_schema} \nSuffix: {json_suffix}\n") print(f"Validator for schema: {json_schema} \nSuffix: {json_suffix}\n")
def file(self, file_path: Path) -> bool: def file(self, file_path: Path) -> bool:
with ( with open(str(file_path)) as data_file:
open(str(self.json_schema)) as schema_file,
open(str(file_path)) as data_file,
):
schema = json.load(schema_file)
data = json.load(data_file) data = json.load(data_file)
schema_path = self.json_schema.parent.absolute().as_uri() self.json_schema.parent.absolute().as_uri() + "/"
resolver = RefResolver(base_uri=schema_path, referrer=schema) schema = self.get_schema()
try: try:
Draft202012Validator( Draft202012Validator(
schema=schema, schema=schema,
format_checker=Draft202012Validator.FORMAT_CHECKER, format_checker=Draft202012Validator.FORMAT_CHECKER,
resolver=resolver,
).validate(data) ).validate(data)
print(f"Validate file: {file_path.parent} / {file_path.name}\n") print(f"Validate file: {file_path.parent} / {file_path.name}\n")
...@@ -40,29 +35,7 @@ class Validator: ...@@ -40,29 +35,7 @@ class Validator:
return True return True
def get_schema(self): def get_schema(self):
schema_path = self.json_schema.parent.absolute().as_uri() schema_path = self.json_schema.parent.absolute().as_uri() + "/"
with open(str(self.json_schema)) as schema_file: with open(str(self.json_schema)) as schema_file:
schema = json.load(schema_file) schema = jsonref.load(schema_file, schema_path)
return schema
resolver = RefResolver(base_uri=schema_path, referrer=schema)
return self.resolve_ref(resolver, schema)
def resolve_ref(self, resolver, schema_part):
if isinstance(schema_part, dict) and "$ref" in schema_part:
# Resolve the reference
ref = schema_part["$ref"]
with resolver.resolving(ref) as resolved:
return self.resolve_ref(
resolver, resolved
) # Recursively resolve nested references
elif isinstance(schema_part, dict):
# Resolve each value in the dictionary
return {
key: self.resolve_ref(resolver, value)
for key, value in schema_part.items()
}
elif isinstance(schema_part, list):
# Resolve each item in the list
return [self.resolve_ref(resolver, item) for item in schema_part]
return schema_part
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "THD Projection Volume File Schema", "title": "THD Projection Volume File Schema",
"type": "object", "type": "object",
"version": "0.1.9", "version": "0.1.11",
"date": "28.11.2024", "date": "20.03.2025",
"properties": { "properties": {
"header": { "header": {
"$ref": "../header/header.json" "$ref": "../header/header.json"
......
...@@ -68,6 +68,15 @@ version = "0.3" ...@@ -68,6 +68,15 @@ version = "0.3"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/2a/04/855eecfdd379ff774ce86770808c6663ad4fdf14c43ed4e6fd7156aa5cf9/json_schema-0.3.tar.gz", hash = "sha256:a164efbb405f535615e58aff191b55fbfdad61d2ff0e7bfce6acf086358ca4b3", size = 5425 } sdist = { url = "https://files.pythonhosted.org/packages/2a/04/855eecfdd379ff774ce86770808c6663ad4fdf14c43ed4e6fd7156aa5cf9/json_schema-0.3.tar.gz", hash = "sha256:a164efbb405f535615e58aff191b55fbfdad61d2ff0e7bfce6acf086358ca4b3", size = 5425 }
[[package]]
name = "jsonref"
version = "1.1.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/aa/0d/c1f3277e90ccdb50d33ed5ba1ec5b3f0a242ed8c1b1a85d3afeb68464dca/jsonref-1.1.0.tar.gz", hash = "sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552", size = 8814 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0c/ec/e1db9922bceb168197a558a2b8c03a7963f1afe93517ddd3cf99f202f996/jsonref-1.1.0-py3-none-any.whl", hash = "sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9", size = 9425 },
]
[[package]] [[package]]
name = "jsonschema" name = "jsonschema"
version = "4.23.0" version = "4.23.0"
...@@ -347,13 +356,14 @@ wheels = [ ...@@ -347,13 +356,14 @@ wheels = [
[[package]] [[package]]
name = "thd-json" name = "thd-json"
version = "0.1.9" version = "0.1.11"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "hatchling" }, { name = "hatchling" },
{ name = "hypothesis" }, { name = "hypothesis" },
{ name = "hypothesis-jsonschema" }, { name = "hypothesis-jsonschema" },
{ name = "json-schema" }, { name = "json-schema" },
{ name = "jsonref" },
{ name = "jsonschema" }, { name = "jsonschema" },
{ name = "numpy" }, { name = "numpy" },
{ name = "pillow" }, { name = "pillow" },
...@@ -371,6 +381,7 @@ requires-dist = [ ...@@ -371,6 +381,7 @@ requires-dist = [
{ name = "hypothesis", specifier = ">=6.119.0" }, { name = "hypothesis", specifier = ">=6.119.0" },
{ name = "hypothesis-jsonschema", specifier = ">=0.23.1" }, { name = "hypothesis-jsonschema", specifier = ">=0.23.1" },
{ name = "json-schema", specifier = ">=0.3" }, { name = "json-schema", specifier = ">=0.3" },
{ name = "jsonref", specifier = ">=1.1.0" },
{ name = "jsonschema", specifier = ">=4.23.0" }, { name = "jsonschema", specifier = ">=4.23.0" },
{ name = "numpy", specifier = ">=2.1.3" }, { name = "numpy", specifier = ">=2.1.3" },
{ name = "numpy", marker = "extra == 'load'", specifier = ">=2.1.3" }, { name = "numpy", marker = "extra == 'load'", specifier = ">=2.1.3" },
......