Skip to content

Commit af158c1

Browse files
Drew KaulDrew Kaul
authored andcommitted
add frames_dict
1 parent 0a1998d commit af158c1

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

nucleus/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
ITEMS_KEY = "items"
4242
ITEM_ID_KEY = "item_id"
4343
ITEM_KEY = "item"
44+
ITEMS_KEY = "items"
4445
ITEM_METADATA_SCHEMA_KEY = "item_metadata_schema"
4546
JOB_ID_KEY = "job_id"
4647
KEEP_HISTORY_KEY = "keep_history"

nucleus/scene.py

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import json
22
from dataclasses import dataclass
3-
from typing import Optional, Dict, List, Set
3+
from typing import Optional, Union, Dict, List, Set
44
from enum import Enum
55
from nucleus.constants import (
66
CAMERA_PARAMS_KEY,
77
FRAMES_KEY,
8+
INDEX_KEY,
9+
ITEMS_KEY,
810
METADATA_KEY,
911
REFERENCE_ID_KEY,
1012
TYPE_KEY,
@@ -70,6 +72,7 @@ def to_json(self) -> str:
7072

7173
@dataclass
7274
class Frame:
75+
index: Union[int, None] = None
7376
items: Dict[str, SceneDatasetItem] = {}
7477

7578
def __post_init__(self):
@@ -84,8 +87,11 @@ def add_item(self, item: SceneDatasetItem, sensor_name: str):
8487

8588
def to_payload(self) -> dict:
8689
return {
87-
sensor: scene_dataset_item.to_payload()
88-
for sensor, scene_dataset_item in self.items.items()
90+
INDEX_KEY: self.index,
91+
ITEMS_KEY: {
92+
sensor: scene_dataset_item.to_payload()
93+
for sensor, scene_dataset_item in self.items.items()
94+
},
8995
}
9096

9197

@@ -95,8 +101,14 @@ class Scene:
95101
frames: List[Frame] = []
96102
metadata: Optional[dict] = None
97103

98-
# TODO: move validation to scene upload
99104
def __post_init__(self):
105+
self.check_valid_frame_indices()
106+
if(all([frame.index is not None for frame in self.frames])):
107+
self.frames_dict = {frame.index: frame for frame in self.frames}
108+
else:
109+
self.frames_dict = {i: frame for i, frame in enumerate(self.frames)}
110+
111+
# TODO: move validation to scene upload
100112
assert isinstance(self.frames, List), "frames must be a list"
101113
for frame in self.frames:
102114
assert isinstance(
@@ -107,13 +119,34 @@ def __post_init__(self):
107119
self.reference_id, str
108120
), "reference_id must be a string"
109121

110-
def add_frame(self, frame: Frame):
111-
self.frames.append(frame)
122+
def check_valid_frame_indices(self):
123+
infer_from_list_position = all([frame.index is None for frame in self.frames])
124+
explicit_frame_order = all([frame.index is not None for frame in self.frames])
125+
assert infer_from_list_position or explicit_frame_order, "Must specify index explicitly for all frames or implicitly for all frames (inferred from list position)"
126+
127+
def add_item(self, item: SceneDatasetItem, index: int, sensor_name: str):
128+
if index not in self.frames_dict:
129+
new_frame = Frame(index, {sensor_name: item})
130+
self.frames_dict[index] = new_frame
131+
else:
132+
self.frames_dict[index].items[sensor_name] = item
133+
134+
def add_frame(self, frame: Frame, update: bool = False):
135+
assert frame.index is not None, "Must specify index explicitly when calling add_frame"
136+
if frame.index not in self.frames_dict or frame.index in self.frames_dict and update:
137+
self.frames_dict[frame.index] = frame
112138

113139
def to_payload(self) -> dict:
140+
frames_payload = [frame.to_payload() for frame in self.frames]
141+
if len(frames_payload) > 0 and frames_payload[0].index is None:
142+
for i in range(len(frames_payload)):
143+
frames_payload[INDEX_KEY] = i
144+
else:
145+
frames_payload.sort(lambda x: x[INDEX_KEY])
146+
114147
return {
115148
REFERENCE_ID_KEY: self.reference_id,
116-
FRAMES_KEY: [frame.to_payload() for frame in self.frames],
149+
FRAMES_KEY: frames_payload,
117150
METADATA_KEY: self.metadata,
118151
}
119152

0 commit comments

Comments
 (0)