diff --git a/examples/generated/example_roi.json b/examples/generated/example_roi.json new file mode 100644 index 0000000000000000000000000000000000000000..d72404715e031f7a9fd0047a4385ca8fcca8dd25 --- /dev/null +++ b/examples/generated/example_roi.json @@ -0,0 +1,27 @@ +{ + "header": { + "timestamp": "2000-01-01T00:00:00Z", + "uuid": "" + }, + "roi_center_position_mm": [ + 0.0, + 0.0, + 0.0 + ], + "roi_orientation_quat": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "roi_resolution_mm": [ + 0.0, + 0.0, + 0.0 + ], + "roi_voxels": [ + 1, + 1, + 1 + ] +} \ No newline at end of file diff --git a/examples/generated/example_volume.json b/examples/generated/example_volume.json new file mode 100644 index 0000000000000000000000000000000000000000..84956ac230ccf6e0bc49508c15f3d71653324db5 --- /dev/null +++ b/examples/generated/example_volume.json @@ -0,0 +1,5 @@ +{ + "timestamp": "2000-01-01T00:00:00Z", + "uuid": "", + "volume_path": ".tif" +} \ No newline at end of file diff --git a/scripts/generate_example_data.py b/scripts/generate_example_data.py index 9dc224031186f916cd547e534a9ae9c357c6cfe6..f3642743a40d976ff437d4fd2f494478d397ed52 100644 --- a/scripts/generate_example_data.py +++ b/scripts/generate_example_data.py @@ -4,6 +4,8 @@ from thd_json.header import get_header_validator from thd_json.source import get_source_validator from thd_json.detector import get_detector_validator from thd_json.image import get_image_validator +from thd_json.roi import get_roi_validator +from thd_json.volume import get_volume_validator from hypothesis import given, settings import json from pathlib import Path @@ -19,6 +21,8 @@ def main(): ("source", get_source_validator), ("detector", get_detector_validator), ("image", get_image_validator), + ("roi", get_roi_validator), + ("volume", get_volume_validator), ]: validator = get_validator() schema = validator.get_schema() diff --git a/src/thd_json/roi/__init__.py b/src/thd_json/roi/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..06c753435afe956466eaa9cb2df4a11d85a64dda --- /dev/null +++ b/src/thd_json/roi/__init__.py @@ -0,0 +1,33 @@ +from thd_json import Validator + +from pathlib import Path +import argparse + + +def get_roi_validator(json_suffix: str = "*.json") -> Validator: + return Validator(Path(__file__).parent / Path("roi.json"), json_suffix) + + +def roi_cli(): + parser = argparse.ArgumentParser(description="JSON THD ROI Validator CLI with uv.") + parser.add_argument("folder", help="Folder to check.", type=str) + parser.add_argument( + "suffix", help="Projection suffix.", default="*.json", type=Path, nargs="?" + ) + args = parser.parse_args() + + suffix = str(args.suffix) + if not suffix.startswith("*"): + raise ValueError(f'The suffix must always start with: "*". \nIt is: {suffix}') + + validator = get_roi_validator(suffix) + + folder = Path(args.folder) + if not folder.exists(): + raise FileNotFoundError(f"Folder: {folder} does not exist") + + validator.folder(Path(args.folder)) + + +if __name__ == "__main__": + roi_cli() diff --git a/src/thd_json/roi/roi.json b/src/thd_json/roi/roi.json new file mode 100644 index 0000000000000000000000000000000000000000..bba833c7894954952de438866b68141f44b8321d --- /dev/null +++ b/src/thd_json/roi/roi.json @@ -0,0 +1,58 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "THD ROI File Schema", + "type": "object", + "version": 0.6, + "date": "20.11.2024", + "properties": { + "header": { + "$ref": "./header/header.json" + }, + "roi_center_position_mm": { + "type": "array", + "description": "Position of the focal spot in millimeters.", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + }, + "roi_orientation_quat": { + "type": "array", + "description": "Quaternion representing the detector's center orientation.", + "items": { + "type": "number" + }, + "minItems": 4, + "maxItems": 4 + }, + "roi_resolution_mm": { + "type": "array", + "description": "Center position of the detector in millimeters.", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + }, + "roi_voxels": { + "type": "array", + "description": "Center position of the detector in millimeters.", + "items": { + "type": "integer", + "minimum": 1 + }, + "minItems": 3, + "maxItems": 3 + } + }, + "required": [ + "header", + "roi_center_position_mm", + "roi_orientation_quat", + "roi_resolution_mm", + "roi_voxels" + ], + "additionalProperties": false + } + \ No newline at end of file diff --git a/src/thd_json/volume/__init__.py b/src/thd_json/volume/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a7237a5939f12b32472c21b1d5a6590bfb7af484 --- /dev/null +++ b/src/thd_json/volume/__init__.py @@ -0,0 +1,35 @@ +from thd_json import Validator + +from pathlib import Path +import argparse + + +def get_volume_validator(json_suffix: str = "*.json") -> Validator: + return Validator(Path(__file__).parent / Path("volume.json"), json_suffix) + + +def volume_cli(): + parser = argparse.ArgumentParser( + description="JSON THD Volume Validator CLI with uv." + ) + parser.add_argument("folder", help="Folder to check.", type=str) + parser.add_argument( + "suffix", help="Projection suffix.", default="*.json", type=Path, nargs="?" + ) + args = parser.parse_args() + + suffix = str(args.suffix) + if not suffix.startswith("*"): + raise ValueError(f'The suffix must always start with: "*". \nIt is: {suffix}') + + validator = get_volume_validator(suffix) + + folder = Path(args.folder) + if not folder.exists(): + raise FileNotFoundError(f"Folder: {folder} does not exist") + + validator.folder(Path(args.folder)) + + +if __name__ == "__main__": + volume_cli() diff --git a/src/thd_json/volume/volume.json b/src/thd_json/volume/volume.json new file mode 100644 index 0000000000000000000000000000000000000000..122db5041f028deeb5db2e745b35daf8053af994 --- /dev/null +++ b/src/thd_json/volume/volume.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "THD Projection Volume File Schema", + "type": "object", + "version": 0.6, + "date": "20.11.2024", + "properties": { + "timestamp": { + "type": "string", + "description": "Timestamp, e.g. 2018-11-13T20:20:39+00:00", + "format": "date-time" + }, + "uuid": { + "type": "string", + "description": "Unique identifier", + "format": "uuid" + }, + "volume_path": { + "type": "string", + "description": "Path to TIFF file.", + "pattern": "^.*\\.(tif|tiff)$" + } + }, + "required": [ + "timestamp", + "uuid", + "volume_path" + ], + "additionalProperties": false +} \ No newline at end of file