From 48b731d1eee03df3c2a758c12d69d99d925dbf1e Mon Sep 17 00:00:00 2001 From: Max SCHMELLER Date: Thu, 29 Jan 2026 15:33:24 +0900 Subject: [PATCH 1/2] fix: abstract away category indexing differences Semseg and non-semseg datasets behave differently (position-based vs. explicit indexing). Now computing index field in case position-based indexing is used. Signed-off-by: Max SCHMELLER --- t4_devkit/compatibility.py | 33 +++++++++++++++++++++++++++++++++ t4_devkit/helper/rendering.py | 2 +- t4_devkit/tier4.py | 5 ++++- 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 t4_devkit/compatibility.py diff --git a/t4_devkit/compatibility.py b/t4_devkit/compatibility.py new file mode 100644 index 0000000..86e0b8a --- /dev/null +++ b/t4_devkit/compatibility.py @@ -0,0 +1,33 @@ +"""Compatibility helpers that abstract away differences between T4Dataset revisions.""" + +from __future__ import annotations + +from t4_devkit.schema import Category + + +def fix_category_table(categories: list[Category]) -> list[Category]: + """Fix unpopulated index fields in some T4Dataset revisions. + + This function behaves differently in the below three cases: + + - All `index` fields are set: the list is returned unmodified. + - All `index` fields are `None`: the position of each category in the list is used to compute + `index`. The resulting indices start at `0`. + - Some `index` fields are set and some are `None`: raise a `ValueError`. + + Args: + categories (list[Category]): List of categories to fix. + + Returns: + list[Category]: Fixed list of categories. + + Raises: + ValueError: If the `index` field is set for some categories and `None` for others. + """ + if any(category.index is None for category in categories): + if not all(category.index is None for category in categories): + raise ValueError("Category index is not set for some categories.") + + for idx, category in enumerate(categories): + category.index = idx + return categories diff --git a/t4_devkit/helper/rendering.py b/t4_devkit/helper/rendering.py index 6088908..4f43859 100644 --- a/t4_devkit/helper/rendering.py +++ b/t4_devkit/helper/rendering.py @@ -54,7 +54,7 @@ def __init__(self, t4: Tier4) -> None: """ self._t4 = t4 self._label2id: dict[str, int] = { - category.name: idx for idx, category in enumerate(self._t4.category) + category.name: category.index for category in self._t4.category } self._executor = concurrent.futures.ThreadPoolExecutor() diff --git a/t4_devkit/tier4.py b/t4_devkit/tier4.py index 8207c50..f8cd011 100644 --- a/t4_devkit/tier4.py +++ b/t4_devkit/tier4.py @@ -12,6 +12,7 @@ from pyquaternion import Quaternion from t4_devkit.common.geometry import is_box_in_image +from t4_devkit.compatibility import fix_category_table from t4_devkit.dataclass import Box2D, Box3D, SemanticLabel, Shape, ShapeType from t4_devkit.helper import RenderingHelper, TimeseriesHelper from t4_devkit.schema import SchemaName, SensorModality, VisibilityLevel, build_schema @@ -181,6 +182,8 @@ def __init__( self.annotation_dir, SchemaName.CALIBRATED_SENSOR ) self.category: list[Category] = load_table(self.annotation_dir, SchemaName.CATEGORY) + self.category = fix_category_table(self.category) + self.ego_pose: list[EgoPose] = load_table(self.annotation_dir, SchemaName.EGO_POSE) self.instance: list[Instance] = load_table(self.annotation_dir, SchemaName.INSTANCE) self.keypoint: list[Keypoint] = load_table(self.annotation_dir, SchemaName.KEYPOINT) @@ -265,7 +268,7 @@ def __make_reverse_index__(self, verbose: bool) -> None: } self._label2id: dict[str, int] = { - category.name: idx for idx, category in enumerate(self.category) + category.name: category.index for category in self.category } # add shortcuts From 9ffef84138df0db30ae4fad853503211f6c98b4f Mon Sep 17 00:00:00 2001 From: Max SCHMELLER Date: Fri, 30 Jan 2026 10:04:24 +0900 Subject: [PATCH 2/2] Cherry-pick of b91ece3 "refactor(compatibility): move to schema package " Signed-off-by: Max SCHMELLER --- t4_devkit/{ => schema}/compatibility.py | 0 t4_devkit/tier4.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename t4_devkit/{ => schema}/compatibility.py (100%) diff --git a/t4_devkit/compatibility.py b/t4_devkit/schema/compatibility.py similarity index 100% rename from t4_devkit/compatibility.py rename to t4_devkit/schema/compatibility.py diff --git a/t4_devkit/tier4.py b/t4_devkit/tier4.py index f8cd011..2453334 100644 --- a/t4_devkit/tier4.py +++ b/t4_devkit/tier4.py @@ -12,10 +12,10 @@ from pyquaternion import Quaternion from t4_devkit.common.geometry import is_box_in_image -from t4_devkit.compatibility import fix_category_table from t4_devkit.dataclass import Box2D, Box3D, SemanticLabel, Shape, ShapeType from t4_devkit.helper import RenderingHelper, TimeseriesHelper from t4_devkit.schema import SchemaName, SensorModality, VisibilityLevel, build_schema +from t4_devkit.schema.compatibility import fix_category_table if TYPE_CHECKING: from t4_devkit.typing import CameraIntrinsicLike, Vector3