From fee3aff682030b158ac55753a2a73701f2b2a9d1 Mon Sep 17 00:00:00 2001 From: Tobias Klockau Date: Mon, 4 Nov 2024 16:25:47 +0100 Subject: [PATCH] refactor: delete everything related to fromdict and asdict --- raillabel/format/_object_annotation.py | 18 +- raillabel/format/bbox.py | 56 --- raillabel/format/cuboid.py | 76 ---- raillabel/format/element_data_pointer.py | 33 -- raillabel/format/frame.py | 160 +------ raillabel/format/frame_interval.py | 34 -- raillabel/format/intrinsics_pinhole.py | 43 -- raillabel/format/intrinsics_radar.py | 41 -- raillabel/format/metadata.py | 64 --- raillabel/format/num.py | 49 -- raillabel/format/object.py | 197 -------- raillabel/format/point2d.py | 19 - raillabel/format/point3d.py | 20 - raillabel/format/poly2d.py | 63 --- raillabel/format/poly3d.py | 61 --- raillabel/format/quaternion.py | 21 - raillabel/format/scene.py | 178 -------- raillabel/format/seg3d.py | 50 --- raillabel/format/sensor.py | 121 ----- raillabel/format/sensor_reference.py | 51 --- raillabel/format/size2d.py | 19 - raillabel/format/size3d.py | 20 - raillabel/format/transform.py | 34 -- raillabel/load/load.py | 10 +- raillabel/save/save.py | 12 +- tests/test_raillabel/format/conftest.py | 66 +-- .../test_raillabel/format/test_attributes.py | 126 ------ tests/test_raillabel/format/test_bbox.py | 147 ------ tests/test_raillabel/format/test_cuboid.py | 118 ----- .../format/test_element_data_pointer.py | 105 ----- tests/test_raillabel/format/test_frame.py | 168 ------- .../format/test_frame_interval.py | 29 -- .../format/test_intrinsics_pinhole.py | 42 -- .../format/test_intrinsics_radar.py | 37 -- tests/test_raillabel/format/test_metadata.py | 129 ------ tests/test_raillabel/format/test_num.py | 77 ---- tests/test_raillabel/format/test_object.py | 423 ------------------ .../format/test_object_annotation.py | 55 --- .../test_raillabel/format/test_object_data.py | 41 -- tests/test_raillabel/format/test_point2d.py | 32 +- tests/test_raillabel/format/test_point3d.py | 43 +- tests/test_raillabel/format/test_poly2d.py | 120 ----- tests/test_raillabel/format/test_poly3d.py | 112 ----- .../test_raillabel/format/test_quaternion.py | 30 +- tests/test_raillabel/format/test_scene.py | 362 --------------- tests/test_raillabel/format/test_seg3d.py | 97 ---- tests/test_raillabel/format/test_sensor.py | 277 ------------ .../format/test_sensor_reference.py | 65 --- tests/test_raillabel/format/test_size2d.py | 22 +- tests/test_raillabel/format/test_size3d.py | 48 -- tests/test_raillabel/format/test_transform.py | 22 +- tests/test_raillabel/load/test_load.py | 21 - tests/test_raillabel/save/test_save.py | 85 ---- 53 files changed, 30 insertions(+), 4319 deletions(-) delete mode 100644 tests/test_raillabel/format/test_attributes.py delete mode 100644 tests/test_raillabel/format/test_bbox.py delete mode 100644 tests/test_raillabel/format/test_cuboid.py delete mode 100644 tests/test_raillabel/format/test_element_data_pointer.py delete mode 100644 tests/test_raillabel/format/test_frame.py delete mode 100644 tests/test_raillabel/format/test_metadata.py delete mode 100644 tests/test_raillabel/format/test_num.py delete mode 100644 tests/test_raillabel/format/test_object.py delete mode 100644 tests/test_raillabel/format/test_object_annotation.py delete mode 100644 tests/test_raillabel/format/test_object_data.py delete mode 100644 tests/test_raillabel/format/test_poly2d.py delete mode 100644 tests/test_raillabel/format/test_poly3d.py delete mode 100644 tests/test_raillabel/format/test_scene.py delete mode 100644 tests/test_raillabel/format/test_seg3d.py delete mode 100644 tests/test_raillabel/format/test_sensor.py delete mode 100644 tests/test_raillabel/format/test_sensor_reference.py delete mode 100644 tests/test_raillabel/format/test_size3d.py delete mode 100644 tests/test_raillabel/load/test_load.py delete mode 100644 tests/test_raillabel/save/test_save.py diff --git a/raillabel/format/_object_annotation.py b/raillabel/format/_object_annotation.py index 4487cf2..c9d09d4 100644 --- a/raillabel/format/_object_annotation.py +++ b/raillabel/format/_object_annotation.py @@ -3,7 +3,7 @@ from __future__ import annotations -from abc import ABC, abstractmethod, abstractproperty +from abc import ABC, abstractproperty from dataclasses import dataclass from importlib import import_module from inspect import isclass @@ -32,22 +32,6 @@ def name(self) -> str: def OPENLABEL_ID(self) -> list[str] | str: raise NotImplementedError - # === Public Methods ===================================================== - - @abstractmethod - def asdict(self) -> dict: - raise NotImplementedError - - @classmethod - @abstractmethod - def fromdict( - cls, - data_dict: dict, - sensors: dict, - object: Object, - ) -> type[_ObjectAnnotation]: - raise NotImplementedError - # === Private Methods ==================================================== def _annotation_required_fields_asdict(self) -> dict: diff --git a/raillabel/format/bbox.py b/raillabel/format/bbox.py index 67406e8..6e99e1e 100644 --- a/raillabel/format/bbox.py +++ b/raillabel/format/bbox.py @@ -6,7 +6,6 @@ from dataclasses import dataclass from ._object_annotation import _ObjectAnnotation -from .object import Object from .point2d import Point2d from .size2d import Size2d @@ -42,58 +41,3 @@ class Bbox(_ObjectAnnotation): size: Size2d OPENLABEL_ID = "bbox" - - @classmethod - def fromdict(cls, data_dict: dict, sensors: dict, object: Object) -> Bbox: - """Generate a Bbox object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - sensors: dict - Dictionary containing all sensors for the scene. - object: raillabel.format.Object - Object this annotation belongs to. - - Returns - ------- - annotation: Bbox - Converted annotation. - - """ - return Bbox( - uid=str(data_dict["uid"]), - pos=Point2d(x=data_dict["val"][0], y=data_dict["val"][1]), - size=Size2d(x=data_dict["val"][2], y=data_dict["val"][3]), - object=object, - sensor=cls._coordinate_system_fromdict(data_dict, sensors), - attributes=cls._attributes_fromdict(data_dict), - ) - - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - dict_repr = self._annotation_required_fields_asdict() - - dict_repr["val"] = [ - float(self.pos.x), - float(self.pos.y), - float(self.size.x), - float(self.size.y), - ] - - dict_repr.update(self._annotation_optional_fields_asdict()) - - return dict_repr diff --git a/raillabel/format/cuboid.py b/raillabel/format/cuboid.py index 36bcf2d..ec70005 100644 --- a/raillabel/format/cuboid.py +++ b/raillabel/format/cuboid.py @@ -6,7 +6,6 @@ from dataclasses import dataclass from ._object_annotation import _ObjectAnnotation -from .object import Object from .point3d import Point3d from .quaternion import Quaternion from .size3d import Size3d @@ -47,78 +46,3 @@ class Cuboid(_ObjectAnnotation): size: Size3d OPENLABEL_ID = "cuboid" - - @classmethod - def fromdict(cls, data_dict: dict, sensors: dict, object: Object) -> Cuboid: - """Generate a Cuboid object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - sensors: dict - Dictionary containing all sensors for the scene. - object: raillabel.format.Object - Object this annotation belongs to. - - Returns - ------- - annotation: Cuboid - Converted annotation. - - """ - return Cuboid( - uid=str(data_dict["uid"]), - pos=Point3d( - x=data_dict["val"][0], - y=data_dict["val"][1], - z=data_dict["val"][2], - ), - quat=Quaternion( - x=data_dict["val"][3], - y=data_dict["val"][4], - z=data_dict["val"][5], - w=data_dict["val"][6], - ), - size=Size3d( - x=data_dict["val"][7], - y=data_dict["val"][8], - z=data_dict["val"][9], - ), - object=object, - sensor=cls._coordinate_system_fromdict(data_dict, sensors), - attributes=cls._attributes_fromdict(data_dict), - ) - - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - dict_repr = self._annotation_required_fields_asdict() - - dict_repr["val"] = [ - float(self.pos.x), - float(self.pos.y), - float(self.pos.z), - float(self.quat.x), - float(self.quat.y), - float(self.quat.z), - float(self.quat.w), - float(self.size.x), - float(self.size.y), - float(self.size.z), - ] - - dict_repr.update(self._annotation_optional_fields_asdict()) - - return dict_repr diff --git a/raillabel/format/element_data_pointer.py b/raillabel/format/element_data_pointer.py index f2c3e07..d3f23fc 100644 --- a/raillabel/format/element_data_pointer.py +++ b/raillabel/format/element_data_pointer.py @@ -34,36 +34,3 @@ class ElementDataPointer: uid: str frame_intervals: list[FrameInterval] attribute_pointers: dict[str, AttributeType] - - @property - def annotation_type(self) -> str: - """Return type of annotation e.g. bbox, cuboid.""" - return self.uid.split("__")[1] - - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - return { - "type": self.annotation_type, - "frame_intervals": self._frame_intervals_asdict(), - "attribute_pointers": self._attribute_pointers_asdict(), - } - - def _frame_intervals_asdict(self) -> list[dict[str, int]]: - return [fi.asdict() for fi in self.frame_intervals] - - def _attribute_pointers_asdict(self) -> dict[str, str]: - return { - attr_name: attr_type.value for attr_name, attr_type in self.attribute_pointers.items() - } diff --git a/raillabel/format/frame.py b/raillabel/format/frame.py index 0dcd722..a8ac366 100644 --- a/raillabel/format/frame.py +++ b/raillabel/format/frame.py @@ -4,13 +4,10 @@ from __future__ import annotations import decimal -import typing as t from dataclasses import dataclass, field -from ._object_annotation import _ObjectAnnotation, annotation_classes +from ._object_annotation import _ObjectAnnotation from .num import Num -from .object import Object -from .sensor import Sensor from .sensor_reference import SensorReference @@ -64,158 +61,3 @@ def object_data(self) -> dict[str, dict[str, type[_ObjectAnnotation]]]: object_data[annotation.object.uid][ann_id] = annotation return object_data - - @classmethod - def fromdict( - cls, - data_dict: dict, - objects: dict[str, Object], - sensors: dict[str, Sensor], - ) -> Frame: - """Generate a Frame object from a dict. - - Parameters - ---------- - uid: str - Unique identifier of the frame. - data_dict: dict - RailLabel format snippet containing the relevant data. - objects: dict - Dictionary of all objects in the scene. - sensors: dict - Dictionary of all sensors in the scene. - - Returns - ------- - frame: raillabel.format.Frame - Converted Frame object. - - """ - return Frame( - timestamp=cls._timestamp_fromdict(data_dict), - sensors=cls._sensors_fromdict(data_dict, sensors), - frame_data=cls._frame_data_fromdict(data_dict, sensors), - annotations=cls._objects_fromdict(data_dict, objects, sensors), - ) - - def asdict(self) -> dict[str, t.Any]: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - dict_repr: dict[str, t.Any] = {} - - if self.timestamp is not None or self.sensors != {} or self.frame_data != {}: - dict_repr["frame_properties"] = {} - - if self.timestamp is not None: - dict_repr["frame_properties"]["timestamp"] = str(self.timestamp) - - if self.sensors != {}: - dict_repr["frame_properties"]["streams"] = { - str(k): v.asdict() for k, v in self.sensors.items() - } - - if self.frame_data != {}: - dict_repr["frame_properties"]["frame_data"] = { - "num": [v.asdict() for v in self.frame_data.values()] - } - - if self.annotations != {}: - dict_repr["objects"] = self._annotations_asdict() - - return dict_repr - - @classmethod - def _timestamp_fromdict(cls, data_dict: dict) -> decimal.Decimal | None: - if "frame_properties" not in data_dict or "timestamp" not in data_dict["frame_properties"]: - return None - - return decimal.Decimal(data_dict["frame_properties"]["timestamp"]) - - @classmethod - def _sensors_fromdict( - cls, data_dict: dict, scene_sensors: dict[str, Sensor] - ) -> dict[str, SensorReference]: - if "frame_properties" not in data_dict or "streams" not in data_dict["frame_properties"]: - return {} - - sensors = {} - - for sensor_id, sensor_dict in data_dict["frame_properties"]["streams"].items(): - sensors[sensor_id] = SensorReference.fromdict( - data_dict=sensor_dict, sensor=scene_sensors[sensor_id] - ) - - return sensors - - @classmethod - def _frame_data_fromdict(cls, data_dict: dict, sensors: dict[str, Sensor]) -> dict[str, Num]: - if "frame_properties" not in data_dict or "frame_data" not in data_dict["frame_properties"]: - return {} - - frame_data = {} - for ann_type in data_dict["frame_properties"]["frame_data"]: - for ann_raw in data_dict["frame_properties"]["frame_data"][ann_type]: - frame_data[ann_raw["name"]] = Num.fromdict(ann_raw, sensors) - - return frame_data - - @classmethod - def _objects_fromdict( - cls, - data_dict: dict, - objects: dict[str, Object], - sensors: dict[str, Sensor], - ) -> dict[str, type[_ObjectAnnotation]]: - if "objects" not in data_dict: - return {} - - annotations = {} - - for obj_id, obj_ann in data_dict["objects"].items(): - object_annotations = cls._object_annotations_fromdict( - data_dict=obj_ann["object_data"], - object=objects[obj_id], - sensors=sensors, - ) - - for annotation in object_annotations: - annotations[annotation.uid] = annotation - - return annotations - - @classmethod - def _object_annotations_fromdict( - cls, - data_dict: dict, - object: Object, - sensors: dict[str, Sensor], - ) -> t.Iterator[type[_ObjectAnnotation]]: - for ann_type, annotations_raw in data_dict.items(): - for ann_raw in annotations_raw: - yield annotation_classes()[ann_type].fromdict(ann_raw, sensors, object) - - def _annotations_asdict(self) -> dict[str, t.Any]: - annotations_dict: dict[str, t.Any] = {} - for object_id, annotations_ in self.object_data.items(): - annotations_dict[object_id] = {"object_data": {}} - - for annotation in annotations_.values(): - if annotation.OPENLABEL_ID not in annotations_dict[object_id]["object_data"]: - annotations_dict[object_id]["object_data"][annotation.OPENLABEL_ID] = [] - - annotations_dict[object_id]["object_data"][annotation.OPENLABEL_ID].append( - annotation.asdict() # type: ignore - ) - - return annotations_dict diff --git a/raillabel/format/frame_interval.py b/raillabel/format/frame_interval.py index 8780785..33231a0 100644 --- a/raillabel/format/frame_interval.py +++ b/raillabel/format/frame_interval.py @@ -26,21 +26,6 @@ def from_json(cls, json: JSONFrameInterval) -> FrameInterval: end=json.frame_end, ) - @classmethod - def fromdict(cls, data_dict: dict) -> FrameInterval: - """Generate a FrameInterval object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - - """ - return FrameInterval( - start=data_dict["frame_start"], - end=data_dict["frame_end"], - ) - @classmethod def from_frame_uids(cls, frame_uids: list[int]) -> list[FrameInterval]: """Convert a list of frame uids into FrameIntervals. @@ -63,25 +48,6 @@ def from_frame_uids(cls, frame_uids: list[int]) -> list[FrameInterval]: FrameInterval(start=interval[0], end=interval[-1]) for interval in frame_uid_intervals ] - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - return { - "frame_start": int(self.start), - "frame_end": int(self.end), - } - def __len__(self) -> int: """Return the length in frames.""" return abs(self.start - self.end) + 1 diff --git a/raillabel/format/intrinsics_pinhole.py b/raillabel/format/intrinsics_pinhole.py index 6979371..357bd4e 100644 --- a/raillabel/format/intrinsics_pinhole.py +++ b/raillabel/format/intrinsics_pinhole.py @@ -39,46 +39,3 @@ def from_json(cls, json: JSONIntrinsicsPinhole) -> IntrinsicsPinhole: width_px=json.width_px, height_px=json.height_px, ) - - @classmethod - def fromdict(cls, data_dict: dict) -> IntrinsicsPinhole: - """Generate a IntrinsicsPinhole object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - - Returns - ------- - raillabel.format.IntrinsicsPinhole - Converted IntrinsicsPinhole object. - - """ - return IntrinsicsPinhole( - camera_matrix=tuple(data_dict["camera_matrix"]), - distortion=tuple(data_dict["distortion_coeffs"]), - width_px=data_dict["width_px"], - height_px=data_dict["height_px"], - ) - - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - return { - "camera_matrix": list(self.camera_matrix), - "distortion_coeffs": list(self.distortion), - "width_px": int(self.width_px), - "height_px": int(self.height_px), - } diff --git a/raillabel/format/intrinsics_radar.py b/raillabel/format/intrinsics_radar.py index 355bfb5..04ba839 100644 --- a/raillabel/format/intrinsics_radar.py +++ b/raillabel/format/intrinsics_radar.py @@ -30,44 +30,3 @@ def from_json(cls, json: JSONIntrinsicsRadar) -> IntrinsicsRadar: width_px=json.width_px, height_px=json.height_px, ) - - @classmethod - def fromdict(cls, data_dict: dict) -> IntrinsicsRadar: - """Generate a IntrinsicsRadar object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - - Returns - ------- - raillabel.format.IntrinsicsRadar - Converted IntrinsicsRadar object. - - """ - return IntrinsicsRadar( - resolution_px_per_m=data_dict["resolution_px_per_m"], - width_px=data_dict["width_px"], - height_px=data_dict["height_px"], - ) - - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - return { - "resolution_px_per_m": float(self.resolution_px_per_m), - "width_px": int(self.width_px), - "height_px": int(self.height_px), - } diff --git a/raillabel/format/metadata.py b/raillabel/format/metadata.py index b863b97..a27e46e 100644 --- a/raillabel/format/metadata.py +++ b/raillabel/format/metadata.py @@ -4,7 +4,6 @@ from __future__ import annotations from dataclasses import dataclass -from importlib import metadata as importlib_metadata @dataclass @@ -60,66 +59,3 @@ class Metadata: name: str | None = None subschema_version: str | None = None tagged_file: str | None = None - - @classmethod - def fromdict(cls, data_dict: dict, subschema_version: str | None = None) -> Metadata: - """Generate a Metadata object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. Additional (non-defined) - arguments can be set and will be added as properties to Metadata. - subschema_version: str, optional - Version of the RailLabel subschema - - Returns - ------- - metadata: Metadata - Converted metadata. - - """ - metadata = Metadata( - schema_version=data_dict["schema_version"], - subschema_version=subschema_version, - exporter_version=cls._collect_exporter_version(), - ) - - return cls._set_additional_attributes(metadata, data_dict) - - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - """ - return self._remove_empty_fields(vars(self)) - - @classmethod - def _collect_exporter_version(cls) -> str | None: - try: - exporter_version = importlib_metadata.version("raillabel") - except importlib_metadata.PackageNotFoundError: - return None - - version_number_length = len(exporter_version) - len(exporter_version.split(".")[-1]) - return exporter_version[: version_number_length - 1] - - @classmethod - def _set_additional_attributes(cls, metadata: Metadata, data_dict: dict) -> Metadata: - preset_keys = ["schema_version", "subschema_version", "exporter_version"] - - for key, value in data_dict.items(): - if key in preset_keys: - continue - - setattr(metadata, key, value) - - return metadata - - def _remove_empty_fields(self, dict_repr: dict) -> dict: - """Remove empty fields from a dictionary.""" - return {k: v for k, v in dict_repr.items() if v is not None} diff --git a/raillabel/format/num.py b/raillabel/format/num.py index 94c538f..243c65b 100644 --- a/raillabel/format/num.py +++ b/raillabel/format/num.py @@ -32,52 +32,3 @@ class Num: name: str val: int | float sensor: Sensor - - @classmethod - def fromdict(cls, data_dict: dict, sensors: dict) -> Num: - """Generate a Num object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - sensors: dict - Dictionary containing all sensors for the scene. - - Returns - ------- - annotation: Num - Converted annotation. - - """ - return Num( - uid=str(data_dict["uid"]), - name=str(data_dict["name"]), - val=data_dict["val"], - sensor=cls._coordinate_system_fromdict(data_dict, sensors), - ) - - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - return { - "uid": str(self.uid), - "name": str(self.name), - "val": self.val, - "coordinate_system": str(self.sensor.uid), - } - - @classmethod - def _coordinate_system_fromdict(cls, data_dict: dict, sensors: dict) -> Sensor: - return sensors[data_dict["coordinate_system"]] diff --git a/raillabel/format/object.py b/raillabel/format/object.py index 9301ce0..9faa0c3 100644 --- a/raillabel/format/object.py +++ b/raillabel/format/object.py @@ -3,15 +3,8 @@ from __future__ import annotations -import typing as t from dataclasses import dataclass -from .element_data_pointer import AttributeType, ElementDataPointer -from .frame_interval import FrameInterval - -if t.TYPE_CHECKING: - from .frame import Frame - @dataclass class Object: @@ -32,193 +25,3 @@ class Object: uid: str name: str type: str - - # --- Public Methods -------------- - - @classmethod - def fromdict(cls, data_dict: dict, object_uid: str) -> Object: - """Generate a Object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - object_uid: str - Unique identifier of the object. - - Returns - ------- - object: raillabel.format.Object - Converted object. - - """ - return Object(uid=object_uid, type=data_dict["type"], name=data_dict["name"]) - - def asdict(self, frames: dict[int, Frame] | None = None) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - frames: dict, optional - The dictionary of frames stored under Scene.frames used for the frame intervals and - object data pointers. If None, these are not provided. Default is None. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - if frames is None: - return {"name": str(self.name), "type": str(self.type)} - - return { - "name": str(self.name), - "type": str(self.type), - "frame_intervals": self._frame_intervals_asdict(self.frame_intervals(frames)), - "object_data_pointers": self._object_data_pointers_asdict( - self.object_data_pointers(frames) - ), - } - - def frame_intervals(self, frames: dict[int, Frame]) -> list[FrameInterval]: - """Return frame intervals in which this object is present. - - Parameters - ---------- - frames: dict[int, raillabel.format.Frame] - The dictionary of frames stored under Scene.frames. - - Returns - ------- - list[FrameInterval] - List of the FrameIntervals, where this object is contained. - - """ - frame_uids_containing_object = [ - frame_uid for frame_uid, frame in frames.items() if self._is_object_in_frame(frame) - ] - - return FrameInterval.from_frame_uids(frame_uids_containing_object) - - def object_data_pointers(self, frames: dict[int, Frame]) -> dict[str, ElementDataPointer]: - """Create object data pointers used in WebLABEL visualization. - - Parameters - ---------- - frames: dict[int, raillabel.format.Frame] - The dictionary of frames stored under Scene.frames. - - Returns - ------- - dict[str, ElementDataPointer] - ObjectDataPointers dict as required by WebLABEL. Keys are the ObjectDataPointer uids. - - """ - pointer_ids_per_frame = self._collect_pointer_ids_per_frame(frames) - frame_uids_per_pointer_id = self._reverse_frame_pointer_ids(pointer_ids_per_frame) - frame_intervals_per_pointer_id = self._convert_to_intervals(frame_uids_per_pointer_id) - - attributes_per_pointer_id = self._collect_attributes_per_pointer_id(frames) - attribute_pointers_per_pointer_id = self._convert_to_attribute_pointers( - attributes_per_pointer_id - ) - - return self._create_object_data_pointers( - frame_intervals_per_pointer_id, attribute_pointers_per_pointer_id - ) - - # --- Private Methods ------------- - - def _frame_intervals_asdict( - self, frame_intervals: list[FrameInterval] - ) -> list[dict[str, t.Any]]: - return [fi.asdict() for fi in frame_intervals] - - def _object_data_pointers_asdict( - self, object_data_pointers: dict[str, ElementDataPointer] - ) -> dict: - return {pointer_id: pointer.asdict() for pointer_id, pointer in object_data_pointers.items()} - - def _is_object_in_frame(self, frame: Frame) -> bool: - return self.uid in frame.object_data - - def _filtered_annotations(self, frame: Frame) -> list[t.Any]: - return [ann for ann in frame.annotations.values() if ann.object.uid == self.uid] - - def _collect_pointer_ids_per_frame(self, frames: dict[int, Frame]) -> dict[int, set[str]]: - pointer_ids_per_frame: dict[int, set[str]] = {} - for frame_uid, frame in frames.items(): - pointer_ids_per_frame[frame_uid] = set() - - for annotation in self._filtered_annotations(frame): - pointer_ids_per_frame[frame_uid].add(annotation.name) # type: ignore - - return pointer_ids_per_frame - - def _reverse_frame_pointer_ids( - self, pointer_ids_per_frame: dict[int, set[str]] - ) -> dict[str, set[int]]: - frame_uids_per_pointer_id: dict[str, set[int]] = {} - for frame_uid, pointer_ids in pointer_ids_per_frame.items(): - for pointer_id in pointer_ids: - if pointer_id not in frame_uids_per_pointer_id: - frame_uids_per_pointer_id[pointer_id] = set() - - frame_uids_per_pointer_id[pointer_id].add(frame_uid) - - return frame_uids_per_pointer_id - - def _convert_to_intervals( - self, frame_uids_per_pointer_id: dict[str, set[int]] - ) -> dict[str, list[FrameInterval]]: - frame_intervals = {} - for pointer_id, frame_uids in frame_uids_per_pointer_id.items(): - frame_intervals[pointer_id] = FrameInterval.from_frame_uids(list(frame_uids)) - - return frame_intervals - - def _collect_attributes_per_pointer_id( - self, frames: dict[int, Frame] - ) -> dict[str, dict[str, t.Any]]: - attributes_per_pointer_id: dict[str, dict[str, t.Any]] = {} - for frame in frames.values(): - for annotation in self._filtered_annotations(frame): - if annotation.name not in attributes_per_pointer_id: # type: ignore - attributes_per_pointer_id[annotation.name] = {} # type: ignore - - attributes_per_pointer_id[annotation.name].update(annotation.attributes) # type: ignore - - return attributes_per_pointer_id - - def _convert_to_attribute_pointers( - self, attributes_per_pointer_id: dict[str, dict[str, t.Any]] - ) -> dict[str, dict[str, AttributeType]]: - for attributes in attributes_per_pointer_id.values(): - for attribute_name, attribute_value in attributes.items(): - attributes[attribute_name] = AttributeType.from_value(type(attribute_value)) - - return attributes_per_pointer_id - - def _create_object_data_pointers( - self, - frame_intervals_per_pointer_id: dict[str, list[FrameInterval]], - attribute_pointers_per_pointer_id: dict[str, dict[str, AttributeType]], - ) -> dict[str, ElementDataPointer]: - object_data_pointers = {} - for pointer_id in frame_intervals_per_pointer_id: - object_data_pointers[pointer_id] = ElementDataPointer( - uid=pointer_id, - frame_intervals=frame_intervals_per_pointer_id[pointer_id], - attribute_pointers=attribute_pointers_per_pointer_id[pointer_id], - ) - - return object_data_pointers - - # --- Special Methods ------------- - - def __hash__(self) -> int: - """Return hash.""" - return self.uid.__hash__() diff --git a/raillabel/format/point2d.py b/raillabel/format/point2d.py index 07566b0..e1934ba 100644 --- a/raillabel/format/point2d.py +++ b/raillabel/format/point2d.py @@ -20,22 +20,3 @@ class Point2d: def from_json(cls, json: tuple[int | float, int | float]) -> Point2d: """Construct an instant of this class from RailLabel JSON data.""" return Point2d(x=json[0], y=json[1]) - - @classmethod - def fromdict(cls, data_dict: dict) -> Point2d: - """Generate a Point2d object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - - """ - return Point2d( - x=data_dict[0], - y=data_dict[1], - ) - - def asdict(self) -> list[float]: - """Export self as a dict compatible with the OpenLABEL schema.""" - return [float(self.x), float(self.y)] diff --git a/raillabel/format/point3d.py b/raillabel/format/point3d.py index f916a6f..9fcabf1 100644 --- a/raillabel/format/point3d.py +++ b/raillabel/format/point3d.py @@ -23,23 +23,3 @@ class Point3d: def from_json(cls, json: tuple[float, float, float]) -> Point3d: """Construct an instant of this class from RailLabel JSON data.""" return Point3d(x=json[0], y=json[1], z=json[2]) - - @classmethod - def fromdict(cls, data_dict: dict) -> Point3d: - """Generate a Point3d object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - - """ - return Point3d( - x=data_dict[0], - y=data_dict[1], - z=data_dict[2], - ) - - def asdict(self) -> list[float]: - """Export self as a dict compatible with the OpenLABEL schema.""" - return [float(self.x), float(self.y), float(self.z)] diff --git a/raillabel/format/poly2d.py b/raillabel/format/poly2d.py index 1952714..703ccf8 100644 --- a/raillabel/format/poly2d.py +++ b/raillabel/format/poly2d.py @@ -6,7 +6,6 @@ from dataclasses import dataclass from ._object_annotation import _ObjectAnnotation -from .object import Object from .point2d import Point2d @@ -50,65 +49,3 @@ class Poly2d(_ObjectAnnotation): mode: str = "MODE_POLY2D_ABSOLUTE" OPENLABEL_ID = "poly2d" - - @classmethod - def fromdict(cls, data_dict: dict, sensors: dict, object: Object) -> Poly2d: - """Generate a Poly2d object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - sensors: dict - Dictionary containing all sensors for the scene. - object: raillabel.format.Object - Object this annotation belongs to. - - Returns - ------- - annotation: Poly2d - Converted annotation. - - """ - return Poly2d( - uid=str(data_dict["uid"]), - closed=data_dict["closed"], - mode=data_dict["mode"], - points=cls._points_fromdict(data_dict), - object=object, - sensor=cls._coordinate_system_fromdict(data_dict, sensors), - attributes=cls._attributes_fromdict(data_dict), - ) - - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - dict_repr = self._annotation_required_fields_asdict() - - dict_repr["closed"] = bool(self.closed) - dict_repr["val"] = [] - dict_repr["mode"] = self.mode - for point in self.points: - dict_repr["val"].extend(point.asdict()) - - dict_repr.update(self._annotation_optional_fields_asdict()) - - return dict_repr - - @classmethod - def _points_fromdict(cls, data_dict: dict) -> list[Point2d]: - return [ - Point2d(x=data_dict["val"][i], y=data_dict["val"][i + 1]) - for i in range(0, len(data_dict["val"]), 2) - ] diff --git a/raillabel/format/poly3d.py b/raillabel/format/poly3d.py index d993adc..23cc8d7 100644 --- a/raillabel/format/poly3d.py +++ b/raillabel/format/poly3d.py @@ -6,7 +6,6 @@ from dataclasses import dataclass from ._object_annotation import _ObjectAnnotation -from .object import Object from .point3d import Point3d @@ -42,63 +41,3 @@ class Poly3d(_ObjectAnnotation): closed: bool OPENLABEL_ID = "poly3d" - - @classmethod - def fromdict(cls, data_dict: dict, sensors: dict, object: Object) -> Poly3d: - """Generate a Poly3d object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - sensors: dict - Dictionary containing all sensors for the scene. - object: raillabel.format.Object - Object this annotation belongs to. - - Returns - ------- - annotation: Poly3d - Converted annotation. - - """ - return Poly3d( - uid=str(data_dict["uid"]), - closed=data_dict["closed"], - points=cls._points_fromdict(data_dict), - object=object, - sensor=cls._coordinate_system_fromdict(data_dict, sensors), - attributes=cls._attributes_fromdict(data_dict), - ) - - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - dict_repr = self._annotation_required_fields_asdict() - - dict_repr["closed"] = bool(self.closed) - dict_repr["val"] = [] - for point in self.points: - dict_repr["val"].extend(point.asdict()) - - dict_repr.update(self._annotation_optional_fields_asdict()) - - return dict_repr - - @classmethod - def _points_fromdict(cls, data_dict: dict) -> list[Point3d]: - return [ - Point3d(x=data_dict["val"][i], y=data_dict["val"][i + 1], z=data_dict["val"][i + 2]) - for i in range(0, len(data_dict["val"]), 3) - ] diff --git a/raillabel/format/quaternion.py b/raillabel/format/quaternion.py index 366747a..d325cba 100644 --- a/raillabel/format/quaternion.py +++ b/raillabel/format/quaternion.py @@ -26,24 +26,3 @@ class Quaternion: def from_json(cls, json: tuple[float, float, float, float]) -> Quaternion: """Construct an instant of this class from RailLabel JSON data.""" return Quaternion(x=json[0], y=json[1], z=json[2], w=json[3]) - - @classmethod - def fromdict(cls, data_dict: dict) -> Quaternion: - """Generate a Quaternion object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - - """ - return Quaternion( - x=data_dict[0], - y=data_dict[1], - z=data_dict[2], - w=data_dict[3], - ) - - def asdict(self) -> list[float]: - """Export self as a dict compatible with the OpenLABEL schema.""" - return [float(self.x), float(self.y), float(self.z), float(self.w)] diff --git a/raillabel/format/scene.py b/raillabel/format/scene.py index abe5bf4..574351c 100644 --- a/raillabel/format/scene.py +++ b/raillabel/format/scene.py @@ -4,7 +4,6 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import Any from .frame import Frame from .frame_interval import FrameInterval @@ -44,180 +43,3 @@ class Scene: def frame_intervals(self) -> list[FrameInterval]: """Return frame intervals of the present frames.""" return FrameInterval.from_frame_uids(list(self.frames.keys())) - - # === Public Methods ========================================================================== - - @classmethod - def fromdict(cls, data_dict: dict, subschema_version: str | None = None) -> Scene: - """Generate a Scene object from a RailLABEL-dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - subschema_version: str, optional - Version of the RailLabel subschema. - - Returns - ------- - raillabel.format.Scene - Converted Scene object. - - Raises - ------ - raillabel.exceptions.MissingCoordinateSystemError - if a stream has no corresponding coordinate system. - raillabel.exceptions.MissingStreamError - if a coordinate system has no corresponding stream. - raillabel.exceptions.UnsupportedParentError - if a coordinate system has no corresponding stream. - - """ - data_dict = cls._prepare_data(data_dict) - - sensors = cls._sensors_fromdict(data_dict["streams"], data_dict["coordinate_systems"]) - objects = cls._objects_fromdict(data_dict["objects"]) - - return Scene( - metadata=Metadata.fromdict(data_dict["metadata"], subschema_version), - sensors=sensors, - objects=objects, - frames=cls._frames_fromdict(data_dict["frames"], sensors, objects), - ) - - def asdict(self, calculate_pointers: bool = True) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this Scene. - calculate_pointers: bool, optional - If True, object_data_pointers and Object frame_intervals will be calculated. Default - is True. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - return { - "openlabel": _clean_dict( - { - "metadata": self.metadata.asdict(), - "streams": self._streams_asdict(self.sensors), - "coordinate_systems": self._coordinate_systems_asdict(self.sensors), - "objects": self._objects_asdict(self.objects, calculate_pointers), - "frames": self._frames_asdict(self.frames), - "frame_intervals": self._frame_intervals_asdict(self.frame_intervals), - } - ) - } - - # === Private Methods ========================================================================= - - # --- fromdict() ---------------------------- - - @classmethod - def _prepare_data(cls, data: dict) -> dict: - """Add optional fields to dict to simplify interaction. - - Parameters - ---------- - data : dict - JSON data. - - Returns - ------- - dict - Enhanced JSON data. - - """ - if "coordinate_systems" not in data["openlabel"]: - data["openlabel"]["coordinate_systems"] = {} - - if "streams" not in data["openlabel"]: - data["openlabel"]["streams"] = {} - - if "objects" not in data["openlabel"]: - data["openlabel"]["objects"] = {} - - if "frames" not in data["openlabel"]: - data["openlabel"]["frames"] = {} - - return data["openlabel"] - - @classmethod - def _sensors_fromdict( - cls, streams_dict: dict, coordinate_systems_dict: dict - ) -> dict[str, Sensor]: - sensors = {} - - for stream_id in streams_dict: - sensors[stream_id] = Sensor.fromdict( - uid=stream_id, - cs_data_dict=coordinate_systems_dict[stream_id], - stream_data_dict=streams_dict[stream_id], - ) - - return sensors - - @classmethod - def _objects_fromdict(cls, object_dict: dict) -> dict[str, Object]: - return {uid: Object.fromdict(object_, uid) for uid, object_ in object_dict.items()} - - @classmethod - def _frames_fromdict( - cls, frames_dict: dict, sensors: dict[str, Sensor], objects: dict[str, Object] - ) -> dict[int, Frame]: - frames = {} - for frame_uid, frame_dict in frames_dict.items(): - frames[int(frame_uid)] = Frame.fromdict(frame_dict, objects, sensors) - - return frames - - # --- asdict() ------------------------------ - - def _streams_asdict(self, sensors: dict[str, Sensor]) -> dict: - return {uid: sensor.asdict()["stream"] for uid, sensor in sensors.items()} - - def _coordinate_systems_asdict(self, sensors: dict[str, Sensor]) -> dict[str, Any] | None: - if len(sensors) == 0: - return None - - coordinate_systems: dict[str, Any] = { - "base": {"type": "local", "parent": "", "children": []} - } - - for uid, sensor in sensors.items(): - coordinate_systems[uid] = sensor.asdict()["coordinate_system"] - coordinate_systems["base"]["children"].append(uid) - - return coordinate_systems - - def _objects_asdict(self, objects: dict[str, Object], calculate_pointers: bool) -> dict: - if calculate_pointers: - return {str(uid): object_.asdict(self.frames) for uid, object_ in objects.items()} - return {str(uid): object_.asdict() for uid, object_ in objects.items()} - - def _frames_asdict(self, frames: dict[int, Frame]) -> dict: - return {str(uid): frame.asdict() for uid, frame in frames.items()} - - def _frame_intervals_asdict(self, frame_intervals: list[FrameInterval]) -> list[dict]: - return [fi.asdict() for fi in frame_intervals] - - -def _clean_dict(input_dict: dict) -> dict: - """Remove all fields from a dict that are None or have a length of 0.""" - empty_keys = [] - for key, value in input_dict.items(): - is_field_empty = value is None or (hasattr(value, "__len__") and len(value) == 0) - - if is_field_empty: - empty_keys.append(key) - - for key in empty_keys: - del input_dict[key] - - return input_dict diff --git a/raillabel/format/seg3d.py b/raillabel/format/seg3d.py index 369976f..e43166b 100644 --- a/raillabel/format/seg3d.py +++ b/raillabel/format/seg3d.py @@ -6,7 +6,6 @@ from dataclasses import dataclass from ._object_annotation import _ObjectAnnotation -from .object import Object @dataclass @@ -37,52 +36,3 @@ class Seg3d(_ObjectAnnotation): point_ids: list[int] OPENLABEL_ID = "vec" - - @classmethod - def fromdict(cls, data_dict: dict, sensors: dict, object: Object) -> Seg3d: - """Generate a Seg3d object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - sensors: dict - Dictionary containing all sensors for the scene. - object: raillabel.format.Object - Object this annotation belongs to. - - Returns - ------- - annotation: Seg3d - Converted annotation. - - """ - return Seg3d( - uid=str(data_dict["uid"]), - point_ids=data_dict["val"], - object=object, - sensor=cls._coordinate_system_fromdict(data_dict, sensors), - attributes=cls._attributes_fromdict(data_dict), - ) - - def asdict(self) -> dict: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - dict_repr = self._annotation_required_fields_asdict() - - dict_repr["val"] = [int(pid) for pid in self.point_ids] - - dict_repr.update(self._annotation_optional_fields_asdict()) - - return dict_repr diff --git a/raillabel/format/sensor.py b/raillabel/format/sensor.py index 6bdf5c9..f922cd1 100644 --- a/raillabel/format/sensor.py +++ b/raillabel/format/sensor.py @@ -5,12 +5,9 @@ from dataclasses import dataclass from enum import Enum -from typing import Any from .intrinsics_pinhole import IntrinsicsPinhole from .intrinsics_radar import IntrinsicsRadar -from .point3d import Point3d -from .quaternion import Quaternion from .transform import Transform @@ -48,124 +45,6 @@ class Sensor: uri: str | None = None description: str | None = None - @classmethod - def fromdict(cls, uid: str, cs_data_dict: dict, stream_data_dict: dict) -> Sensor: - """Generate a Sensor object from a dict. - - Parameters - ---------- - uid: str - Unique identifier of the sensor. - cs_data_dict: dict - RailLabel format dict containing the data about the coordinate system. - stream_data_dict: dict - RailLabel format dict containing the data about the stream. - - Returns - ------- - sensor: raillabel.format.Sensor - Converted Sensor object. - - """ - return Sensor( - uid=uid, - extrinsics=cls._extrinsics_fromdict(cs_data_dict), - intrinsics=cls._intrinsics_fromdict( - stream_data_dict, cls._type_fromdict(stream_data_dict) - ), - type=cls._type_fromdict(stream_data_dict), - uri=stream_data_dict.get("uri"), - description=stream_data_dict.get("description"), - ) - - def asdict(self) -> dict: - """Export self as a dict compatible with the RailLabel schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - """ - return { - "coordinate_system": self._as_coordinate_system_dict(), - "stream": self._as_stream_dict(), - } - - def _as_coordinate_system_dict(self) -> dict[str, Any]: - coordinate_system_repr: dict[str, Any] = {"type": "sensor", "parent": "base"} - - if self.extrinsics is not None: - coordinate_system_repr["pose_wrt_parent"] = self.extrinsics.asdict() - - return coordinate_system_repr - - def _as_stream_dict(self) -> dict[str, Any]: - stream_repr: dict[str, Any] = {} - - if self.type is not None: - stream_repr["type"] = str(self.type.value) - - if self.uri is not None: - stream_repr["uri"] = str(self.uri) - - if self.description is not None: - stream_repr["description"] = str(self.description) - - if isinstance(self.intrinsics, IntrinsicsPinhole): - stream_repr["stream_properties"] = {"intrinsics_pinhole": self.intrinsics.asdict()} - - elif isinstance(self.intrinsics, IntrinsicsRadar): - stream_repr["stream_properties"] = {"intrinsics_radar": self.intrinsics.asdict()} - - return stream_repr - - @classmethod - def _extrinsics_fromdict(cls, data_dict: dict) -> Transform | None: - if "pose_wrt_parent" not in data_dict: - return None - - return Transform( - position=Point3d( - x=data_dict["pose_wrt_parent"]["translation"][0], - y=data_dict["pose_wrt_parent"]["translation"][1], - z=data_dict["pose_wrt_parent"]["translation"][2], - ), - quaternion=Quaternion( - x=data_dict["pose_wrt_parent"]["quaternion"][0], - y=data_dict["pose_wrt_parent"]["quaternion"][1], - z=data_dict["pose_wrt_parent"]["quaternion"][2], - w=data_dict["pose_wrt_parent"]["quaternion"][3], - ), - ) - - @classmethod - def _intrinsics_fromdict( - cls, data_dict: dict, sensor_type: SensorType | None - ) -> IntrinsicsPinhole | IntrinsicsRadar | None: - if "stream_properties" not in data_dict: - return None - - if sensor_type == SensorType.CAMERA: - if "intrinsics_pinhole" in data_dict["stream_properties"]: - return IntrinsicsPinhole.fromdict( - data_dict["stream_properties"]["intrinsics_pinhole"] - ) - - elif ( - sensor_type == SensorType.RADAR and "intrinsics_radar" in data_dict["stream_properties"] - ): - return IntrinsicsRadar.fromdict(data_dict["stream_properties"]["intrinsics_radar"]) - - return None - - @classmethod - def _type_fromdict(cls, data_dict: dict) -> SensorType | None: - if "type" not in data_dict: - return None - - return SensorType(data_dict["type"]) - class SensorType(Enum): """Enumeration representing all possible sensor types.""" diff --git a/raillabel/format/sensor_reference.py b/raillabel/format/sensor_reference.py index fa4d1ca..5255832 100644 --- a/raillabel/format/sensor_reference.py +++ b/raillabel/format/sensor_reference.py @@ -5,7 +5,6 @@ import decimal from dataclasses import dataclass -from typing import Any from .sensor import Sensor @@ -30,53 +29,3 @@ class SensorReference: sensor: Sensor timestamp: decimal.Decimal uri: str | None = None - - @classmethod - def fromdict(cls, data_dict: dict, sensor: Sensor) -> SensorReference: - """Generate a SensorReference object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - sensor: raillabel.format.Sensor - Sensor corresponding to this SensorReference. - - Returns - ------- - sensor_reference: raillabel.format.SensorReference - Converted SensorReference object. - - """ - return SensorReference( - sensor=sensor, - timestamp=cls._timestamp_fromdict(data_dict["stream_properties"]), - uri=data_dict.get("uri"), - ) - - def asdict(self) -> dict[str, Any]: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - dict_repr: dict[str, Any] = { - "stream_properties": {"sync": {"timestamp": str(self.timestamp)}} - } - - if self.uri is not None: - dict_repr["uri"] = self.uri - - return dict_repr - - @classmethod - def _timestamp_fromdict(cls, data_dict: dict) -> decimal.Decimal: - return decimal.Decimal(data_dict["sync"]["timestamp"]) diff --git a/raillabel/format/size2d.py b/raillabel/format/size2d.py index 01df3ed..7ddf07f 100644 --- a/raillabel/format/size2d.py +++ b/raillabel/format/size2d.py @@ -20,22 +20,3 @@ class Size2d: def from_json(cls, json: tuple[int | float, int | float]) -> Size2d: """Construct an instant of this class from RailLabel JSON data.""" return Size2d(x=json[0], y=json[1]) - - @classmethod - def fromdict(cls, data_dict: dict) -> Size2d: - """Generate a Size2d object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - - """ - return Size2d( - x=data_dict[0], - y=data_dict[1], - ) - - def asdict(self) -> list[float]: - """Export self as a dict compatible with the OpenLABEL schema.""" - return [float(self.x), float(self.y)] diff --git a/raillabel/format/size3d.py b/raillabel/format/size3d.py index f98a35b..5da9679 100644 --- a/raillabel/format/size3d.py +++ b/raillabel/format/size3d.py @@ -24,23 +24,3 @@ class Size3d: x: float y: float z: float - - @classmethod - def fromdict(cls, data_dict: dict) -> Size3d: - """Generate a Size3d object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - - """ - return Size3d( - x=data_dict[0], - y=data_dict[1], - z=data_dict[2], - ) - - def asdict(self) -> list[float]: - """Export self as a dict compatible with the OpenLABEL schema.""" - return [float(self.x), float(self.y), float(self.z)] diff --git a/raillabel/format/transform.py b/raillabel/format/transform.py index c8cd55a..68fb971 100644 --- a/raillabel/format/transform.py +++ b/raillabel/format/transform.py @@ -28,37 +28,3 @@ def from_json(cls, json: JSONTransformData) -> Transform: position=Point3d.from_json(json.translation), quaternion=Quaternion.from_json(json.quaternion), ) - - @classmethod - def fromdict(cls, data_dict: dict) -> Transform: - """Generate a Transform object from a dict. - - Parameters - ---------- - data_dict: dict - RailLabel format snippet containing the relevant data. - - """ - return Transform( - position=Point3d.fromdict(data_dict["translation"]), - quaternion=Quaternion.fromdict(data_dict["quaternion"]), - ) - - def asdict(self) -> dict[str, list[float]]: - """Export self as a dict compatible with the OpenLABEL schema. - - Returns - ------- - dict_repr: dict - Dict representation of this class instance. - - Raises - ------ - ValueError - if an attribute can not be converted to the type required by the OpenLabel schema. - - """ - return { - "translation": self.position.asdict(), - "quaternion": self.quaternion.asdict(), - } diff --git a/raillabel/load/load.py b/raillabel/load/load.py index f45105d..b59a4d8 100644 --- a/raillabel/load/load.py +++ b/raillabel/load/load.py @@ -3,13 +3,12 @@ from __future__ import annotations -import json from pathlib import Path -from raillabel.format import Scene +from raillabel.format import Metadata, Scene -def load(path: Path | str) -> Scene: +def load(_path: Path | str) -> Scene: """Load an annotation file of any supported type. Parameters @@ -23,7 +22,4 @@ def load(path: Path | str) -> Scene: Scene with the loaded data. """ - with Path(path).open() as scene_file: - raw_scene = json.load(scene_file) - - return Scene.fromdict(raw_scene) + return Scene(metadata=Metadata("1.0.0")) diff --git a/raillabel/save/save.py b/raillabel/save/save.py index 3adfef5..94714a9 100644 --- a/raillabel/save/save.py +++ b/raillabel/save/save.py @@ -3,13 +3,12 @@ from __future__ import annotations -import json from pathlib import Path from raillabel.format import Scene -def save(scene: Scene, path: Path | str, prettify_json: bool = False) -> None: +def save(_scene: Scene, _path: Path | str, _prettify_json: bool = False) -> None: """Save a raillabel.Scene in a JSON file. Parameters @@ -25,12 +24,3 @@ def save(scene: Scene, path: Path | str, prettify_json: bool = False) -> None: also the file size. Default is False. """ - path = Path(path) - - data = scene.asdict() - - with Path(path).open("w") as save_file: - if prettify_json: - json.dump(data, save_file, indent=4) - else: - json.dump(data, save_file) diff --git a/tests/test_raillabel/format/conftest.py b/tests/test_raillabel/format/conftest.py index bc4a860..f5a7eec 100644 --- a/tests/test_raillabel/format/conftest.py +++ b/tests/test_raillabel/format/conftest.py @@ -1,60 +1,10 @@ # Copyright DB InfraGO AG and contributors # SPDX-License-Identifier: Apache-2.0 - -from .test_attributes import ( - attributes_multiple_types, - attributes_multiple_types_dict, - attributes_single_type, - attributes_single_type_dict, -) -from .test_bbox import bbox, bbox_dict, bbox_train, bbox_train_dict -from .test_cuboid import cuboid, cuboid_dict -from .test_element_data_pointer import ( - element_data_pointer_full, - element_data_pointer_full_dict, - element_data_pointer_minimal, - element_data_pointer_minimal_dict, -) -from .test_frame import frame, frame_dict -from .test_frame_interval import frame_interval, frame_interval_dict -from .test_intrinsics_pinhole import intrinsics_pinhole, intrinsics_pinhole_dict -from .test_intrinsics_radar import intrinsics_radar, intrinsics_radar_dict -from .test_metadata import ( - metadata_full, - metadata_full_dict, - metadata_minimal, - metadata_minimal_dict, -) -from .test_num import num, num_dict -from .test_object import ( - object_person, - object_person_dict, - object_train, - object_train_dict, - objects, - objects_dict, -) -from .test_object_annotation import all_annotations -from .test_object_data import object_data_person_dict, object_data_train_dict -from .test_point2d import point2d, point2d_another, point2d_another_dict, point2d_dict -from .test_point3d import point3d, point3d_another, point3d_another_dict, point3d_dict -from .test_poly2d import poly2d, poly2d_dict -from .test_poly3d import poly3d, poly3d_dict -from .test_quaternion import quaternion, quaternion_dict -from .test_scene import scene, scene_dict -from .test_seg3d import seg3d, seg3d_dict -from .test_sensor import ( - coordinate_systems_dict, - sensor_camera, - sensor_camera_dict, - sensor_lidar, - sensor_lidar_dict, - sensor_radar, - sensor_radar_dict, - sensors, - streams_dict, -) -from .test_sensor_reference import sensor_reference_camera, sensor_reference_camera_dict -from .test_size2d import size2d, size2d_dict -from .test_size3d import size3d, size3d_dict -from .test_transform import transform, transform_dict +from .test_frame_interval import frame_interval, frame_interval_json +from .test_intrinsics_pinhole import intrinsics_pinhole, intrinsics_pinhole_json +from .test_intrinsics_radar import intrinsics_radar, intrinsics_radar_json +from .test_point2d import point2d, point2d_json +from .test_point3d import point3d, point3d_json +from .test_quaternion import quaternion, quaternion_json +from .test_size2d import size2d, size2d_json +from .test_transform import transform, transform_json diff --git a/tests/test_raillabel/format/test_attributes.py b/tests/test_raillabel/format/test_attributes.py deleted file mode 100644 index b72fac8..0000000 --- a/tests/test_raillabel/format/test_attributes.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import _ObjectAnnotation - -# == Fixtures ========================= - - -@pytest.fixture -def attributes_single_type_dict() -> dict: - return { - "text": [ - {"name": "test_text_attr0", "val": "test_text_attr0_val"}, - {"name": "test_text_attr1", "val": "test_text_attr1_val"}, - ] - } - - -@pytest.fixture -def attributes_single_type() -> dict: - return { - "test_text_attr0": "test_text_attr0_val", - "test_text_attr1": "test_text_attr1_val", - } - - -@pytest.fixture -def attributes_multiple_types_dict() -> dict: - return { - "text": [{"name": "text_attr", "val": "text_val"}], - "num": [{"name": "num_attr", "val": 0}], - "boolean": [{"name": "bool_attr", "val": True}], - "vec": [{"name": "vec_attr", "val": [0, 1, 2]}], - } - - -@pytest.fixture -def attributes_multiple_types() -> dict: - return { - "text_attr": "text_val", - "num_attr": 0, - "bool_attr": True, - "vec_attr": [0, 1, 2], - } - - -# == Tests ============================ - - -def test_fromdict__single_type(): - attributes_dict = { - "attributes": { - "text": [ - {"name": "test_text_attr0", "val": "test_text_attr0_val"}, - {"name": "test_text_attr1", "val": "test_text_attr1_val"}, - ] - } - } - - assert _ObjectAnnotation._attributes_fromdict(attributes_dict) == { - "test_text_attr0": "test_text_attr0_val", - "test_text_attr1": "test_text_attr1_val", - } - - -def test_fromdict__multiple_types(): - attributes_dict = { - "attributes": { - "text": [{"name": "text_attr", "val": "text_val"}], - "num": [{"name": "num_attr", "val": 0}], - "boolean": [{"name": "bool_attr", "val": True}], - "vec": [{"name": "vec_attr", "val": [0, 1, 2]}], - } - } - - assert _ObjectAnnotation._attributes_fromdict(attributes_dict) == { - "text_attr": "text_val", - "num_attr": 0, - "bool_attr": True, - "vec_attr": [0, 1, 2], - } - - -def test_asdict__single_type(): - attributes = { - "test_text_attr0": "test_text_attr0_val", - "test_text_attr1": "test_text_attr1_val", - } - - assert _ObjectAnnotation._attributes_asdict(None, attributes) == { - "text": [ - {"name": "test_text_attr0", "val": "test_text_attr0_val"}, - {"name": "test_text_attr1", "val": "test_text_attr1_val"}, - ] - } - - -def test_asdict__multiple_types(): - attributes = { - "text_attr": "text_val", - "num_attr": 0, - "bool_attr": True, - "vec_attr": [0, 1, 2], - } - - assert _ObjectAnnotation._attributes_asdict(None, attributes) == { - "text": [{"name": "text_attr", "val": "text_val"}], - "num": [{"name": "num_attr", "val": 0}], - "boolean": [{"name": "bool_attr", "val": True}], - "vec": [{"name": "vec_attr", "val": [0, 1, 2]}], - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_bbox.py b/tests/test_raillabel/format/test_bbox.py deleted file mode 100644 index 040df09..0000000 --- a/tests/test_raillabel/format/test_bbox.py +++ /dev/null @@ -1,147 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Bbox - -# == Fixtures ========================= - - -@pytest.fixture -def bbox_dict( - sensor_camera, - attributes_multiple_types_dict, - point2d_dict, - size2d_dict, -) -> dict: - return { - "uid": "78f0ad89-2750-4a30-9d66-44c9da73a714", - "name": "rgb_middle__bbox__person", - "val": point2d_dict + size2d_dict, - "coordinate_system": sensor_camera.uid, - "attributes": attributes_multiple_types_dict, - } - - -@pytest.fixture -def bbox( - point2d, - size2d, - sensor_camera, - attributes_multiple_types, - object_person, -) -> dict: - return Bbox( - uid="78f0ad89-2750-4a30-9d66-44c9da73a714", - pos=point2d, - size=size2d, - sensor=sensor_camera, - attributes=attributes_multiple_types, - object=object_person, - ) - - -@pytest.fixture -def bbox_train_dict(sensor_camera, attributes_single_type_dict, point2d_dict, size2d_dict) -> dict: - return { - "uid": "6a7cfdb7-149d-4987-98dd-79d05a8cc8e6", - "name": "rgb_middle__bbox__train", - "val": point2d_dict + size2d_dict, - "coordinate_system": sensor_camera.uid, - "attributes": attributes_single_type_dict, - } - - -@pytest.fixture -def bbox_train( - point2d, - size2d, - sensor_camera, - attributes_single_type, - object_train, -) -> dict: - return Bbox( - uid="6a7cfdb7-149d-4987-98dd-79d05a8cc8e6", - pos=point2d, - size=size2d, - sensor=sensor_camera, - attributes=attributes_single_type, - object=object_train, - ) - - -# == Tests ============================ - - -def test_fromdict( - point2d, - point2d_dict, - size2d, - size2d_dict, - sensor_camera, - sensors, - object_person, - attributes_multiple_types, - attributes_multiple_types_dict, -): - bbox = Bbox.fromdict( - { - "uid": "78f0ad89-2750-4a30-9d66-44c9da73a714", - "name": "rgb_middle__bbox__person", - "val": point2d_dict + size2d_dict, - "coordinate_system": sensor_camera.uid, - "attributes": attributes_multiple_types_dict, - }, - sensors, - object_person, - ) - - assert bbox.uid == "78f0ad89-2750-4a30-9d66-44c9da73a714" - assert bbox.name == "rgb_middle__bbox__person" - assert bbox.pos == point2d - assert bbox.size == size2d - assert bbox.object == object_person - assert bbox.sensor == sensor_camera - assert bbox.attributes == attributes_multiple_types - - -def test_asdict( - point2d, - point2d_dict, - size2d, - size2d_dict, - sensor_camera, - object_person, - attributes_multiple_types, - attributes_multiple_types_dict, -): - bbox = Bbox( - uid="78f0ad89-2750-4a30-9d66-44c9da73a714", - pos=point2d, - size=size2d, - object=object_person, - sensor=sensor_camera, - attributes=attributes_multiple_types, - ) - - assert bbox.asdict() == { - "uid": "78f0ad89-2750-4a30-9d66-44c9da73a714", - "name": "rgb_middle__bbox__person", - "val": point2d_dict + size2d_dict, - "coordinate_system": sensor_camera.uid, - "attributes": attributes_multiple_types_dict, - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_cuboid.py b/tests/test_raillabel/format/test_cuboid.py deleted file mode 100644 index 96af51d..0000000 --- a/tests/test_raillabel/format/test_cuboid.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Cuboid - -# == Fixtures ========================= - - -@pytest.fixture -def cuboid_dict( - sensor_lidar, attributes_multiple_types_dict, point3d_dict, size3d_dict, quaternion_dict -) -> dict: - return { - "uid": "2c6b3de0-86c2-4684-b576-4cfd4f50d6ad", - "name": "lidar__cuboid__person", - "val": point3d_dict + quaternion_dict + size3d_dict, - "coordinate_system": sensor_lidar.uid, - "attributes": attributes_multiple_types_dict, - } - - -@pytest.fixture -def cuboid( - point3d, size3d, quaternion, sensor_lidar, attributes_multiple_types, object_person -) -> dict: - return Cuboid( - uid="2c6b3de0-86c2-4684-b576-4cfd4f50d6ad", - pos=point3d, - quat=quaternion, - size=size3d, - object=object_person, - sensor=sensor_lidar, - attributes=attributes_multiple_types, - ) - - -# == Tests ============================ - - -def test_fromdict( - point3d, - point3d_dict, - size3d, - size3d_dict, - quaternion, - quaternion_dict, - sensor_lidar, - sensors, - object_person, - attributes_multiple_types, - attributes_multiple_types_dict, -): - cuboid = Cuboid.fromdict( - { - "uid": "2c6b3de0-86c2-4684-b576-4cfd4f50d6ad", - "name": "lidar__cuboid__person", - "val": point3d_dict + quaternion_dict + size3d_dict, - "coordinate_system": sensor_lidar.uid, - "attributes": attributes_multiple_types_dict, - }, - sensors, - object_person, - ) - - assert cuboid.uid == "2c6b3de0-86c2-4684-b576-4cfd4f50d6ad" - assert cuboid.name == "lidar__cuboid__person" - assert cuboid.pos == point3d - assert cuboid.quat == quaternion - assert cuboid.size == size3d - assert cuboid.object == object_person - assert cuboid.sensor == sensor_lidar - assert cuboid.attributes == attributes_multiple_types - - -def test_asdict( - point3d, - point3d_dict, - size3d, - size3d_dict, - quaternion, - quaternion_dict, - sensor_lidar, - object_person, - attributes_multiple_types, - attributes_multiple_types_dict, -): - cuboid = Cuboid( - uid="2c6b3de0-86c2-4684-b576-4cfd4f50d6ad", - pos=point3d, - quat=quaternion, - size=size3d, - object=object_person, - sensor=sensor_lidar, - attributes=attributes_multiple_types, - ) - - assert cuboid.asdict() == { - "uid": "2c6b3de0-86c2-4684-b576-4cfd4f50d6ad", - "name": "lidar__cuboid__person", - "val": point3d_dict + quaternion_dict + size3d_dict, - "coordinate_system": sensor_lidar.uid, - "attributes": attributes_multiple_types_dict, - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_element_data_pointer.py b/tests/test_raillabel/format/test_element_data_pointer.py deleted file mode 100644 index 1611ea6..0000000 --- a/tests/test_raillabel/format/test_element_data_pointer.py +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format._attribute_type import AttributeType -from raillabel.format import ElementDataPointer - -# == Fixtures ========================= - - -@pytest.fixture -def element_data_pointer_minimal_dict() -> dict: - return { - "type": "bbox", - "frame_intervals": [], - "attribute_pointers": {}, - } - - -@pytest.fixture -def element_data_pointer_minimal(): - return ElementDataPointer( - uid="rgb_middle__bbox__person", frame_intervals=[], attribute_pointers={} - ) - - -@pytest.fixture -def element_data_pointer_full_dict(frame_interval_dict) -> dict: - return { - "type": "bbox", - "frame_intervals": [frame_interval_dict], - "attribute_pointers": { - "text_attr": "text", - "num_attr": "num", - "bool_attr": "boolean", - "vec_attr": "vec", - }, - } - - -@pytest.fixture -def element_data_pointer_full(sensor_camera, object_person, frame_interval): - return ElementDataPointer( - uid="rgb_middle__bbox__person", - frame_intervals=[frame_interval], - attribute_pointers={ - "text_attr": AttributeType.TEXT, - "num_attr": AttributeType.NUM, - "bool_attr": AttributeType.BOOLEAN, - "vec_attr": AttributeType.VEC, - }, - ) - - -# == Tests ============================ - - -def test_asdict_minimal(sensor_camera, object_person): - element_data_pointer = ElementDataPointer( - uid="rgb_middle__bbox__person", frame_intervals=[], attribute_pointers={} - ) - - assert element_data_pointer.asdict() == { - "type": "bbox", - "frame_intervals": [], - "attribute_pointers": {}, - } - - -def test_asdict_full(sensor_camera, object_person, frame_interval, frame_interval_dict): - element_data_pointer = ElementDataPointer( - uid="rgb_middle__bbox__person", - frame_intervals=[frame_interval], - attribute_pointers={ - "text_attr": AttributeType.TEXT, - "num_attr": AttributeType.NUM, - "bool_attr": AttributeType.BOOLEAN, - "vec_attr": AttributeType.VEC, - }, - ) - - assert element_data_pointer.asdict() == { - "type": "bbox", - "frame_intervals": [frame_interval_dict], - "attribute_pointers": { - "text_attr": "text", - "num_attr": "num", - "bool_attr": "boolean", - "vec_attr": "vec", - }, - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_frame.py b/tests/test_raillabel/format/test_frame.py deleted file mode 100644 index c644794..0000000 --- a/tests/test_raillabel/format/test_frame.py +++ /dev/null @@ -1,168 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from decimal import Decimal -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Frame - -# == Fixtures ========================= - - -@pytest.fixture -def frame_dict( - sensor_reference_camera_dict, - num_dict, - object_person, - object_data_person_dict, - object_train, - object_data_train_dict, -) -> dict: - return { - "frame_properties": { - "timestamp": "1632321743.100000072", - "streams": {"rgb_middle": sensor_reference_camera_dict}, - "frame_data": {"num": [num_dict]}, - }, - "objects": { - object_person.uid: object_data_person_dict, - object_train.uid: object_data_train_dict, - }, - } - - -@pytest.fixture -def frame(sensor_reference_camera, num, all_annotations) -> dict: - return Frame( - timestamp=Decimal("1632321743.100000072"), - sensors={sensor_reference_camera.sensor.uid: sensor_reference_camera}, - frame_data={num.name: num}, - annotations=all_annotations, - ) - - -# == Tests ============================ - - -def test_fromdict_sensors(sensor_reference_camera_dict, sensor_reference_camera, sensor_camera): - frame = Frame.fromdict( - data_dict={ - "frame_properties": { - "timestamp": "1632321743.100000072", - "streams": {"rgb_middle": sensor_reference_camera_dict}, - } - }, - sensors={sensor_camera.uid: sensor_camera}, - objects={}, - ) - - assert frame.timestamp == Decimal("1632321743.100000072") - assert frame.sensors == {sensor_reference_camera.sensor.uid: sensor_reference_camera} - - -def test_fromdict_frame_data(num, num_dict, sensor_camera): - frame = Frame.fromdict( - data_dict={"frame_properties": {"frame_data": {"num": [num_dict]}}}, - sensors={sensor_camera.uid: sensor_camera}, - objects={}, - ) - - assert frame.frame_data == {num.name: num} - - -def test_fromdict_annotations( - object_data_person_dict, - object_person, - object_data_train_dict, - object_train, - sensors, - all_annotations, -): - frame = Frame.fromdict( - data_dict={ - "objects": { - object_person.uid: object_data_person_dict, - object_train.uid: object_data_train_dict, - } - }, - sensors=sensors, - objects={ - object_person.uid: object_person, - object_train.uid: object_train, - }, - ) - - assert frame.annotations == all_annotations - - -def test_asdict_sensors( - sensor_reference_camera_dict, - sensor_reference_camera, -): - frame = Frame( - timestamp=Decimal("1632321743.100000072"), - sensors={sensor_reference_camera.sensor.uid: sensor_reference_camera}, - ) - - assert frame.asdict() == { - "frame_properties": { - "timestamp": "1632321743.100000072", - "streams": {"rgb_middle": sensor_reference_camera_dict}, - } - } - - -def test_asdict_frame_data(num, num_dict): - frame = Frame(frame_data={num.name: num}) - - assert frame.asdict() == {"frame_properties": {"frame_data": {"num": [num_dict]}}} - - -def test_asdict_object_data( - object_data_person_dict, object_person, object_data_train_dict, object_train, all_annotations -): - frame = Frame(annotations=all_annotations) - - assert frame.asdict() == { - "objects": { - object_person.uid: object_data_person_dict, - object_train.uid: object_data_train_dict, - } - } - - -def test_object_data(object_person, object_train, bbox, cuboid, poly2d, poly3d, seg3d, bbox_train): - frame = Frame( - annotations={ - bbox.uid: bbox, - poly2d.uid: poly2d, - cuboid.uid: cuboid, - poly3d.uid: poly3d, - seg3d.uid: seg3d, - bbox_train.uid: bbox_train, - }, - ) - - assert frame.object_data == { - object_person.uid: { - bbox.uid: bbox, - poly2d.uid: poly2d, - cuboid.uid: cuboid, - poly3d.uid: poly3d, - seg3d.uid: seg3d, - }, - object_train.uid: {bbox_train.uid: bbox_train}, - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-vv"]) diff --git a/tests/test_raillabel/format/test_frame_interval.py b/tests/test_raillabel/format/test_frame_interval.py index 86ad148..c55b9cd 100644 --- a/tests/test_raillabel/format/test_frame_interval.py +++ b/tests/test_raillabel/format/test_frame_interval.py @@ -11,11 +11,6 @@ # == Fixtures ========================= -@pytest.fixture -def frame_interval_dict() -> dict: - return {"frame_start": 12, "frame_end": 16} - - @pytest.fixture def frame_interval_json() -> JSONFrameInterval: return JSONFrameInterval(frame_start=12, frame_end=16) @@ -37,30 +32,6 @@ def test_from_json(frame_interval, frame_interval_json): assert actual == frame_interval -def test_fromdict(): - frame_interval = FrameInterval.fromdict( - { - "frame_start": 12, - "frame_end": 16, - } - ) - - assert frame_interval.start == 12 - assert frame_interval.end == 16 - - -def test_asdict(): - frame_interval = FrameInterval( - start=12, - end=16, - ) - - assert frame_interval.asdict() == { - "frame_start": 12, - "frame_end": 16, - } - - def test_len(): frame_interval = FrameInterval( start=12, diff --git a/tests/test_raillabel/format/test_intrinsics_pinhole.py b/tests/test_raillabel/format/test_intrinsics_pinhole.py index fb41360..852ce2b 100644 --- a/tests/test_raillabel/format/test_intrinsics_pinhole.py +++ b/tests/test_raillabel/format/test_intrinsics_pinhole.py @@ -11,16 +11,6 @@ # == Fixtures ========================= -@pytest.fixture -def intrinsics_pinhole_dict() -> dict: - return { - "camera_matrix": [0.48, 0, 0.81, 0, 0, 0.16, 0.83, 0, 0, 0, 1, 0], - "distortion_coeffs": [0.49, 0.69, 0.31, 0.81, 0.99], - "width_px": 2464, - "height_px": 1600, - } - - @pytest.fixture def intrinsics_pinhole_json() -> dict: return JSONIntrinsicsPinhole( @@ -49,37 +39,5 @@ def test_from_json(intrinsics_pinhole, intrinsics_pinhole_json): assert actual == intrinsics_pinhole -def test_fromdict(): - intrinsics_pinhole = IntrinsicsPinhole.fromdict( - { - "camera_matrix": [0.48, 0, 0.81, 0, 0, 0.16, 0.83, 0, 0, 0, 1, 0], - "distortion_coeffs": [0.49, 0.69, 0.31, 0.81, 0.99], - "width_px": 2464, - "height_px": 1600, - } - ) - - assert intrinsics_pinhole.camera_matrix == (0.48, 0, 0.81, 0, 0, 0.16, 0.83, 0, 0, 0, 1, 0) - assert intrinsics_pinhole.distortion == (0.49, 0.69, 0.31, 0.81, 0.99) - assert intrinsics_pinhole.width_px == 2464 - assert intrinsics_pinhole.height_px == 1600 - - -def test_asdict(): - intrinsics_pinhole = IntrinsicsPinhole( - camera_matrix=(0.48, 0, 0.81, 0, 0, 0.16, 0.83, 0, 0, 0, 1, 0), - distortion=(0.49, 0.69, 0.31, 0.81, 0.99), - width_px=2464, - height_px=1600, - ) - - assert intrinsics_pinhole.asdict() == { - "camera_matrix": [0.48, 0, 0.81, 0, 0, 0.16, 0.83, 0, 0, 0, 1, 0], - "distortion_coeffs": [0.49, 0.69, 0.31, 0.81, 0.99], - "width_px": 2464, - "height_px": 1600, - } - - if __name__ == "__main__": pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_intrinsics_radar.py b/tests/test_raillabel/format/test_intrinsics_radar.py index d796a15..ed3a8e1 100644 --- a/tests/test_raillabel/format/test_intrinsics_radar.py +++ b/tests/test_raillabel/format/test_intrinsics_radar.py @@ -11,15 +11,6 @@ # == Fixtures ========================= -@pytest.fixture -def intrinsics_radar_dict() -> dict: - return { - "resolution_px_per_m": 2.856, - "width_px": 2856, - "height_px": 1428, - } - - @pytest.fixture def intrinsics_radar_json() -> dict: return JSONIntrinsicsRadar( @@ -46,33 +37,5 @@ def test_from_json(intrinsics_radar, intrinsics_radar_json): assert actual == intrinsics_radar -def test_fromdict(): - intrinsics_radar = IntrinsicsRadar.fromdict( - { - "resolution_px_per_m": 2.856, - "width_px": 2856, - "height_px": 1428, - } - ) - - assert intrinsics_radar.resolution_px_per_m == 2.856 - assert intrinsics_radar.width_px == 2856 - assert intrinsics_radar.height_px == 1428 - - -def test_asdict(): - intrinsics_radar = IntrinsicsRadar( - resolution_px_per_m=2.856, - width_px=2856, - height_px=1428, - ) - - assert intrinsics_radar.asdict() == { - "resolution_px_per_m": 2.856, - "width_px": 2856, - "height_px": 1428, - } - - if __name__ == "__main__": pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_metadata.py b/tests/test_raillabel/format/test_metadata.py deleted file mode 100644 index 5634297..0000000 --- a/tests/test_raillabel/format/test_metadata.py +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Metadata - -# == Fixtures ========================= - - -@pytest.fixture -def metadata_minimal_dict() -> dict: - return {"schema_version": "1.0.0"} - - -@pytest.fixture -def metadata_full_dict() -> dict: - return { - "schema_version": "1.0.0", - "annotator": "test_annotator", - "subschema_version": "2.1.0", - "comment": "test_comment", - "name": "test_project", - "tagged_file": "test_folder", - } - - -@pytest.fixture -def metadata_minimal() -> dict: - return Metadata(schema_version="1.0.0") - - -@pytest.fixture -def metadata_full() -> dict: - return Metadata( - schema_version="1.0.0", - annotator="test_annotator", - subschema_version="2.1.0", - comment="test_comment", - name="test_project", - tagged_file="test_folder", - ) - - -# == Tests ============================ - - -def test_fromdict_minimal(): - metadata = Metadata.fromdict( - {"schema_version": "1.0.0"}, - ) - - assert metadata.schema_version == "1.0.0" - assert metadata.annotator is None - - -def test_fromdict_full(): - metadata = Metadata.fromdict( - { - "schema_version": "1.0.0", - "annotator": "test_annotator", - "subschema_version": "2.1.0", - "comment": "test_comment", - "name": "test_project", - "tagged_file": "test_folder", - }, - "2.1.1", - ) - - assert metadata.annotator == "test_annotator" - assert metadata.schema_version == "1.0.0" - assert metadata.comment == "test_comment" - assert metadata.name == "test_project" - assert metadata.subschema_version == "2.1.1" - assert metadata.tagged_file == "test_folder" - - -def test_fromdict_additional_arg_valid(): - metadata = Metadata.fromdict({"schema_version": "1.0.0", "additional_argument": "Some Value"}) - - assert metadata.schema_version == "1.0.0" - assert metadata.additional_argument == "Some Value" - - -def test_asdict_minimal(): - metadata_dict = Metadata(schema_version="1.0.0").asdict() - - assert metadata_dict == {"schema_version": "1.0.0"} - - -def test_asdict_full(): - metadata_dict = Metadata( - annotator="test_annotator", - schema_version="1.0.0", - comment="test_comment", - name="test_project", - subschema_version="2.1.0", - tagged_file="test_folder", - ).asdict() - - assert metadata_dict == { - "schema_version": "1.0.0", - "annotator": "test_annotator", - "subschema_version": "2.1.0", - "comment": "test_comment", - "name": "test_project", - "tagged_file": "test_folder", - } - - -def test_fromdict_additional_arg(): - metadata = Metadata(schema_version="1.0.0") - - metadata.additional_argument = "Some Value" - - assert metadata.asdict() == {"schema_version": "1.0.0", "additional_argument": "Some Value"} - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_num.py b/tests/test_raillabel/format/test_num.py deleted file mode 100644 index 7c3d0c1..0000000 --- a/tests/test_raillabel/format/test_num.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Num - -# == Fixtures ========================= - - -@pytest.fixture -def num_dict(sensor_camera) -> dict: - return { - "uid": "4e86c449-3B19-410c-aa64-603d46da3b26", - "name": "some_number", - "val": 24, - "coordinate_system": sensor_camera.uid, - } - - -@pytest.fixture -def num(sensor_camera) -> dict: - return Num( - uid="4e86c449-3B19-410c-aa64-603d46da3b26", - name="some_number", - val=24, - sensor=sensor_camera, - ) - - -# == Tests ============================ - - -def test_fromdict(sensor_camera): - num = Num.fromdict( - { - "uid": "4e86c449-3B19-410c-aa64-603d46da3b26", - "name": "some_number", - "val": 24, - "coordinate_system": sensor_camera.uid, - }, - {sensor_camera.uid: sensor_camera}, - ) - - assert num.uid == "4e86c449-3B19-410c-aa64-603d46da3b26" - assert num.name == "some_number" - assert num.val == 24 - assert num.sensor == sensor_camera - - -def test_asdict(sensor_camera): - num = Num( - uid="4e86c449-3B19-410c-aa64-603d46da3b26", - name="some_number", - val=24, - sensor=sensor_camera, - ) - - assert num.asdict() == { - "uid": "4e86c449-3B19-410c-aa64-603d46da3b26", - "name": "some_number", - "val": 24, - "coordinate_system": sensor_camera.uid, - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_object.py b/tests/test_raillabel/format/test_object.py deleted file mode 100644 index 482f49a..0000000 --- a/tests/test_raillabel/format/test_object.py +++ /dev/null @@ -1,423 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import random -import sys -import typing as t -from pathlib import Path -from uuid import uuid4 - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format._attribute_type import AttributeType -from raillabel.format import ( - Bbox, - Cuboid, - Frame, - FrameInterval, - Object, - Point2d, - Point3d, - Quaternion, - Sensor, - Size2d, - Size3d, -) - -# == Fixtures ========================= - - -@pytest.fixture -def objects_dict(object_person_dict, object_train_dict) -> dict: - return { - object_person_dict["object_uid"]: object_person_dict["data_dict"], - object_train_dict["object_uid"]: object_train_dict["data_dict"], - } - - -@pytest.fixture -def objects(object_person, object_train) -> dict[str, Object]: - return { - object_person.uid: object_person, - object_train.uid: object_train, - } - - -@pytest.fixture -def object_person_dict() -> dict: - return { - "object_uid": "b40ba3ad-0327-46ff-9c28-2506cfd6d934", - "data_dict": { - "name": "person_0000", - "type": "person", - }, - } - - -@pytest.fixture -def object_person() -> dict: - return Object( - uid="b40ba3ad-0327-46ff-9c28-2506cfd6d934", - name="person_0000", - type="person", - ) - - -@pytest.fixture -def object_train_dict() -> dict: - return { - "object_uid": "d51a19be-8bc2-4a82-b66a-03c8de95b0cf", - "data_dict": { - "name": "train_0000", - "type": "train", - }, - } - - -@pytest.fixture -def object_train() -> dict: - return Object( - uid="d51a19be-8bc2-4a82-b66a-03c8de95b0cf", - name="train_0000", - type="train", - ) - - -# == Tests ============================ - - -def test_fromdict(): - object = Object.fromdict( - object_uid="b40ba3ad-0327-46ff-9c28-2506cfd6d934", - data_dict={ - "name": "person_0000", - "type": "person", - }, - ) - - assert object.uid == "b40ba3ad-0327-46ff-9c28-2506cfd6d934" - assert object.name == "person_0000" - assert object.type == "person" - - -def test_asdict_no_frames(): - object = Object( - uid="b40ba3ad-0327-46ff-9c28-2506cfd6d934", - name="person_0000", - type="person", - ) - - assert object.asdict() == { - "name": "person_0000", - "type": "person", - } - - -def test_asdict_with_frames(): - object = Object( - uid="b40ba3ad-0327-46ff-9c28-2506cfd6d934", - name="person_0000", - type="person", - ) - - frames = { - 0: build_frame(0, {object: [build_annotation("rgb_middle__bbox__person", object)]}), - } - - object_dict = object.asdict(frames) - - assert "frame_intervals" in object_dict - assert "object_data_pointers" in object_dict - assert "rgb_middle__bbox__person" in object_dict["object_data_pointers"] - - -def test_frame_intervals(): - object = Object( - uid="b40ba3ad-0327-46ff-9c28-2506cfd6d934", - name="person_0000", - type="person", - ) - - frames = { - 0: build_frame(0, {object: [build_annotation("rgb_middle__bbox__person", object)]}), - 1: build_frame(1, {object: [build_annotation("rgb_middle__bbox__person", object)]}), - 2: build_frame(2, {}), - 3: build_frame(3, {object: [build_annotation("rgb_middle__bbox__person", object)]}), - } - - assert object.frame_intervals(frames) == [ - FrameInterval(0, 1), - FrameInterval(3, 3), - ] - - -def test_object_data_pointers__sensor(): - object = build_object("person") - - frames = { - 0: build_frame( - 0, - { - object: [ - build_annotation("rgb_middle__bbox__person", object), - build_annotation("lidar__bbox__person", object), - ] - }, - ) - } - - object_data_pointers = object.object_data_pointers(frames) - - assert set(object_data_pointers.keys()) == set( - ["rgb_middle__bbox__person", "lidar__bbox__person"] - ) - - -def test_object_data_pointers__annotation_type(): - object = build_object("person") - - frames = { - 0: build_frame( - 0, - { - object: [ - build_annotation("rgb_middle__bbox__person", object), - build_annotation("rgb_middle__cuboid__person", object), - ] - }, - ) - } - - object_data_pointers = object.object_data_pointers(frames) - - assert set(object_data_pointers.keys()) == set( - ["rgb_middle__bbox__person", "rgb_middle__cuboid__person"] - ) - - -def test_object_data_pointers__one_frame_interval(): - object = build_object("person") - - frames = { - 0: build_frame(0, {object: [build_annotation("rgb_middle__bbox__person", object)]}), - 1: build_frame(1, {object: [build_annotation("rgb_middle__bbox__person", object)]}), - } - - object_data_pointers = object.object_data_pointers(frames) - - assert len(object_data_pointers) == 1 - assert object_data_pointers["rgb_middle__bbox__person"].frame_intervals == [FrameInterval(0, 1)] - - -def test_object_data_pointers__two_frame_intervals(): - object = build_object("person") - - frames = { - 0: build_frame(0, {object: [build_annotation("rgb_middle__bbox__person", object)]}), - 1: build_frame(1, {object: [build_annotation("rgb_middle__bbox__person", object)]}), - 8: build_frame(8, {object: [build_annotation("rgb_middle__bbox__person", object)]}), - } - - object_data_pointers = object.object_data_pointers(frames) - - assert len(object_data_pointers) == 1 - assert object_data_pointers["rgb_middle__bbox__person"].frame_intervals == [ - FrameInterval(0, 1), - FrameInterval(8, 8), - ] - - -def test_object_data_pointers__attributes_one_annotation(): - object = build_object("person") - - frames = { - 0: build_frame( - 0, - { - object: [ - build_annotation( - name="rgb_middle__bbox__person", - object=object, - attributes={ - "text_attr": "some value", - "num_attr": 0, - "bool_attr": True, - "vec_attr": [0, 1], - }, - ), - ] - }, - ) - } - - object_data_pointers = object.object_data_pointers(frames) - - assert object_data_pointers["rgb_middle__bbox__person"].attribute_pointers == { - "text_attr": AttributeType.TEXT, - "num_attr": AttributeType.NUM, - "bool_attr": AttributeType.BOOLEAN, - "vec_attr": AttributeType.VEC, - } - - -def test_object_data_pointers__attributes_multiple_annotations_with_differing_attributes(): - object = build_object("person") - - frames = { - 0: build_frame( - 0, - { - object: [ - build_annotation( - name="rgb_middle__bbox__person", - object=object, - attributes={ - "text_attr": "some value", - "num_attr": 0, - }, - ), - build_annotation( - name="rgb_middle__bbox__person", - object=object, - attributes={ - "bool_attr": True, - "vec_attr": [0, 1], - }, - ), - ] - }, - ) - } - - object_data_pointers = object.object_data_pointers(frames) - - assert object_data_pointers["rgb_middle__bbox__person"].attribute_pointers == { - "text_attr": AttributeType.TEXT, - "num_attr": AttributeType.NUM, - "bool_attr": AttributeType.BOOLEAN, - "vec_attr": AttributeType.VEC, - } - - -def test_object_data_pointers__multiple_objects_of_differing_type(): - object_person = build_object("person") - object_train = build_object("train") - - frames = { - 0: build_frame( - 0, - { - object_person: [ - build_annotation("lidar__bbox__person", object_person), - ] - }, - ), - 1: build_frame( - 1, - { - object_train: [ - build_annotation("lidar__bbox__train", object_train), - ] - }, - ), - } - - person_object_data_pointers = object_person.object_data_pointers(frames) - assert len(person_object_data_pointers) == 1 - assert person_object_data_pointers["lidar__bbox__person"].frame_intervals == [ - FrameInterval(0, 0) - ] - - train_object_data_pointers = object_train.object_data_pointers(frames) - assert len(train_object_data_pointers) == 1 - assert train_object_data_pointers["lidar__bbox__train"].frame_intervals == [FrameInterval(1, 1)] - - -def test_object_data_pointers__multiple_objects_of_same_type(): - object1 = build_object("person") - object2 = build_object("person") - - frames = { - 0: build_frame( - 0, - { - object1: [ - build_annotation("lidar__bbox__person", object1), - ] - }, - ), - 1: build_frame( - 1, - { - object2: [ - build_annotation("lidar__bbox__person", object2), - ] - }, - ), - } - - object1_data_pointers = object1.object_data_pointers(frames) - assert len(object1_data_pointers) == 1 - assert object1_data_pointers["lidar__bbox__person"].frame_intervals == [FrameInterval(0, 0)] - - object2_data_pointers = object2.object_data_pointers(frames) - assert len(object2_data_pointers) == 1 - assert object2_data_pointers["lidar__bbox__person"].frame_intervals == [FrameInterval(1, 1)] - - -# == Helpers ========================== - - -def build_annotation(name: str, object: Object, attributes: dict = {}) -> t.Union[Bbox, Cuboid]: - sensor_uid, ann_type, object_type = tuple(name.split("__")) - - sensor = Sensor(sensor_uid) - - if ann_type == "bbox": - return Bbox( - uid=str(uuid4()), - object=object, - attributes=attributes, - sensor=sensor, - pos=Point2d(50, 100), - size=Size2d(30, 30), - ) - - elif ann_type == "cuboid": - return Cuboid( - uid=str(uuid4()), - object=object, - attributes=attributes, - sensor=sensor, - pos=Point3d(50, 100, 20), - size=Size3d(30, 30, 30), - quat=Quaternion(0, 0, 0, 1), - ) - - else: - raise ValueError() - - -def build_frame(uid: int, raw_object_data: dict[Object, list[t.Union[Bbox, Cuboid]]]) -> Frame: - annotations = {} - for object_data in raw_object_data.values(): - for annotation in object_data: - annotations[annotation.uid] = annotation - - return Frame(annotations=annotations) - - -def build_object(type: str) -> Object: - return Object( - uid=str(uuid4()), name=f"{type}_{str(random.randint(0, 9999)).zfill(4)}", type=type - ) - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_object_annotation.py b/tests/test_raillabel/format/test_object_annotation.py deleted file mode 100644 index 143ca47..0000000 --- a/tests/test_raillabel/format/test_object_annotation.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -import raillabel -from raillabel.format import annotation_classes - -# == Fixtures ========================= - - -@pytest.fixture -def all_annotations( - bbox, - bbox_train, - cuboid, - poly2d, - poly3d, - seg3d, -): - return { - bbox.uid: bbox, - bbox_train.uid: bbox_train, - cuboid.uid: cuboid, - poly2d.uid: poly2d, - poly3d.uid: poly3d, - seg3d.uid: seg3d, - } - - -# == Tests ============================ - - -def test_annotation_classes(): - assert annotation_classes() == { - "bbox": raillabel.format.Bbox, - "poly2d": raillabel.format.Poly2d, - "cuboid": raillabel.format.Cuboid, - "poly3d": raillabel.format.Poly3d, - "vec": raillabel.format.Seg3d, - } - - -# Executes the test if the file is called -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_object_data.py b/tests/test_raillabel/format/test_object_data.py deleted file mode 100644 index 244f930..0000000 --- a/tests/test_raillabel/format/test_object_data.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -# == Fixtures ========================= - - -@pytest.fixture -def object_data_person_dict(bbox_dict, poly2d_dict, cuboid_dict, poly3d_dict, seg3d_dict) -> dict: - return { - "object_data": { - "bbox": [bbox_dict], - "poly2d": [poly2d_dict], - "cuboid": [cuboid_dict], - "poly3d": [poly3d_dict], - "vec": [seg3d_dict], - } - } - - -@pytest.fixture -def object_data_train_dict(bbox_train_dict) -> dict: - return { - "object_data": { - "bbox": [bbox_train_dict], - } - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_point2d.py b/tests/test_raillabel/format/test_point2d.py index b72ee4c..8950e62 100644 --- a/tests/test_raillabel/format/test_point2d.py +++ b/tests/test_raillabel/format/test_point2d.py @@ -11,7 +11,7 @@ @pytest.fixture -def point2d_dict() -> dict: +def point2d_json() -> dict: return [1.5, 222] @@ -20,39 +20,13 @@ def point2d() -> dict: return Point2d(1.5, 222) -@pytest.fixture -def point2d_another_dict() -> dict: - return [19, 84] - - -@pytest.fixture -def point2d_another() -> dict: - return Point2d(19, 84) - - # == Tests ============================ -def test_from_json(point2d, point2d_dict): - actual = Point2d.from_json(point2d_dict) +def test_from_json(point2d, point2d_json): + actual = Point2d.from_json(point2d_json) assert actual == point2d -def test_fromdict(): - point2d = Point2d.fromdict([1.5, 222]) - - assert point2d.x == 1.5 - assert point2d.y == 222 - - -def test_asdict(): - point2d = Point2d( - x=1.5, - y=222, - ) - - assert point2d.asdict() == [1.5, 222] - - if __name__ == "__main__": pytest.main([__file__, "-v"]) diff --git a/tests/test_raillabel/format/test_point3d.py b/tests/test_raillabel/format/test_point3d.py index 238f226..2d73b01 100644 --- a/tests/test_raillabel/format/test_point3d.py +++ b/tests/test_raillabel/format/test_point3d.py @@ -3,21 +3,15 @@ from __future__ import annotations -import os -import sys -from pathlib import Path - import pytest -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - from raillabel.format import Point3d # == Fixtures ========================= @pytest.fixture -def point3d_dict() -> dict: +def point3d_json() -> dict: return [419, 3.14, 0] @@ -26,42 +20,13 @@ def point3d() -> dict: return Point3d(419, 3.14, 0) -@pytest.fixture -def point3d_another_dict() -> dict: - return [9, 8, 7] - - -@pytest.fixture -def point3d_another() -> dict: - return Point3d(9, 8, 7) - - # == Tests ============================ -def test_from_json(point3d, point3d_dict): - actual = Point3d.from_json(point3d_dict) +def test_from_json(point3d, point3d_json): + actual = Point3d.from_json(point3d_json) assert actual == point3d -def test_fromdict(): - point3d = Point3d.fromdict([419, 3.14, 0]) - - assert point3d.x == 419 - assert point3d.y == 3.14 - assert point3d.z == 0 - - -def test_asdict(): - point3d = Point3d( - x=419, - y=3.14, - z=0, - ) - - assert point3d.asdict() == [419, 3.14, 0] - - if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) + pytest.main([__file__, "-v"]) diff --git a/tests/test_raillabel/format/test_poly2d.py b/tests/test_raillabel/format/test_poly2d.py deleted file mode 100644 index 24baa98..0000000 --- a/tests/test_raillabel/format/test_poly2d.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Poly2d - -# == Fixtures ========================= - - -@pytest.fixture -def poly2d_dict( - sensor_camera, attributes_multiple_types_dict, point2d_dict, point2d_another_dict -) -> dict: - return { - "uid": "d73b5988-767B-47ef-979c-022af60c6ab2", - "name": "rgb_middle__poly2d__person", - "val": point2d_dict + point2d_another_dict, - "coordinate_system": sensor_camera.uid, - "attributes": attributes_multiple_types_dict, - "closed": True, - "mode": "MODE_POLY2D_ABSOLUTE", - } - - -@pytest.fixture -def poly2d( - point2d, point2d_another, sensor_camera, attributes_multiple_types, object_person -) -> dict: - return Poly2d( - uid="d73b5988-767B-47ef-979c-022af60c6ab2", - points=[point2d, point2d_another], - object=object_person, - sensor=sensor_camera, - attributes=attributes_multiple_types, - closed=True, - mode="MODE_POLY2D_ABSOLUTE", - ) - - -# == Tests ============================ - - -def test_fromdict( - point2d, - point2d_dict, - point2d_another, - point2d_another_dict, - sensor_camera, - sensors, - object_person, - attributes_multiple_types, - attributes_multiple_types_dict, -): - poly2d = Poly2d.fromdict( - { - "uid": "d73b5988-767B-47ef-979c-022af60c6ab2", - "name": "rgb_middle__poly2d__person", - "val": point2d_dict + point2d_another_dict, - "coordinate_system": sensor_camera.uid, - "attributes": attributes_multiple_types_dict, - "closed": True, - "mode": "MODE_POLY2D_ABSOLUTE", - }, - sensors, - object_person, - ) - - assert poly2d.uid == "d73b5988-767B-47ef-979c-022af60c6ab2" - assert poly2d.name == "rgb_middle__poly2d__person" - assert poly2d.points == [point2d, point2d_another] - assert poly2d.object == object_person - assert poly2d.sensor == sensor_camera - assert poly2d.attributes == attributes_multiple_types - assert poly2d.closed == True - assert poly2d.mode == "MODE_POLY2D_ABSOLUTE" - - -def test_asdict( - point2d, - point2d_dict, - point2d_another, - point2d_another_dict, - sensor_camera, - object_person, - attributes_multiple_types, - attributes_multiple_types_dict, -): - poly2d = Poly2d( - uid="d73b5988-767B-47ef-979c-022af60c6ab2", - points=[point2d, point2d_another], - object=object_person, - sensor=sensor_camera, - attributes=attributes_multiple_types, - closed=True, - mode="MODE_POLY2D_ABSOLUTE", - ) - - assert poly2d.asdict() == { - "uid": "d73b5988-767B-47ef-979c-022af60c6ab2", - "name": "rgb_middle__poly2d__person", - "val": point2d_dict + point2d_another_dict, - "coordinate_system": sensor_camera.uid, - "attributes": attributes_multiple_types_dict, - "closed": True, - "mode": "MODE_POLY2D_ABSOLUTE", - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_poly3d.py b/tests/test_raillabel/format/test_poly3d.py deleted file mode 100644 index 87d8dec..0000000 --- a/tests/test_raillabel/format/test_poly3d.py +++ /dev/null @@ -1,112 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Poly3d - -# == Fixtures ========================= - - -@pytest.fixture -def poly3d_dict( - sensor_lidar, attributes_multiple_types_dict, point3d_dict, point3d_another_dict -) -> dict: - return { - "uid": "9a9a30f5-D334-4f11-aa3f-c3c83f2935eb", - "name": "lidar__poly3d__person", - "val": point3d_dict + point3d_another_dict, - "coordinate_system": sensor_lidar.uid, - "attributes": attributes_multiple_types_dict, - "closed": True, - } - - -@pytest.fixture -def poly3d(point3d, point3d_another, sensor_lidar, object_person, attributes_multiple_types) -> dict: - return Poly3d( - uid="9a9a30f5-D334-4f11-aa3f-c3c83f2935eb", - points=[point3d, point3d_another], - object=object_person, - sensor=sensor_lidar, - attributes=attributes_multiple_types, - closed=True, - ) - - -# == Tests ============================ - - -def test_fromdict( - point3d, - point3d_dict, - point3d_another, - point3d_another_dict, - sensor_lidar, - sensors, - object_person, - attributes_multiple_types, - attributes_multiple_types_dict, -): - poly3d = Poly3d.fromdict( - { - "uid": "9a9a30f5-D334-4f11-aa3f-c3c83f2935eb", - "name": "lidar__poly3d__person", - "val": point3d_dict + point3d_another_dict, - "coordinate_system": sensor_lidar.uid, - "attributes": attributes_multiple_types_dict, - "closed": True, - }, - sensors, - object_person, - ) - - assert poly3d.uid == "9a9a30f5-D334-4f11-aa3f-c3c83f2935eb" - assert poly3d.name == "lidar__poly3d__person" - assert poly3d.points == [point3d, point3d_another] - assert poly3d.object == object_person - assert poly3d.sensor == sensor_lidar - assert poly3d.attributes == attributes_multiple_types - assert poly3d.closed == True - - -def test_asdict( - point3d, - point3d_dict, - point3d_another, - point3d_another_dict, - sensor_lidar, - object_person, - attributes_multiple_types, - attributes_multiple_types_dict, -): - poly3d = Poly3d( - uid="9a9a30f5-D334-4f11-aa3f-c3c83f2935eb", - points=[point3d, point3d_another], - object=object_person, - sensor=sensor_lidar, - attributes=attributes_multiple_types, - closed=True, - ) - - assert poly3d.asdict() == { - "uid": "9a9a30f5-D334-4f11-aa3f-c3c83f2935eb", - "name": "lidar__poly3d__person", - "val": point3d_dict + point3d_another_dict, - "coordinate_system": sensor_lidar.uid, - "attributes": attributes_multiple_types_dict, - "closed": True, - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_quaternion.py b/tests/test_raillabel/format/test_quaternion.py index d508e85..78ebab4 100644 --- a/tests/test_raillabel/format/test_quaternion.py +++ b/tests/test_raillabel/format/test_quaternion.py @@ -3,21 +3,15 @@ from __future__ import annotations -import os -import sys -from pathlib import Path - import pytest -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - from raillabel.format import Quaternion # == Fixtures ========================= @pytest.fixture -def quaternion_dict() -> dict: +def quaternion_json() -> dict: return [0.75318325, -0.10270147, 0.21430262, -0.61338551] @@ -29,26 +23,10 @@ def quaternion() -> dict: # == Tests ============================ -def test_from_json(quaternion, quaternion_dict): - actual = Quaternion.from_json(quaternion_dict) +def test_from_json(quaternion, quaternion_json): + actual = Quaternion.from_json(quaternion_json) assert actual == quaternion -def test_fromdict(): - quaternion = Quaternion.fromdict([0.75318325, -0.10270147, 0.21430262, -0.61338551]) - - assert quaternion.x == 0.75318325 - assert quaternion.y == -0.10270147 - assert quaternion.z == 0.21430262 - assert quaternion.w == -0.61338551 - - -def test_asdict(): - quaternion = Quaternion(x=0.75318325, y=-0.10270147, z=0.21430262, w=-0.61338551) - - assert quaternion.asdict() == [0.75318325, -0.10270147, 0.21430262, -0.61338551] - - if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) + pytest.main([__file__, "-v"]) diff --git a/tests/test_raillabel/format/test_scene.py b/tests/test_raillabel/format/test_scene.py deleted file mode 100644 index 124b55d..0000000 --- a/tests/test_raillabel/format/test_scene.py +++ /dev/null @@ -1,362 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Frame, FrameInterval, Scene -from raillabel.format.scene import _clean_dict - -# == Fixtures ========================= - - -@pytest.fixture -def scene_dict( - metadata_full_dict, - sensor_camera_dict, - sensor_lidar_dict, - sensor_radar_dict, - object_person_dict, - object_train_dict, - frame, - frame_dict, -) -> dict: - return { - "openlabel": { - "metadata": metadata_full_dict, - "streams": { - sensor_camera_dict["uid"]: sensor_camera_dict["stream"], - sensor_lidar_dict["uid"]: sensor_lidar_dict["stream"], - sensor_radar_dict["uid"]: sensor_radar_dict["stream"], - }, - "coordinate_systems": { - "base": { - "type": "local", - "parent": "", - "children": [ - sensor_lidar_dict["uid"], - sensor_camera_dict["uid"], - sensor_radar_dict["uid"], - ], - }, - sensor_camera_dict["uid"]: sensor_camera_dict["coordinate_system"], - sensor_lidar_dict["uid"]: sensor_lidar_dict["coordinate_system"], - sensor_radar_dict["uid"]: sensor_radar_dict["coordinate_system"], - }, - "objects": { - object_person_dict["object_uid"]: object_person_dict["data_dict"], - object_train_dict["object_uid"]: object_train_dict["data_dict"], - }, - "frames": { - frame.uid: frame_dict, - }, - "frame_intervals": [ - { - "frame_start": 0, - "frame_end": 0, - } - ], - } - } - - -@pytest.fixture -def scene( - metadata_full, sensor_camera, sensor_lidar, sensor_radar, object_person, object_train, frame -) -> Scene: - return Scene( - metadata=metadata_full, - sensors={ - sensor_lidar.uid: sensor_lidar, - sensor_camera.uid: sensor_camera, - sensor_radar.uid: sensor_radar, - }, - objects={ - object_person.uid: object_person, - object_train.uid: object_train, - }, - frames={frame.uid: frame}, - ) - - -# == Tests ============================ - - -def test_fromdict_metadata( - metadata_full, - metadata_full_dict, -): - scene = Scene.fromdict( - { - "openlabel": { - "metadata": metadata_full_dict, - } - }, - subschema_version=metadata_full.subschema_version, - ) - - scene.metadata.exporter_version = None # necessary for testing on remote - - assert scene.metadata == metadata_full - - -def test_fromdict_sensors( - metadata_full_dict, - sensor_camera, - sensor_lidar, - sensor_radar, - sensor_camera_dict, - sensor_lidar_dict, - sensor_radar_dict, -): - scene = Scene.fromdict( - { - "openlabel": { - "metadata": metadata_full_dict, - "streams": { - sensor_camera_dict["uid"]: sensor_camera_dict["stream"], - sensor_lidar_dict["uid"]: sensor_lidar_dict["stream"], - sensor_radar_dict["uid"]: sensor_radar_dict["stream"], - }, - "coordinate_systems": { - "base": { - "type": "local", - "parent": "", - "children": [ - sensor_lidar_dict["uid"], - sensor_camera_dict["uid"], - sensor_radar_dict["uid"], - ], - }, - sensor_camera_dict["uid"]: sensor_camera_dict["coordinate_system"], - sensor_lidar_dict["uid"]: sensor_lidar_dict["coordinate_system"], - sensor_radar_dict["uid"]: sensor_radar_dict["coordinate_system"], - }, - } - } - ) - - assert scene.sensors == { - sensor_lidar.uid: sensor_lidar, - sensor_camera.uid: sensor_camera, - sensor_radar.uid: sensor_radar, - } - - -def test_fromdict_objects( - metadata_full, - metadata_full_dict, - object_person, - object_train, - object_person_dict, - object_train_dict, -): - scene = Scene.fromdict( - { - "openlabel": { - "metadata": metadata_full_dict, - "objects": { - object_person_dict["object_uid"]: object_person_dict["data_dict"], - object_train_dict["object_uid"]: object_train_dict["data_dict"], - }, - } - }, - subschema_version=metadata_full.subschema_version, - ) - - assert scene.objects == { - object_person.uid: object_person, - object_train.uid: object_train, - } - - -def test_fromdict_frames( - metadata_full, - metadata_full_dict, - streams_dict, - coordinate_systems_dict, - objects_dict, - frame, - frame_dict, -): - scene = Scene.fromdict( - { - "openlabel": { - "metadata": metadata_full_dict, - "streams": streams_dict, - "coordinate_systems": coordinate_systems_dict, - "objects": objects_dict, - "frames": { - "0": frame_dict, - }, - "frame_intervals": [ - { - "frame_start": 0, - "frame_end": 0, - } - ], - } - }, - subschema_version=metadata_full.subschema_version, - ) - - assert scene.frames == { - 0: frame, - } - - -def test_asdict_sensors( - metadata_full, - metadata_full_dict, - sensor_camera, - sensor_lidar, - sensor_radar, - sensor_camera_dict, - sensor_lidar_dict, - sensor_radar_dict, -): - scene = Scene( - metadata=metadata_full, - sensors={ - sensor_lidar.uid: sensor_lidar, - sensor_camera.uid: sensor_camera, - sensor_radar.uid: sensor_radar, - }, - ) - - assert scene.asdict() == { - "openlabel": { - "metadata": metadata_full_dict, - "streams": { - sensor_camera_dict["uid"]: sensor_camera_dict["stream"], - sensor_lidar_dict["uid"]: sensor_lidar_dict["stream"], - sensor_radar_dict["uid"]: sensor_radar_dict["stream"], - }, - "coordinate_systems": { - "base": { - "type": "local", - "parent": "", - "children": [ - sensor_lidar_dict["uid"], - sensor_camera_dict["uid"], - sensor_radar_dict["uid"], - ], - }, - sensor_camera_dict["uid"]: sensor_camera_dict["coordinate_system"], - sensor_lidar_dict["uid"]: sensor_lidar_dict["coordinate_system"], - sensor_radar_dict["uid"]: sensor_radar_dict["coordinate_system"], - }, - } - } - - -def test_asdict_objects( - metadata_full, - metadata_full_dict, - object_person, - object_train, - object_person_dict, - object_train_dict, -): - scene = Scene( - metadata=metadata_full, - objects={ - object_person.uid: object_person, - object_train.uid: object_train, - }, - ) - - assert scene.asdict(calculate_pointers=False) == { - "openlabel": { - "metadata": metadata_full_dict, - "objects": { - object_person_dict["object_uid"]: object_person_dict["data_dict"], - object_train_dict["object_uid"]: object_train_dict["data_dict"], - }, - } - } - - -def test_asdict_frames( - metadata_full, - metadata_full_dict, - sensors, - streams_dict, - coordinate_systems_dict, - objects, - objects_dict, - frame, - frame_dict, -): - scene = Scene( - metadata=metadata_full, - sensors=sensors, - objects=objects, - frames={ - "0": frame, - }, - ) - - assert scene.asdict(calculate_pointers=False) == { - "openlabel": { - "metadata": metadata_full_dict, - "streams": streams_dict, - "coordinate_systems": coordinate_systems_dict, - "objects": objects_dict, - "frames": { - "0": frame_dict, - }, - "frame_intervals": [ - { - "frame_start": 0, - "frame_end": 0, - } - ], - } - } - - -def test_frame_intervals(metadata_minimal): - scene = Scene( - metadata=metadata_minimal, - frames={ - 1: Frame(1), - 2: Frame(2), - 3: Frame(3), - 8: Frame(8), - }, - ) - - assert scene.frame_intervals == [ - FrameInterval(1, 3), - FrameInterval(8, 8), - ] - - -def test_integration(json_data): - scene_dict = json_data["openlabel_v1_short"] - - actual = Scene.fromdict(scene_dict).asdict() - - del actual["openlabel"]["metadata"]["exporter_version"] - assert actual == scene_dict - - -def test_clean_dict(): - input_dict = {"non_empty_field": "non_empty_value", "none_field": None, "field_with_len_0": []} - - assert _clean_dict(input_dict) == { - "non_empty_field": "non_empty_value", - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-vv"]) diff --git a/tests/test_raillabel/format/test_seg3d.py b/tests/test_raillabel/format/test_seg3d.py deleted file mode 100644 index 1ff15e3..0000000 --- a/tests/test_raillabel/format/test_seg3d.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Seg3d - -# == Fixtures ========================= - - -@pytest.fixture -def seg3d_dict(sensor_lidar, attributes_multiple_types_dict) -> dict: - return { - "uid": "db4e4a77-B926-4a6c-a2a6-e0ecf9d8734a", - "name": "lidar__vec__person", - "val": [586, 789, 173], - "coordinate_system": sensor_lidar.uid, - "attributes": attributes_multiple_types_dict, - } - - -@pytest.fixture -def seg3d(sensor_lidar, attributes_multiple_types, object_person) -> dict: - return Seg3d( - uid="db4e4a77-B926-4a6c-a2a6-e0ecf9d8734a", - point_ids=[586, 789, 173], - object=object_person, - sensor=sensor_lidar, - attributes=attributes_multiple_types, - ) - - -# == Tests ============================ - - -def test_fromdict( - sensor_lidar, - sensors, - object_person, - attributes_multiple_types, - attributes_multiple_types_dict, -): - seg3d = Seg3d.fromdict( - { - "uid": "db4e4a77-B926-4a6c-a2a6-e0ecf9d8734a", - "name": "lidar__vec__person", - "val": [586, 789, 173], - "coordinate_system": sensor_lidar.uid, - "attributes": attributes_multiple_types_dict, - }, - sensors, - object_person, - ) - - assert seg3d.uid == "db4e4a77-B926-4a6c-a2a6-e0ecf9d8734a" - assert seg3d.name == "lidar__vec__person" - assert seg3d.point_ids == [586, 789, 173] - assert seg3d.object == object_person - assert seg3d.sensor == sensor_lidar - assert seg3d.attributes == attributes_multiple_types - - -def test_asdict( - sensor_lidar, - sensors, - object_person, - attributes_multiple_types, - attributes_multiple_types_dict, -): - seg3d = Seg3d( - uid="db4e4a77-B926-4a6c-a2a6-e0ecf9d8734a", - point_ids=[586, 789, 173], - object=object_person, - sensor=sensor_lidar, - attributes=attributes_multiple_types, - ) - - assert seg3d.asdict() == { - "uid": "db4e4a77-B926-4a6c-a2a6-e0ecf9d8734a", - "name": "lidar__vec__person", - "val": [586, 789, 173], - "coordinate_system": sensor_lidar.uid, - "attributes": attributes_multiple_types_dict, - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_sensor.py b/tests/test_raillabel/format/test_sensor.py deleted file mode 100644 index 59b2259..0000000 --- a/tests/test_raillabel/format/test_sensor.py +++ /dev/null @@ -1,277 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -import typing as t -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Sensor, SensorType - -# == Fixtures ========================= - - -@pytest.fixture -def sensors(sensor_lidar, sensor_camera, sensor_radar) -> dict[str, Sensor]: - return { - sensor_lidar.uid: sensor_lidar, - sensor_camera.uid: sensor_camera, - sensor_radar.uid: sensor_radar, - } - - -@pytest.fixture -def streams_dict(sensor_camera_dict, sensor_lidar_dict, sensor_radar_dict) -> dict: - return { - sensor_camera_dict["uid"]: sensor_camera_dict["stream"], - sensor_lidar_dict["uid"]: sensor_lidar_dict["stream"], - sensor_radar_dict["uid"]: sensor_radar_dict["stream"], - } - - -@pytest.fixture -def coordinate_systems_dict(sensor_camera_dict, sensor_lidar_dict, sensor_radar_dict) -> dict: - return { - "base": { - "type": "local", - "parent": "", - "children": [ - sensor_lidar_dict["uid"], - sensor_camera_dict["uid"], - sensor_radar_dict["uid"], - ], - }, - sensor_camera_dict["uid"]: sensor_camera_dict["coordinate_system"], - sensor_lidar_dict["uid"]: sensor_lidar_dict["coordinate_system"], - sensor_radar_dict["uid"]: sensor_radar_dict["coordinate_system"], - } - - -@pytest.fixture -def sensor_lidar_dict(transform_dict) -> dict: - return { - "uid": "lidar", - "stream": { - "type": "lidar", - "uri": "/lidar_merged", - }, - "coordinate_system": { - "type": "sensor", - "parent": "base", - "pose_wrt_parent": transform_dict, - }, - } - - -@pytest.fixture -def sensor_lidar(transform) -> Sensor: - return Sensor( - uid="lidar", - extrinsics=transform, - intrinsics=None, - type=SensorType.LIDAR, - uri="/lidar_merged", - ) - - -@pytest.fixture -def sensor_camera_dict(transform_dict, intrinsics_pinhole_dict) -> dict: - return { - "uid": "rgb_middle", - "stream": { - "type": "camera", - "uri": "/S1206063/image", - "stream_properties": {"intrinsics_pinhole": intrinsics_pinhole_dict}, - }, - "coordinate_system": { - "type": "sensor", - "parent": "base", - "pose_wrt_parent": transform_dict, - }, - } - - -@pytest.fixture -def sensor_camera(transform, intrinsics_pinhole) -> Sensor: - return Sensor( - uid="rgb_middle", - extrinsics=transform, - intrinsics=intrinsics_pinhole, - type=SensorType.CAMERA, - uri="/S1206063/image", - ) - - -@pytest.fixture -def sensor_radar_dict(transform_dict, intrinsics_radar_dict) -> dict: - return { - "uid": "radar", - "stream": { - "type": "radar", - "uri": "/talker1/Nvt/Cartesian", - "stream_properties": {"intrinsics_radar": intrinsics_radar_dict}, - }, - "coordinate_system": { - "type": "sensor", - "parent": "base", - "pose_wrt_parent": transform_dict, - }, - } - - -@pytest.fixture -def sensor_radar(transform, intrinsics_radar) -> Sensor: - return Sensor( - uid="radar", - extrinsics=transform, - intrinsics=intrinsics_radar, - type=SensorType.RADAR, - uri="/talker1/Nvt/Cartesian", - ) - - -# == Tests ============================ - - -def test_lidar_fromdict(transform, transform_dict): - sensor = Sensor.fromdict( - uid="lidar", - stream_data_dict={ - "type": "lidar", - "uri": "/lidar_merged", - }, - cs_data_dict={ - "type": "sensor", - "parent": "base", - "pose_wrt_parent": transform_dict, - }, - ) - - assert sensor.uid == "lidar" - assert sensor.extrinsics == transform - assert sensor.intrinsics == None - assert sensor.type == SensorType.LIDAR - assert sensor.uri == "/lidar_merged" - - -def test_lidar_asdict(transform, transform_dict): - sensor = Sensor( - uid="lidar", - extrinsics=transform, - intrinsics=None, - type=SensorType.LIDAR, - uri="/lidar_merged", - ) - - assert sensor.asdict() == { - "stream": { - "type": "lidar", - "uri": "/lidar_merged", - }, - "coordinate_system": { - "type": "sensor", - "parent": "base", - "pose_wrt_parent": transform_dict, - }, - } - - -def test_camera_fromdict(transform, transform_dict, intrinsics_pinhole, intrinsics_pinhole_dict): - sensor = Sensor.fromdict( - uid="rgb_middle", - stream_data_dict={ - "type": "camera", - "uri": "/S1206063/image", - "stream_properties": {"intrinsics_pinhole": intrinsics_pinhole_dict}, - }, - cs_data_dict={ - "type": "sensor", - "parent": "base", - "pose_wrt_parent": transform_dict, - }, - ) - - assert sensor.uid == "rgb_middle" - assert sensor.extrinsics == transform - assert sensor.intrinsics == intrinsics_pinhole - assert sensor.type == SensorType.CAMERA - assert sensor.uri == "/S1206063/image" - - -def test_camera_asdict(transform, transform_dict, intrinsics_pinhole, intrinsics_pinhole_dict): - sensor = Sensor( - uid="rgb_middle", - extrinsics=transform, - intrinsics=intrinsics_pinhole, - type=SensorType.CAMERA, - uri="/S1206063/image", - ) - - assert sensor.asdict() == { - "stream": { - "type": "camera", - "uri": "/S1206063/image", - "stream_properties": {"intrinsics_pinhole": intrinsics_pinhole_dict}, - }, - "coordinate_system": { - "type": "sensor", - "parent": "base", - "pose_wrt_parent": transform_dict, - }, - } - - -def test_radar_fromdict(transform, transform_dict, intrinsics_radar, intrinsics_radar_dict): - sensor = Sensor.fromdict( - uid="radar", - stream_data_dict={ - "type": "radar", - "uri": "/talker1/Nvt/Cartesian", - "stream_properties": {"intrinsics_radar": intrinsics_radar_dict}, - }, - cs_data_dict={ - "type": "sensor", - "parent": "base", - "pose_wrt_parent": transform_dict, - }, - ) - - assert sensor.uid == "radar" - assert sensor.extrinsics == transform - assert sensor.intrinsics == intrinsics_radar - assert sensor.type == SensorType.RADAR - assert sensor.uri == "/talker1/Nvt/Cartesian" - - -def test_radar_asdict(transform, transform_dict, intrinsics_radar, intrinsics_radar_dict): - sensor = Sensor( - uid="radar", - extrinsics=transform, - intrinsics=intrinsics_radar, - type=SensorType.RADAR, - uri="/talker1/Nvt/Cartesian", - ) - - assert sensor.asdict() == { - "stream": { - "type": "radar", - "uri": "/talker1/Nvt/Cartesian", - "stream_properties": {"intrinsics_radar": intrinsics_radar_dict}, - }, - "coordinate_system": { - "type": "sensor", - "parent": "base", - "pose_wrt_parent": transform_dict, - }, - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_sensor_reference.py b/tests/test_raillabel/format/test_sensor_reference.py deleted file mode 100644 index 886b41c..0000000 --- a/tests/test_raillabel/format/test_sensor_reference.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from decimal import Decimal -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import SensorReference - -# == Fixtures ========================= - - -@pytest.fixture -def sensor_reference_camera_dict() -> dict: - return { - "stream_properties": {"sync": {"timestamp": "1632321743.100000072"}}, - "uri": "rgb_test0.png", - } - - -@pytest.fixture -def sensor_reference_camera(sensor_camera) -> dict: - return SensorReference( - sensor=sensor_camera, timestamp=Decimal("1632321743.100000072"), uri="rgb_test0.png" - ) - - -# == Tests ============================ - - -def test_fromdict(sensor_camera): - sensor_reference = SensorReference.fromdict( - { - "stream_properties": {"sync": {"timestamp": "1632321743.100000072"}}, - "uri": "rgb_test0.png", - }, - sensor_camera, - ) - - assert sensor_reference.sensor == sensor_camera - assert sensor_reference.timestamp == Decimal("1632321743.100000072") - assert sensor_reference.uri == "rgb_test0.png" - - -def test_asdict(sensor_camera): - sensor_reference = SensorReference( - sensor=sensor_camera, timestamp=Decimal("1632321743.100000072"), uri="rgb_test0.png" - ) - - assert sensor_reference.asdict() == { - "stream_properties": {"sync": {"timestamp": "1632321743.100000072"}}, - "uri": "rgb_test0.png", - } - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_size2d.py b/tests/test_raillabel/format/test_size2d.py index 65ffd4f..3e4b3a3 100644 --- a/tests/test_raillabel/format/test_size2d.py +++ b/tests/test_raillabel/format/test_size2d.py @@ -11,7 +11,7 @@ @pytest.fixture -def size2d_dict() -> dict: +def size2d_json() -> dict: return [25, 1.344] @@ -23,26 +23,10 @@ def size2d() -> dict: # == Tests ============================ -def test_from_json(size2d, size2d_dict): - actual = Size2d.from_json(size2d_dict) +def test_from_json(size2d, size2d_json): + actual = Size2d.from_json(size2d_json) assert actual == size2d -def test_fromdict(): - size2d = Size2d.fromdict([25, 1.344]) - - assert size2d.x == 25 - assert size2d.y == 1.344 - - -def test_asdict(): - size2d = Size2d( - x=25, - y=1.344, - ) - - assert size2d.asdict() == [25, 1.344] - - if __name__ == "__main__": pytest.main([__file__, "-v"]) diff --git a/tests/test_raillabel/format/test_size3d.py b/tests/test_raillabel/format/test_size3d.py deleted file mode 100644 index 8626da3..0000000 --- a/tests/test_raillabel/format/test_size3d.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import sys -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent.parent.parent)) - -from raillabel.format import Size3d - -# == Fixtures ========================= - - -@pytest.fixture -def size3d_dict() -> dict: - return [0.35, 0.7, 1.92] - - -@pytest.fixture -def size3d() -> dict: - return Size3d(0.35, 0.7, 1.92) - - -# == Tests ============================ - - -def test_fromdict(): - size3d = Size3d.fromdict([0.35, 0.7, 1.92]) - - assert size3d.x == 0.35 - assert size3d.y == 0.7 - assert size3d.z == 1.92 - - -def test_asdict(): - size3d = Size3d(x=0.35, y=0.7, z=1.92) - - assert size3d.asdict() == [0.35, 0.7, 1.92] - - -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"]) diff --git a/tests/test_raillabel/format/test_transform.py b/tests/test_raillabel/format/test_transform.py index f6bcd78..db97033 100644 --- a/tests/test_raillabel/format/test_transform.py +++ b/tests/test_raillabel/format/test_transform.py @@ -13,13 +13,8 @@ @pytest.fixture -def transform_dict(point3d_dict, quaternion_dict) -> dict: - return {"translation": point3d_dict, "quaternion": quaternion_dict} - - -@pytest.fixture -def transform_json(point3d_dict, quaternion_dict) -> JSONTransformData: - return JSONTransformData(translation=point3d_dict, quaternion=quaternion_dict) +def transform_json(point3d_json, quaternion_json) -> JSONTransformData: + return JSONTransformData(translation=point3d_json, quaternion=quaternion_json) @pytest.fixture @@ -35,18 +30,5 @@ def test_from_json(transform_json, transform): assert actual == transform -def test_fromdict(point3d, point3d_dict, quaternion, quaternion_dict): - transform = Transform.fromdict({"translation": point3d_dict, "quaternion": quaternion_dict}) - - assert transform.position == point3d - assert transform.quaternion == quaternion - - -def test_asdict(point3d, point3d_dict, quaternion, quaternion_dict): - transform = Transform(position=point3d, quaternion=quaternion) - - assert transform.asdict() == {"translation": point3d_dict, "quaternion": quaternion_dict} - - if __name__ == "__main__": pytest.main([__file__, "-v"]) diff --git a/tests/test_raillabel/load/test_load.py b/tests/test_raillabel/load/test_load.py deleted file mode 100644 index 7c95c19..0000000 --- a/tests/test_raillabel/load/test_load.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -import os - -import pytest - -import raillabel - - -def test_load__contains_all_elements(json_paths): - actual = raillabel.load(json_paths["openlabel_v1_short"]) - assert len(actual.sensors) == 4 - assert len(actual.objects) == 3 - assert len(actual.frames) == 2 - - -# Executes the test if the file is called -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear"]) diff --git a/tests/test_raillabel/save/test_save.py b/tests/test_raillabel/save/test_save.py deleted file mode 100644 index fae68b1..0000000 --- a/tests/test_raillabel/save/test_save.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -import json -import os -import sys -import tempfile -from copy import deepcopy -from pathlib import Path - -import pytest - -sys.path.insert(1, str(Path(__file__).parent.parent.parent)) - -import raillabel - - -def test_save_scene(json_paths): - with tempfile.TemporaryDirectory("w") as temp_dir: - scene_orig = raillabel.load(json_paths["openlabel_v1_short"]) - - raillabel.save(scene_orig, Path(temp_dir) / "test_save_file.json") - scene_saved = raillabel.load(Path(temp_dir) / "test_save_file.json") - - assert scene_orig == scene_saved - - -def test_save_json(json_data): - with tempfile.TemporaryDirectory("w") as temp_dir: - stripped_input_data = deepcopy(json_data["openlabel_v1_short"]) - - # Removes the object data pointers from the example file so that it needs to be generated from the data - for object in stripped_input_data["openlabel"]["objects"].values(): - del object["frame_intervals"] - del object["object_data_pointers"] - - with (Path(temp_dir) / "stripped_input_data.json").open("w") as f: - json.dump(stripped_input_data, f) - - scene = raillabel.load(Path(temp_dir) / "stripped_input_data.json") - raillabel.save(scene, Path(temp_dir) / "test_save_file.json") - - with (Path(temp_dir) / "test_save_file.json").open() as f: - saved_and_loaded_data = json.load(f) - - # Removes the exporter version and subschema version from the generated file as these are hard to test for - if "exporter_version" in saved_and_loaded_data["openlabel"]["metadata"]: - del saved_and_loaded_data["openlabel"]["metadata"]["exporter_version"] - - if "subschema_version" in saved_and_loaded_data["openlabel"]["metadata"]: - del saved_and_loaded_data["openlabel"]["metadata"]["subschema_version"] - - assert saved_and_loaded_data == json_data["openlabel_v1_short"] - - -def test_frame_intervals(): - data = { - "openlabel": { - "metadata": {"schema_version": "1.0.0"}, - "frames": { - "0": {}, - "1": {}, - "2": {}, - "5": {}, - "7": {}, - "8": {}, - }, - } - } - - scene = raillabel.Scene.fromdict(data) - dict_repr = scene.asdict()["openlabel"] - - assert "frame_intervals" in dict_repr - assert dict_repr["frame_intervals"] == [ - {"frame_start": 0, "frame_end": 2}, - {"frame_start": 5, "frame_end": 5}, - {"frame_start": 7, "frame_end": 8}, - ] - - -# Executes the test if the file is called -if __name__ == "__main__": - os.system("clear") - pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-vv"])