Skip to content

Commit a99b421

Browse files
author
Ubuntu
committed
Switch to using annotation id
1 parent 1c74466 commit a99b421

File tree

8 files changed

+46
-103
lines changed

8 files changed

+46
-103
lines changed

nucleus/__init__.py

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -951,40 +951,6 @@ def predictions_loc(self, model_run_id: str, dataset_item_id: str):
951951
{}, f"modelRun/{model_run_id}/loc/{dataset_item_id}", requests.get
952952
)
953953

954-
def prediction_loc(self, model_run_id: str, prediction_id: str):
955-
"""
956-
Returns info for single Prediction by its id.
957-
:param model_run_id: id of the model run
958-
:param prediction_id: internally controlled id for model predictions.
959-
:return:
960-
{
961-
"ref_id": Reference id of dataset item associated with this prediction
962-
"prediction": BoxPrediction | PolygonPrediction | CuboidPrediction
963-
}
964-
"""
965-
return self.make_request(
966-
{},
967-
f"modelRun/{model_run_id}/prediction/loc/{prediction_id}",
968-
requests.get,
969-
)
970-
971-
def ground_truth_loc(self, dataset_id: str, ground_truth_id: str):
972-
"""
973-
Returns info for single Prediction by its id.
974-
:param dataset_id: id of the dataset
975-
:param ground_truth_id: internally controlled id for ground truth annotations.
976-
:return:
977-
{
978-
"ref_id": Reference id of dataset item associated with this prediction
979-
"ground_truth": BoxAnnotation | PolygonAnnotation | CuboidAnnotation
980-
}
981-
"""
982-
return self.make_request(
983-
{},
984-
f"dataset/{dataset_id}/groundTruth/loc/{ground_truth_id}",
985-
requests.get,
986-
)
987-
988954
def create_slice(self, dataset_id: str, payload: dict) -> Slice:
989955
"""
990956
Creates a slice from items already present in a dataset.

nucleus/dataset.py

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -386,27 +386,19 @@ def loc(self, dataset_item_id: str) -> dict:
386386
response = self._client.dataitem_loc(self.id, dataset_item_id)
387387
return format_dataset_item_response(response)
388388

389-
def ground_truth_loc(self, ground_truth_id: str):
389+
def ground_truth_loc(self, reference_id: str, annotation_id: str):
390390
"""
391391
Returns info for single ground truth Annotation by its id.
392-
:param prediction_id: internally controlled id for ground truth annotations.
392+
:param annotation_id: internally controlled id for ground truth annotations.
393393
:return:
394-
{
395-
"ref_id": Reference id of dataset item associated with this annotation
396-
"groundTruth": BoxAnnotation | PolygonAnnotation | CuboidAnnotation
397-
}
394+
BoxAnnotation | PolygonAnnotation | CuboidAnnotation
398395
"""
399-
response = self._client.ground_truth_loc(self.id, ground_truth_id)
400-
annotation_type = response["groundTruth"].keys()[0]
401-
return {
402-
"ref_id": response["ref_id"],
403-
"ground_truth": Annotation.from_json(
404-
{
405-
REFERENCE_ID_KEY: response["ref_id"],
406-
**response["groundTruth"][annotation_type],
407-
}
408-
),
409-
}
396+
response = self._client.make_request(
397+
{},
398+
f"dataset/{self.id}/groundTruth/loc/{reference_id}/{annotation_id}",
399+
requests.get,
400+
)
401+
return Annotation.from_json(response)
410402

411403
def create_slice(
412404
self,

nucleus/model_run.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
CuboidPrediction,
2020
PolygonPrediction,
2121
SegmentationPrediction,
22+
from_json,
2223
)
2324

2425

@@ -160,25 +161,22 @@ def loc(self, dataset_item_id: str):
160161
)
161162
return self._format_prediction_response(response)
162163

163-
def prediction_loc(self, prediction_id: str):
164+
def prediction_loc(self, reference_id: str, annotation_id: str):
164165
"""
165-
Returns info for single Prediction by its id.
166-
:param prediction_id: internally controlled id for model predictions.
166+
Returns info for single Prediction by its reference id and annotation id.
167+
:param reference_id: the user specified id for the image
168+
:param annotation_id: the user specified id for the prediction
167169
:return:
168-
{
169-
"ref_id": Reference id of dataset item associated with this prediction
170-
"prediction": BoxPrediction | PolygonPrediction | CuboidPrediction
171-
}
170+
BoxPrediction | PolygonPrediction | CuboidPrediction
172171
"""
173-
response = self._client.prediction_loc(
174-
self.model_run_id, prediction_id
172+
173+
response = self._client.make_request(
174+
{},
175+
f"modelRun/{self.model_run_id}/prediction/loc/{reference_id}/{annotation_id}",
176+
requests.get,
175177
)
176-
return {
177-
"ref_id": response["ref_id"],
178-
"prediction": self._format_prediction_response(
179-
{"predictions": [response["prediction"]]}
180-
),
181-
}
178+
179+
return from_json(response)
182180

183181
def ungrouped_export(self):
184182
json_response = self._client.make_request(

nucleus/prediction.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@
1010
)
1111
from .constants import (
1212
ANNOTATION_ID_KEY,
13+
BOX_TYPE,
14+
CUBOID_TYPE,
15+
POLYGON_TYPE,
1316
REFERENCE_ID_KEY,
1417
METADATA_KEY,
1518
GEOMETRY_KEY,
1619
LABEL_KEY,
20+
TYPE_KEY,
1721
X_KEY,
1822
Y_KEY,
1923
WIDTH_KEY,
@@ -29,6 +33,17 @@
2933
)
3034

3135

36+
def from_json(payload: dict):
37+
if payload.get(TYPE_KEY, None) == BOX_TYPE:
38+
return BoxPrediction.from_json(payload)
39+
elif payload.get(TYPE_KEY, None) == POLYGON_TYPE:
40+
return PolygonPrediction.from_json(payload)
41+
elif payload.get(TYPE_KEY, None) == CUBOID_TYPE:
42+
return CuboidPrediction.from_json(payload)
43+
else:
44+
return SegmentationPrediction.from_json(payload)
45+
46+
3247
class SegmentationPrediction(SegmentationAnnotation):
3348
# No need to define init or to_payload methods because
3449
# we default to functions defined in the parent class

tests/helpers.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414
TEST_PROJECT_ID = "60b699d70f139e002dd31bfc"
1515

1616
DATASET_WITH_AUTOTAG = "ds_c4dgj702e2vjft7m9xa0"
17-
DATASET_WITH_PREDICTIONS = "ds_c4283fxxjfvg05rmm5p0"
18-
DATASET_WITH_PREDICTIONS_MODEL_RUN_ID = "run_c4283gpxjfvg0ehz6gjg"
19-
DATASET_WITH_PREDICTIONS_SAMPLE_PREDICTION_ID = "pred_c4283gp2s2b00esdarq0"
20-
DATASET_WITH_GROUND_TRUTH = "ds_c3pz51mjy60g09hfzhfg"
21-
DATASET_WITH_GROUND_TRUTH_SAMPLE_GROUND_TRUTH_ID = "ann_c3pz524k221g0css4ns0"
2217
NUCLEUS_PYTEST_USER_ID = "60ad648c85db770026e9bf77"
2318

2419

tests/test_annotation.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ def test_box_gt_upload(dataset):
7070
assert response["annotations_ignored"] == 0
7171

7272
response = dataset.refloc(annotation.reference_id)["annotations"]["box"]
73+
single_annotation_response = dataset.ground_truth_loc(
74+
annotation.reference_id, annotation.annotation_id
75+
)
76+
77+
assert response[0] == single_annotation_response
7378
assert len(response) == 1
7479
response_annotation = response[0]
7580
assert_box_annotation_matches_dict(

tests/test_dataset.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
from nucleus.job import AsyncJob, JobError
3434

3535
from .helpers import (
36-
DATASET_WITH_GROUND_TRUTH,
37-
DATASET_WITH_GROUND_TRUTH_SAMPLE_GROUND_TRUTH_ID,
3836
LOCAL_FILENAME,
3937
TEST_BOX_ANNOTATIONS,
4038
TEST_DATASET_NAME,
@@ -102,15 +100,6 @@ def make_dataset_items():
102100
return ds_items_with_metadata
103101

104102

105-
def test_dataset_ground_truth_loc(CLIENT):
106-
ds = CLIENT.get_dataset(DATASET_WITH_GROUND_TRUTH)
107-
response = ds.ground_truth_loc(
108-
DATASET_WITH_GROUND_TRUTH_SAMPLE_GROUND_TRUTH_ID
109-
)
110-
assert response["ref_id"] is not None
111-
assert response["ground_truth"] is not None
112-
113-
114103
def test_dataset_create_and_delete(CLIENT):
115104
# Creation
116105
ds = CLIENT.create_dataset(TEST_DATASET_NAME)

tests/test_prediction.py

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33
import pytest
44
import time
55
from .helpers import (
6-
DATASET_WITH_PREDICTIONS,
7-
DATASET_WITH_PREDICTIONS_MODEL_RUN_ID,
8-
DATASET_WITH_PREDICTIONS_SAMPLE_PREDICTION_ID,
9-
NUCLEUS_PYTEST_USER_ID,
106
TEST_DATASET_NAME,
117
TEST_MODEL_NAME,
128
TEST_MODEL_RUN,
@@ -25,14 +21,10 @@
2521
PolygonPrediction,
2622
SegmentationPrediction,
2723
DatasetItem,
28-
Segment,
2924
ModelRun,
30-
Point,
3125
)
3226
from nucleus.constants import ERROR_PAYLOAD
3327

34-
from nucleus import utils
35-
3628

3729
def test_reprs():
3830
def test_repr(test_object: any):
@@ -81,19 +73,6 @@ def model_run(CLIENT):
8173
assert response == {}
8274

8375

84-
def test_pred_loc(CLIENT):
85-
if NUCLEUS_PYTEST_USER_ID in os.environ["NUCLEUS_PYTEST_USER_ID"]:
86-
run = CLIENT.get_model_run(
87-
DATASET_WITH_PREDICTIONS_MODEL_RUN_ID, DATASET_WITH_PREDICTIONS
88-
)
89-
response = run.prediction_loc(
90-
DATASET_WITH_PREDICTIONS_SAMPLE_PREDICTION_ID
91-
)
92-
93-
assert response["ref_id"] is not None
94-
assert response["prediction"] is not None
95-
96-
9776
def test_box_pred_upload(model_run):
9877
prediction = BoxPrediction(**TEST_BOX_PREDICTIONS[0])
9978
response = model_run.predict(annotations=[prediction])
@@ -103,6 +82,10 @@ def test_box_pred_upload(model_run):
10382
assert response["predictions_ignored"] == 0
10483

10584
response = model_run.refloc(prediction.reference_id)["box"]
85+
single_prediction = model_run.prediction_loc(
86+
prediction.reference_id, prediction.annotation_id
87+
)
88+
assert response[0] == single_prediction
10689
assert len(response) == 1
10790
assert_box_prediction_matches_dict(response[0], TEST_BOX_PREDICTIONS[0])
10891

0 commit comments

Comments
 (0)