scale-nucleus 0.12b1__py3-none-any.whl → 0.14.14b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. cli/slices.py +14 -28
  2. nucleus/__init__.py +211 -18
  3. nucleus/annotation.py +28 -5
  4. nucleus/connection.py +9 -1
  5. nucleus/constants.py +9 -3
  6. nucleus/dataset.py +197 -59
  7. nucleus/dataset_item.py +11 -1
  8. nucleus/job.py +1 -1
  9. nucleus/metrics/__init__.py +2 -1
  10. nucleus/metrics/base.py +34 -56
  11. nucleus/metrics/categorization_metrics.py +6 -2
  12. nucleus/metrics/cuboid_utils.py +4 -6
  13. nucleus/metrics/errors.py +4 -0
  14. nucleus/metrics/filtering.py +369 -19
  15. nucleus/metrics/polygon_utils.py +3 -3
  16. nucleus/metrics/segmentation_loader.py +30 -0
  17. nucleus/metrics/segmentation_metrics.py +256 -195
  18. nucleus/metrics/segmentation_to_poly_metrics.py +229 -105
  19. nucleus/metrics/segmentation_utils.py +239 -8
  20. nucleus/model.py +66 -10
  21. nucleus/model_run.py +1 -1
  22. nucleus/{shapely_not_installed.py → package_not_installed.py} +3 -3
  23. nucleus/payload_constructor.py +4 -0
  24. nucleus/prediction.py +6 -3
  25. nucleus/scene.py +7 -0
  26. nucleus/slice.py +160 -16
  27. nucleus/utils.py +51 -12
  28. nucleus/validate/__init__.py +1 -0
  29. nucleus/validate/client.py +57 -8
  30. nucleus/validate/constants.py +1 -0
  31. nucleus/validate/data_transfer_objects/eval_function.py +22 -0
  32. nucleus/validate/data_transfer_objects/scenario_test_evaluations.py +13 -5
  33. nucleus/validate/eval_functions/available_eval_functions.py +33 -20
  34. nucleus/validate/eval_functions/config_classes/segmentation.py +2 -46
  35. nucleus/validate/scenario_test.py +71 -13
  36. nucleus/validate/scenario_test_evaluation.py +21 -21
  37. nucleus/validate/utils.py +1 -1
  38. {scale_nucleus-0.12b1.dist-info → scale_nucleus-0.14.14b0.dist-info}/LICENSE +0 -0
  39. {scale_nucleus-0.12b1.dist-info → scale_nucleus-0.14.14b0.dist-info}/METADATA +13 -11
  40. {scale_nucleus-0.12b1.dist-info → scale_nucleus-0.14.14b0.dist-info}/RECORD +42 -41
  41. {scale_nucleus-0.12b1.dist-info → scale_nucleus-0.14.14b0.dist-info}/WHEEL +1 -1
  42. {scale_nucleus-0.12b1.dist-info → scale_nucleus-0.14.14b0.dist-info}/entry_points.txt +0 -0
@@ -1,7 +1,6 @@
1
1
  import itertools
2
2
  from typing import Callable, Dict, List, Optional, Union
3
3
 
4
- from nucleus.logger import logger
5
4
  from nucleus.validate.eval_functions.base_eval_function import (
6
5
  EvalFunctionConfig,
7
6
  )
@@ -10,7 +9,6 @@ from ...metrics.filtering import ListOfAndFilters, ListOfOrAndFilters
10
9
  from ..data_transfer_objects.eval_function import EvalFunctionEntry
11
10
  from ..errors import EvalFunctionNotAvailableError
12
11
  from .config_classes.segmentation import (
13
- SegmentationAveragePrecisionConfig,
14
12
  SegmentationFWAVACCConfig,
15
13
  SegmentationIOUConfig,
16
14
  SegmentationMAPConfig,
@@ -344,7 +342,7 @@ class SegmentationToPolyIOUConfig(EvalFunctionConfig):
344
342
  class SegmentationToPolyMAPConfig(EvalFunctionConfig):
345
343
  def __call__(
346
344
  self,
347
- iou_threshold: float = 0.5,
345
+ iou_thresholds: Union[List[float], str] = "coco",
348
346
  annotation_filters: Optional[
349
347
  Union[ListOfOrAndFilters, ListOfAndFilters]
350
348
  ] = None,
@@ -389,7 +387,7 @@ class SegmentationToPolyMAPConfig(EvalFunctionConfig):
389
387
  Finally, the most outer list combines these filters as a disjunction (OR).
390
388
  """
391
389
  return super().__call__(
392
- iou_threshold=iou_threshold,
390
+ iou_thresholds=iou_thresholds,
393
391
  annotation_filters=annotation_filters,
394
392
  prediction_filters=prediction_filters,
395
393
  **kwargs,
@@ -1139,22 +1137,24 @@ class CustomEvalFunction(EvalFunctionConfig):
1139
1137
  @classmethod
1140
1138
  def expected_name(cls) -> str:
1141
1139
  raise NotImplementedError(
1142
- "Custm evaluation functions are coming soon"
1140
+ "Custom evaluation functions are coming soon"
1143
1141
  ) # Placeholder: See super().eval_func_entry for actual name
1144
1142
 
1145
1143
 
1144
+ class ExternalEvalFunction(EvalFunctionConfig):
1145
+ def __call__(self, **kwargs):
1146
+ raise NotImplementedError("Cannot call an external function")
1147
+
1148
+ @classmethod
1149
+ def expected_name(cls) -> str:
1150
+ return "external_function"
1151
+
1152
+
1146
1153
  class StandardEvalFunction(EvalFunctionConfig):
1147
1154
  """Class for standard Model CI eval functions that have not been added as attributes on
1148
1155
  AvailableEvalFunctions yet.
1149
1156
  """
1150
1157
 
1151
- def __init__(self, eval_function_entry: EvalFunctionEntry):
1152
- logger.warning(
1153
- "Standard function %s not implemented as an attribute on AvailableEvalFunctions",
1154
- eval_function_entry.name,
1155
- )
1156
- super().__init__(eval_function_entry)
1157
-
1158
1158
  @classmethod
1159
1159
  def expected_name(cls) -> str:
1160
1160
  return "public_function" # Placeholder: See super().eval_func_entry for actual name
@@ -1194,6 +1194,7 @@ EvalFunction = Union[
1194
1194
  CuboidPrecisionConfig,
1195
1195
  CategorizationF1Config,
1196
1196
  CustomEvalFunction,
1197
+ ExternalEvalFunction,
1197
1198
  EvalFunctionNotAvailable,
1198
1199
  StandardEvalFunction,
1199
1200
  PolygonMAPConfig,
@@ -1205,7 +1206,6 @@ EvalFunction = Union[
1205
1206
  SegmentationToPolyMAPConfig,
1206
1207
  SegmentationToPolyPrecisionConfig,
1207
1208
  SegmentationToPolyAveragePrecisionConfig,
1208
- SegmentationAveragePrecisionConfig,
1209
1209
  SegmentationFWAVACCConfig,
1210
1210
  SegmentationIOUConfig,
1211
1211
  SegmentationPrecisionConfig,
@@ -1243,7 +1243,12 @@ class AvailableEvalFunctions:
1243
1243
  self._custom_to_function: Dict[str, CustomEvalFunction] = {
1244
1244
  f.name: CustomEvalFunction(f)
1245
1245
  for f in available_functions
1246
- if not f.is_public
1246
+ if not f.is_public and not f.is_external_function
1247
+ }
1248
+ self._external_to_function: Dict[str, ExternalEvalFunction] = {
1249
+ f.name: ExternalEvalFunction(f)
1250
+ for f in available_functions
1251
+ if f.is_external_function
1247
1252
  }
1248
1253
  self.bbox_iou: BoundingBoxIOUConfig = (
1249
1254
  self._assign_eval_function_if_defined(BoundingBoxIOUConfig)
@@ -1297,9 +1302,6 @@ class AvailableEvalFunctions:
1297
1302
  self.seg_iou: SegmentationIOUConfig = self._assign_eval_function_if_defined(
1298
1303
  SegmentationIOUConfig # type: ignore
1299
1304
  )
1300
- self.seg_ap: SegmentationAveragePrecisionConfig = self._assign_eval_function_if_defined(
1301
- SegmentationAveragePrecisionConfig # type: ignore
1302
- )
1303
1305
  self.seg_recall: SegmentationRecallConfig = self._assign_eval_function_if_defined(
1304
1306
  SegmentationRecallConfig # type: ignore
1305
1307
  )
@@ -1326,8 +1328,9 @@ class AvailableEvalFunctions:
1326
1328
  str(name).lower() for name in self._public_func_entries.keys()
1327
1329
  ]
1328
1330
  return (
1329
- f"<AvailableEvaluationFunctions: public:{functions_lower} "
1330
- f"private: {list(self._custom_to_function.keys())}"
1331
+ f"<AvailableEvaluationFunctions: public: {functions_lower} "
1332
+ f"private: {list(self._custom_to_function.keys())} "
1333
+ f"external: {list(self._external_to_function.keys())}"
1331
1334
  )
1332
1335
 
1333
1336
  @property
@@ -1344,13 +1347,22 @@ class AvailableEvalFunctions:
1344
1347
 
1345
1348
  @property
1346
1349
  def private_functions(self) -> Dict[str, CustomEvalFunction]:
1347
- """Custom functions uploaded to Model CI
1350
+ """Private functions uploaded to Model CI
1348
1351
 
1349
1352
  Returns:
1350
1353
  Dict of function name to :class:`CustomEvalFunction`.
1351
1354
  """
1352
1355
  return self._custom_to_function
1353
1356
 
1357
+ @property
1358
+ def external_functions(self) -> Dict[str, ExternalEvalFunction]:
1359
+ """External functions uploaded to Model CI
1360
+
1361
+ Returns:
1362
+ Dict of function name to :class:`ExternalEvalFunction`.
1363
+ """
1364
+ return self._external_to_function
1365
+
1354
1366
  def _assign_eval_function_if_defined(
1355
1367
  self,
1356
1368
  eval_function_constructor: Callable[[EvalFunctionEntry], EvalFunction],
@@ -1372,6 +1384,7 @@ class AvailableEvalFunctions:
1372
1384
  for eval_func in itertools.chain(
1373
1385
  self._public_to_function.values(),
1374
1386
  self._custom_to_function.values(),
1387
+ self._external_to_function.values(),
1375
1388
  ):
1376
1389
  if eval_func.id == eval_function_id:
1377
1390
  return eval_func
@@ -80,12 +80,12 @@ class SegmentationMAPConfig(EvalFunctionConfig):
80
80
  import nucleus
81
81
 
82
82
  client = nucleus.NucleusClient(YOUR_SCALE_API_KEY)
83
- poly_map: BoundingBoxMeanAveragePrecision= client.validate.eval_functions.poly_map
83
+ seg_map: SegmentationMAP= client.validate.eval_functions.seg_map
84
84
  slice_id = "slc_<your_slice>"
85
85
  scenario_test = client.validate.create_scenario_test(
86
86
  "Example test",
87
87
  slice_id=slice_id,
88
- evaluation_criteria=[poly_map(iou_threshold=0.6) > 0.8]
88
+ evaluation_criteria=[seg_map(iou_threshold=0.6) > 0.8]
89
89
  )
90
90
 
91
91
  Args:
@@ -231,50 +231,6 @@ class SegmentationPrecisionConfig(EvalFunctionConfig):
231
231
  return "seg_precision"
232
232
 
233
233
 
234
- class SegmentationAveragePrecisionConfig(EvalFunctionConfig):
235
- def __call__(
236
- self,
237
- annotation_filters: Optional[
238
- Union[ListOfOrAndFilters, ListOfAndFilters]
239
- ] = None,
240
- prediction_filters: Optional[
241
- Union[ListOfOrAndFilters, ListOfAndFilters]
242
- ] = None,
243
- **kwargs,
244
- ):
245
- """Initializes SegmentationAveragePrecision object.
246
-
247
- Args:
248
- annotation_filters: Filter predicates. Allowed formats are:
249
- ListOfAndFilters where each Filter forms a chain of AND predicates.
250
- or
251
- ListOfOrAndFilters where Filters are expressed in disjunctive normal form (DNF), like
252
- [[MetadataFilter("short_haired", "==", True), FieldFilter("label", "in", ["cat", "dog"]), ...].
253
- DNF allows arbitrary boolean logical combinations of single field predicates. The innermost structures
254
- each describe a single column predicate. The list of inner predicates is interpreted as a conjunction
255
- (AND), forming a more selective `and` multiple field predicate.
256
- Finally, the most outer list combines these filters as a disjunction (OR).
257
- prediction_filters: Filter predicates. Allowed formats are:
258
- ListOfAndFilters where each Filter forms a chain of AND predicates.
259
- or
260
- ListOfOrAndFilters where Filters are expressed in disjunctive normal form (DNF), like
261
- [[MetadataFilter("short_haired", "==", True), FieldFilter("label", "in", ["cat", "dog"]), ...].
262
- DNF allows arbitrary boolean logical combinations of single field predicates. The innermost structures
263
- each describe a single column predicate. The list of inner predicates is interpreted as a conjunction
264
- (AND), forming a more selective `and` multiple field predicate.
265
- Finally, the most outer list combines these filters as a disjunction (OR).
266
- """
267
- return super().__call__(
268
- annotation_filters=annotation_filters,
269
- prediction_filters=prediction_filters,
270
- **kwargs,
271
- )
272
-
273
- @classmethod
274
- def expected_name(cls) -> str:
275
- return "seg_ap"
276
-
277
-
278
234
  class SegmentationFWAVACCConfig(EvalFunctionConfig):
279
235
  def __call__(
280
236
  self,
@@ -18,9 +18,12 @@ from .constants import (
18
18
  THRESHOLD_KEY,
19
19
  ThresholdComparison,
20
20
  )
21
- from .data_transfer_objects.scenario_test_evaluations import GetEvalHistory
21
+ from .data_transfer_objects.scenario_test_evaluations import EvaluationResult
22
22
  from .data_transfer_objects.scenario_test_metric import AddScenarioTestFunction
23
- from .eval_functions.available_eval_functions import EvalFunction
23
+ from .eval_functions.available_eval_functions import (
24
+ EvalFunction,
25
+ ExternalEvalFunction,
26
+ )
24
27
  from .scenario_test_evaluation import ScenarioTestEvaluation
25
28
  from .scenario_test_metric import ScenarioTestMetric
26
29
 
@@ -46,13 +49,24 @@ class ScenarioTest:
46
49
  slice_id: str = field(init=False)
47
50
  baseline_model_id: Optional[str] = None
48
51
 
49
- def __post_init__(self):
52
+ @classmethod
53
+ def from_id(cls, unit_test_id: str, connection: Connection):
50
54
  # TODO(gunnar): Remove this pattern. It's too slow. We should get all the info required in one call
51
- response = self.connection.get(
52
- f"validate/scenario_test/{self.id}/info",
55
+ response = connection.get(
56
+ f"validate/scenario_test/{unit_test_id}/info",
53
57
  )
54
- self.name = response[NAME_KEY]
55
- self.slice_id = response[SLICE_ID_KEY]
58
+ instance = cls(unit_test_id, connection)
59
+ instance.name = response[NAME_KEY]
60
+ instance.slice_id = response[SLICE_ID_KEY]
61
+ return instance
62
+
63
+ @classmethod
64
+ def from_response(cls, response, connection: Connection):
65
+ instance = cls(response["id"], connection)
66
+ instance.name = response[NAME_KEY]
67
+ instance.slice_id = response[SLICE_ID_KEY]
68
+ instance.baseline_model_id = response.get("baseline_model_id", None)
69
+ return instance
56
70
 
57
71
  def add_eval_function(
58
72
  self, eval_function: EvalFunction
@@ -83,9 +97,13 @@ class ScenarioTest:
83
97
  Args:
84
98
  eval_function: :class:`EvalFunction`
85
99
 
100
+ Raises:
101
+ NucleusAPIError: By adding this function, the scenario test mixes external with non-external functions which is not permitted.
102
+
86
103
  Returns:
87
104
  The created ScenarioTestMetric object.
88
105
  """
106
+
89
107
  response = self.connection.post(
90
108
  AddScenarioTestFunction(
91
109
  scenario_test_name=self.name,
@@ -93,7 +111,7 @@ class ScenarioTest:
93
111
  ).dict(),
94
112
  "validate/scenario_test_eval_function",
95
113
  )
96
- print(response)
114
+
97
115
  return ScenarioTestMetric(
98
116
  scenario_test_id=response[SCENARIO_TEST_ID_KEY],
99
117
  eval_function_id=response[EVAL_FUNCTION_ID_KEY],
@@ -138,13 +156,13 @@ class ScenarioTest:
138
156
  A list of :class:`ScenarioTestEvaluation` objects.
139
157
  """
140
158
  response = self.connection.get(
141
- f"validate/scenario_test/{self.id}/eval_history",
159
+ f"validate/scenario_test/{self.id}/eval_history/details",
142
160
  )
143
- eval_history = GetEvalHistory.parse_obj(response)
144
- return [
145
- ScenarioTestEvaluation(evaluation.id, self.connection)
146
- for evaluation in eval_history.evaluations
161
+ evaluations = [
162
+ ScenarioTestEvaluation.from_request(eval_payload, self.connection)
163
+ for eval_payload in response
147
164
  ]
165
+ return evaluations
148
166
 
149
167
  def get_items(self) -> List[DatasetItem]:
150
168
  response = self.connection.get(
@@ -174,3 +192,43 @@ class ScenarioTest:
174
192
  )
175
193
  self.baseline_model_id = response.get("baseline_model_id")
176
194
  return self.baseline_model_id
195
+
196
+ def upload_external_evaluation_results(
197
+ self,
198
+ eval_fn: ExternalEvalFunction,
199
+ results: List[EvaluationResult],
200
+ model_id: str,
201
+ ):
202
+ assert (
203
+ eval_fn.eval_func_entry.is_external_function
204
+ ), "Submitting evaluation results is only available for external functions."
205
+
206
+ assert (
207
+ len(results) > 0
208
+ ), "Submitting evaluation requires at least one result."
209
+
210
+ metric_per_ref_id = {}
211
+ weight_per_ref_id = {}
212
+ aggregate_weighted_sum = 0.0
213
+ aggregate_weight = 0.0
214
+ # aggregation based on https://en.wikipedia.org/wiki/Weighted_arithmetic_mean
215
+ for r in results:
216
+ metric_per_ref_id[r.item_ref_id] = r.score
217
+ weight_per_ref_id[r.item_ref_id] = r.weight
218
+ aggregate_weighted_sum += r.score * r.weight
219
+ aggregate_weight += r.weight
220
+
221
+ payload = {
222
+ "unit_test_id": self.id,
223
+ "eval_function_id": eval_fn.id,
224
+ "result_per_ref_id": metric_per_ref_id,
225
+ "weight_per_ref_id": weight_per_ref_id,
226
+ "overall_metric": aggregate_weighted_sum / aggregate_weight,
227
+ "model_id": model_id,
228
+ "slice_id": self.slice_id,
229
+ }
230
+ response = self.connection.post(
231
+ payload,
232
+ "validate/scenario_test/upload_results",
233
+ )
234
+ return response
@@ -1,5 +1,5 @@
1
1
  """Data types for Scenario Test Evaluation results."""
2
- from dataclasses import InitVar, dataclass, field
2
+ from dataclasses import dataclass, field
3
3
  from enum import Enum
4
4
  from typing import List, Optional
5
5
 
@@ -77,31 +77,30 @@ class ScenarioTestEvaluation:
77
77
  status: ScenarioTestEvaluationStatus = field(init=False)
78
78
  result: Optional[float] = field(init=False)
79
79
  passed: bool = field(init=False)
80
- item_evals: List[ScenarioTestItemEvaluation] = field(init=False)
81
- connection: InitVar[Connection]
82
-
83
- def __post_init__(self, connection: Connection):
84
- # TODO(gunnar): Having the function call /info on every construction is too slow. The original
85
- # endpoint should rather return the necessary human-readable information
86
- response = connection.make_request(
80
+ connection: Connection = field(init=False, repr=False)
81
+
82
+ @classmethod
83
+ def from_request(cls, response, connection):
84
+ instance = cls(response["id"])
85
+ instance.connection = connection
86
+
87
+ instance.scenario_test_id = response[SCENARIO_TEST_ID_KEY]
88
+ instance.eval_function_id = response[EVAL_FUNCTION_ID_KEY]
89
+ instance.model_id = response[MODEL_ID_KEY]
90
+ instance.status = ScenarioTestEvaluationStatus(response[STATUS_KEY])
91
+ instance.result = try_convert_float(response[RESULT_KEY])
92
+ instance.passed = bool(response[PASS_KEY])
93
+ return instance
94
+
95
+ @property
96
+ def item_evals(self) -> List[ScenarioTestItemEvaluation]:
97
+ response = self.connection.make_request(
87
98
  {},
88
99
  f"validate/eval/{self.id}/info",
89
100
  requests_command=requests.get,
90
101
  )
91
- eval_response = response[SCENARIO_TEST_EVAL_KEY]
92
102
  items_response = response[ITEM_EVAL_KEY]
93
-
94
- self.scenario_test_id: str = eval_response[SCENARIO_TEST_ID_KEY]
95
- self.eval_function_id: str = eval_response[EVAL_FUNCTION_ID_KEY]
96
- self.model_id: str = eval_response[MODEL_ID_KEY]
97
- self.status: ScenarioTestEvaluationStatus = (
98
- ScenarioTestEvaluationStatus(eval_response[STATUS_KEY])
99
- )
100
- self.result: Optional[float] = try_convert_float(
101
- eval_response[RESULT_KEY]
102
- )
103
- self.passed: bool = bool(eval_response[PASS_KEY])
104
- self.item_evals: List[ScenarioTestItemEvaluation] = [
103
+ items = [
105
104
  ScenarioTestItemEvaluation(
106
105
  evaluation_id=res[EVALUATION_ID_KEY],
107
106
  scenario_test_id=res[SCENARIO_TEST_ID_KEY],
@@ -112,3 +111,4 @@ class ScenarioTestEvaluation:
112
111
  )
113
112
  for res in items_response
114
113
  ]
114
+ return items
nucleus/validate/utils.py CHANGED
@@ -4,5 +4,5 @@ from typing import Optional
4
4
  def try_convert_float(float_str: str) -> Optional[float]:
5
5
  try:
6
6
  return float(float_str)
7
- except ValueError:
7
+ except (ValueError, TypeError):
8
8
  return None
@@ -1,31 +1,33 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scale-nucleus
3
- Version: 0.12b1
3
+ Version: 0.14.14b0
4
4
  Summary: The official Python client library for Nucleus, the Data Platform for AI
5
5
  Home-page: https://scale.com/nucleus
6
6
  License: MIT
7
7
  Author: Scale AI Nucleus Team
8
8
  Author-email: nucleusapi@scaleapi.com
9
- Requires-Python: >=3.6.2,<4.0.0
9
+ Requires-Python: >=3.6.2,<4.0
10
10
  Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.7
14
14
  Classifier: Programming Language :: Python :: 3.8
15
15
  Classifier: Programming Language :: Python :: 3.9
16
- Provides-Extra: shapely
17
- Requires-Dist: Pillow (>=8.3.1)
18
- Requires-Dist: Shapely (>=1.8.0); extra == "shapely"
16
+ Provides-Extra: launch
17
+ Provides-Extra: metrics
18
+ Requires-Dist: Pillow (>=7.1.2)
19
+ Requires-Dist: Shapely (>=1.8.0); extra == "metrics"
19
20
  Requires-Dist: aiohttp (>=3.7.4,<4.0.0)
20
21
  Requires-Dist: click (>=7.1.2,<9.0)
21
22
  Requires-Dist: dataclasses (>=0.7,<0.8); python_full_version >= "3.6.1" and python_version < "3.7"
22
23
  Requires-Dist: nest-asyncio (>=1.5.1,<2.0.0)
23
- Requires-Dist: numpy (>=1.19.5,<2.0.0)
24
+ Requires-Dist: numpy (>=1.19.5); python_version >= "3.6" and python_version < "3.10"
25
+ Requires-Dist: numpy (>=1.22.0); python_version >= "3.10"
24
26
  Requires-Dist: pydantic (>=1.8.2,<2.0.0)
25
- Requires-Dist: rasterio (>=1.2.10,<2.0.0)
27
+ Requires-Dist: rasterio (>=1.2.0); extra == "metrics"
26
28
  Requires-Dist: requests (>=2.23.0,<3.0.0)
27
- Requires-Dist: rich (>=10.15.2,<11.0.0)
28
- Requires-Dist: s3fs (>=2022.1.0)
29
+ Requires-Dist: rich (>=10.15.2)
30
+ Requires-Dist: scale-launch (>=0.1.0); (python_version >= "3.7" and python_version < "4.0") and (extra == "launch")
29
31
  Requires-Dist: scikit-learn (>=0.24.0)
30
32
  Requires-Dist: scipy (>=1.4.1)
31
33
  Requires-Dist: shellingham (>=1.4.0,<2.0.0)
@@ -224,7 +226,7 @@ sphinx-autobuild . ./_build/html --watch ../nucleus
224
226
 
225
227
  ## Custom Metrics using Shapely in scale-validate
226
228
 
227
- Certain metrics use `shapely` which is added as an optional dependency.
229
+ Certain metrics use `Shapely` and `rasterio` which is added as optional dependencies.
228
230
 
229
231
  ```bash
230
232
  pip install scale-nucleus[metrics]
@@ -241,5 +243,5 @@ apt-get install libgeos-dev
241
243
 
242
244
  To develop it locally use
243
245
 
244
- `poetry install --extras shapely`
246
+ `poetry install --extras metrics`
245
247
 
@@ -8,77 +8,78 @@ cli/jobs.py,sha256=v-ArlqUyK3iPose2ihlzk7rq2W3uf5gOKmN0npNULKU,1176
8
8
  cli/models.py,sha256=IWJyL9EJZXlpul0aW2qRgZG9rhFO59M8Ux-u-yMofzI,1039
9
9
  cli/nu.py,sha256=0f71zPq4fe3I1ghhiSRQi39ENhAzoLPdhz_vh8vxSI8,2074
10
10
  cli/reference.py,sha256=RuHVhmGTZNe0MfwpL96YjJdaH0OJzg98rz4xeIu4hJU,256
11
- cli/slices.py,sha256=p7UGiUgvYKqi5iJpYSkoX3H-1GGoG5EQoOSObtkjYjg,2106
11
+ cli/slices.py,sha256=1qAeX3-50-aBEDQxz0M8REwlTg9taLExS0a4PA3r3-U,1520
12
12
  cli/tests.py,sha256=q90eo3l8yn0VxRwjWB821E709y_9xWqvFdEgPwV8vTY,4508
13
- nucleus/__init__.py,sha256=U1oWUr7PsWG1bu4EHGXygKMnpnO2mTcC7zhBemQMiuA,30290
14
- nucleus/annotation.py,sha256=qqw51aFNg4QSYymzh_tNDoSEvxssfDaAJZc3uvVvAKo,35302
13
+ nucleus/__init__.py,sha256=P9mw2bqIjffa8Ys7RlB-KznxsouPDwrRcKcrdvku5jQ,39897
14
+ nucleus/annotation.py,sha256=yAmK734BhhuJitdKvoV8FGILKCUjc72d_fEtwjjyCV4,36189
15
15
  nucleus/annotation_uploader.py,sha256=v9mlvKs1nV3LzZC5rL_gu8O366SSbvKzn9fvpkpRdpc,9477
16
16
  nucleus/async_utils.py,sha256=RhHymn-GvP9cEs-nerbjrUmGxwqvWES4yWmf_9nr-qs,6709
17
17
  nucleus/autocurate.py,sha256=Juw8V5CYKp3T-15u1QZOWaT6_fhXqGITf80eqtBNIqY,1074
18
18
  nucleus/camera_params.py,sha256=fl17aaSAZDAJIWo6F2HFvM6HKGcQh9fXvo4t3RzGMc4,3726
19
- nucleus/connection.py,sha256=GCgsNESj-SRron9H9GP7lHexmsJ31nir3DF958s_qng,2651
20
- nucleus/constants.py,sha256=MgZmfs9eSYNnpousLJyfy5BGyNbj6iWf8y3d_oVf020,4018
19
+ nucleus/connection.py,sha256=xl6Dz8io57GOn02Fbg5btnlMslEgNbijpht7JekZoD4,2862
20
+ nucleus/constants.py,sha256=ohLj4T9EjWYoh9zeVs9MmNmuKGjVrPkNJuNMUf1fH6g,4245
21
21
  nucleus/data_transfer_object/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  nucleus/data_transfer_object/dataset_details.py,sha256=1YGvfKkPSqDrXK_y5mBXyRThY07tU-nwOCYTkYCSl6k,214
23
23
  nucleus/data_transfer_object/dataset_info.py,sha256=5P_gpvAyaqXxj2ZQuzLkGN2XROaN9Me56OLybCmO3R4,940
24
24
  nucleus/data_transfer_object/dataset_size.py,sha256=oe-dXaMLpsQRDcJQRZ9Ja8JTagYz4dviZuTognEylp0,111
25
25
  nucleus/data_transfer_object/scenes_list.py,sha256=iTHE6vA47bRB6ciyEU4LArUXEXco4ArnGvZTGTeK8xs,432
26
- nucleus/dataset.py,sha256=QcMxs6vD3I8goh-s2-4UKi8j3FZMlRJRK4Ivk1SZAdQ,65054
27
- nucleus/dataset_item.py,sha256=-hZF8oYCje5bV99wjJFJDStTLr_9hzYCEMtpj_vSV2w,8779
26
+ nucleus/dataset.py,sha256=w1BF3Qwg7jA_ymEU3QLx37dzXP2AZYVsneXdfh8ezHw,70455
27
+ nucleus/dataset_item.py,sha256=NbJMHjaLIjsdF6IfsYgJgYibvNWn7BiV9dWmDX7QWeI,9148
28
28
  nucleus/dataset_item_uploader.py,sha256=oH4Ly6sIQYrkdaOqrcbU_l-n5wQnspMefpJvgdBYAUM,6938
29
29
  nucleus/deprecation_warning.py,sha256=5C9dVusR5UkUQnW2MrRkIXCfbc8ULc7xOaB134agNKk,976
30
30
  nucleus/errors.py,sha256=IAONLQq-vsFVZSCY3zWzEOyRjkiOpJ3hUquS7_jNAz8,2870
31
- nucleus/job.py,sha256=qB2kUHXrUWI6ZwctQkSYqSia1OXTcMXw6_V-610D-J8,4745
31
+ nucleus/job.py,sha256=juxzn3xB8HwGDxolANX8Ryo4xM5QCOCaOembCdxyFaQ,4745
32
32
  nucleus/logger.py,sha256=acoFtszu4T-fj_Op4rwlXNNaLPrQ8Kw2ofaYusBHO8I,208
33
33
  nucleus/metadata_manager.py,sha256=gO1jChfP7sAokr-llYv3D86eV_VPumMWfOtn6GMw-Ew,1890
34
- nucleus/metrics/__init__.py,sha256=y98Wddfo3FqhzI2iFYqFxCxkFNVc2q3FRUoZx38Le94,877
35
- nucleus/metrics/base.py,sha256=EuLggnjuvIeMaDjAsKw67cAY4GST9GVUx3AQlsdEiuE,8928
36
- nucleus/metrics/categorization_metrics.py,sha256=3pcpbzNfQrwB54cwNeZIVZeVy-ckX8xRloeujntpsjo,11790
34
+ nucleus/metrics/__init__.py,sha256=bve48T1quN_vh3zhpW1nbv8ZfFBBiT9k6d8cipu-1k0,894
35
+ nucleus/metrics/base.py,sha256=cwBE1xm-2SN6ULfRwajLwNrC8oaLU4cGxP686EP4KE8,7757
36
+ nucleus/metrics/categorization_metrics.py,sha256=sGM7Zyz1DLSUEFbaqBFEf4oNXlWvc465dMCFVI5LhcI,11934
37
37
  nucleus/metrics/cuboid_metrics.py,sha256=ZjlFNa8kknx2mJzEiJ8ZvTlvOSW0BjZzzfJiv3WHm-g,12461
38
- nucleus/metrics/cuboid_utils.py,sha256=Y0W6_UVzGZHXsDZoJ1sfQVV5Nb-ACDEBu2m1OrxF01c,11227
38
+ nucleus/metrics/cuboid_utils.py,sha256=J_HOd5c9m77naHhiS0xhbUbRwTOicN9RpGrf97ODtAY,11190
39
39
  nucleus/metrics/custom_types.py,sha256=6oWmlajz229crwEm2ImvC5vOhBXjt-HhVqj41D5uSwk,485
40
- nucleus/metrics/errors.py,sha256=1n0t4wdjzzryHlCqCcW8a-1oJmE3OXV4aoV0xjgeXCA,251
41
- nucleus/metrics/filtering.py,sha256=wIIyaWq5Ff8Q2HPoE2wXuMIwVksNc0l4JaFAh6QYFDk,12608
40
+ nucleus/metrics/errors.py,sha256=Cu2W5tSsIHpazryd-9FXzu46OLC12Wk6gQT66hxQDis,304
41
+ nucleus/metrics/filtering.py,sha256=_DLjiEmJ1uBL2ell-0pXow4gHRjMsDUL0WDhT0s7LdQ,25444
42
42
  nucleus/metrics/filters.py,sha256=SegJ2UdYSSnRJpoiqguVpGrDSGfyCK7OiREziunZw54,1140
43
43
  nucleus/metrics/metric_utils.py,sha256=1EJf3ezTQAzh4mgECrxWyiUHzUjDqA_5hV9eqZISxRU,971
44
44
  nucleus/metrics/polygon_metrics.py,sha256=mrsGc7714B944NDhLZ6pa0FbyWltuJEkd6ZVccLibdU,29277
45
- nucleus/metrics/polygon_utils.py,sha256=HzrYHIK89ebuGB8_vNnwAQXbLUuNa_-eplqzC6tyQ_g,12360
46
- nucleus/metrics/segmentation_metrics.py,sha256=zerhFKQ8FLU93L-DPmCVBeksm2Gj9o5L3nDplXQNpD8,27591
47
- nucleus/metrics/segmentation_to_poly_metrics.py,sha256=IMkePtC54HIOowpAnOEPh9KPalOFkmZPwPdhhO0yqRw,24201
48
- nucleus/metrics/segmentation_utils.py,sha256=h5X6k0RzgBXXJjRpf-HtTN5y3h32Y8xbln4e9v6HSGI,1395
49
- nucleus/model.py,sha256=DfErwRRxZemX7QJ7yZYy_Y_ou07TA3sT1xD-Rs1__lE,7193
50
- nucleus/model_run.py,sha256=BPBrTp8M1Qgqw11SS_H5FArBZNqz5Gj6i7T13hZceHQ,9538
51
- nucleus/payload_constructor.py,sha256=9CCBeDtkKIT6NVeytKtFzVyOHwCO54pbKeUfHGN2B_4,4339
52
- nucleus/prediction.py,sha256=yaqzUqalKUFeRLasZIkf4VmLPfeR4Tl499G3Oc4Slrc,25852
45
+ nucleus/metrics/polygon_utils.py,sha256=z1ERZepMwrmEgUz1tSBfCy9z07uqsoLZFNJ41Bl-sX4,12371
46
+ nucleus/metrics/segmentation_loader.py,sha256=GEKbdp71hIiyBwrZm7qkLJ1fFH_FOsDGYTSuZ_9GPYA,790
47
+ nucleus/metrics/segmentation_metrics.py,sha256=6PFp4ESPx3gUWqxF7HOtDm44_j_Sdp2lTi1P0bkEFas,29522
48
+ nucleus/metrics/segmentation_to_poly_metrics.py,sha256=1C1In5Kz2CAgVy39GCF3zBBT_OBybHnbL-jlCsQYrZc,29087
49
+ nucleus/metrics/segmentation_utils.py,sha256=uvypa95DX66sDIHHdE5xUjsuePTFJWePiq2OceolW3I,10075
50
+ nucleus/model.py,sha256=vbBgq0ZJEWL-1-w_rWMZiYmH5N3rDX_pY2Gvlg_QwmQ,8738
51
+ nucleus/model_run.py,sha256=Epbr-M2m0qOZY2AR9r-tzX6Au9i9bbk2Vwb5mw27i0Q,9541
52
+ nucleus/package_not_installed.py,sha256=1ae0aqKAM3KrB0C-5MuPPXoz9tLWJUKtP1UZ-vw9Zik,1117
53
+ nucleus/payload_constructor.py,sha256=-x4UYu_NHTaWfbrhEx9USUKH2q6wZzelh1gGG_-2nQM,4442
54
+ nucleus/prediction.py,sha256=D91YVjHvtGFmVuJjUS1LfxeJiJcMORJUtfhQP3FFxaY,25921
53
55
  nucleus/pydantic_base.py,sha256=EQER8_XqG4B-RC4aggUfukJa6f5OZ7ej92AsDWWIWPc,682
54
56
  nucleus/quaternion.py,sha256=TAnwj4arQXoTeofFgZMdZsCyxAMnu23N6to0F1WFNwk,1111
55
57
  nucleus/retry_strategy.py,sha256=daKZqjZYCh87WtXoVUuR9BZu2TTE-CtOFEYZ-d6xVMY,312
56
- nucleus/scene.py,sha256=l4bKjDDdnjJGB-YBXhQW4CzhEnn_4b1YIyGBm8mGTUs,25881
57
- nucleus/shapely_not_installed.py,sha256=cTcMPnU5UowaSLaA2abnO6pr1YZi3LSY1hJlCaQVLuU,1117
58
- nucleus/slice.py,sha256=wf5MAoGdN0Rf4dIyEh__3vSvHAGgJiobYJ8KxRoM-H0,12926
58
+ nucleus/scene.py,sha256=4mQLstDi9GNRP7EGr4nLcHN9ALIldgR6Yw4hrBaULVk,26149
59
+ nucleus/slice.py,sha256=2MR6dbFjEHc7vji45KdFI-4BKWgTWBoCN4TssvKnXgE,18767
59
60
  nucleus/upload_response.py,sha256=wR_pfZCBju1vGiGqbVgk8zhM6GhD3ebYxyGBm8y0GvY,3287
60
61
  nucleus/url_utils.py,sha256=EZ3vy1FYTGvXRVNyq43Wif-ypS8LFoDrYMYJre_DVuQ,790
61
- nucleus/utils.py,sha256=ADuXXrxBDe7LbvJE3QXQB7E3CRgQKg4u6EMBSsVvRyQ,11491
62
- nucleus/validate/__init__.py,sha256=yXQ1jZSARDSDDXqQMNYq2ygcBrk1frDl0r9AuG3m3wE,695
63
- nucleus/validate/client.py,sha256=FYblCtqyyCMoYYQSNxthA15-PqjMcF2NlB634RGbY8Y,6277
64
- nucleus/validate/constants.py,sha256=AmQyiPMGwfQ-czg78fTqML9BSZCVAEidyn5MHcukTco,633
62
+ nucleus/utils.py,sha256=fxISxhIPbAeBBRs25YG_kRnRfHKxpisXv-AF9uHZGCA,12653
63
+ nucleus/validate/__init__.py,sha256=de4m8RfJXSMBD8lF_mR0NAedP4Y5F03jHqNU0-XHSjI,773
64
+ nucleus/validate/client.py,sha256=0QcF2u1g513NjvR_CID0M6zM0jqRthSqBY9zla6LBZg,7786
65
+ nucleus/validate/constants.py,sha256=aHCX56E-yqsbIzeLbstaOhPqZOEXQptn4-zr74NDgzw,663
65
66
  nucleus/validate/data_transfer_objects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
- nucleus/validate/data_transfer_objects/eval_function.py,sha256=DP5blh2rP_mtIdG9E2wFI4o3URqxCrX-tVKMVW4aGTY,3150
67
+ nucleus/validate/data_transfer_objects/eval_function.py,sha256=5scyeLfQhTWdNWrdybUEf5MIJJ0r9xdyfUO-aeYq7cQ,3828
67
68
  nucleus/validate/data_transfer_objects/scenario_test.py,sha256=6gFGzBkl9y0Z5yNI_QtAC_TDPbLWqG0_pPAteDF0vnw,574
68
- nucleus/validate/data_transfer_objects/scenario_test_evaluations.py,sha256=zKNKWJQHY9UL2Cvj2JacBP2CoJRKFjw64FeW5O0bVMo,196
69
+ nucleus/validate/data_transfer_objects/scenario_test_evaluations.py,sha256=MsQQp8ls5g91MzsyD6-n9KdBqV_rKrjOe3wfCbfSDoA,491
69
70
  nucleus/validate/data_transfer_objects/scenario_test_metric.py,sha256=jXGwPx0Y99ga0RfzwGMCG3_06NkiFsp0yHxUuGFJ2EI,208
70
71
  nucleus/validate/errors.py,sha256=UOI4oPeVzNLEmibWayfMdCMFNZvgsq-VRG42vC1cT_w,110
71
72
  nucleus/validate/eval_functions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
- nucleus/validate/eval_functions/available_eval_functions.py,sha256=MhU2ybIaQVjkQS6VjShCabJu640szIn6A4F5mlu3EQQ,68576
73
+ nucleus/validate/eval_functions/available_eval_functions.py,sha256=Uv3SeXLocbvAvWhyZafeOc3pc_Fd238xdtqyx7k4_tk,68938
73
74
  nucleus/validate/eval_functions/base_eval_function.py,sha256=bMwK1oTiVmQOJZ07S6p7cr5ZHaHlt6idMZY7yV-9fjw,2207
74
75
  nucleus/validate/eval_functions/config_classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
- nucleus/validate/eval_functions/config_classes/segmentation.py,sha256=ypbpPKRknqO6dLXedtbShIt6lGdwk6h1Qt_tc9tR-mQ,15706
76
- nucleus/validate/scenario_test.py,sha256=fzRg_i_TgW-oGktZYK__T4ybqFC_4SlAzOz0FbIJ-BI,6581
77
- nucleus/validate/scenario_test_evaluation.py,sha256=IoqyIok2Kbug2AEmWzvmBKne14gvnFPeD9bt5CE4Wpk,4316
76
+ nucleus/validate/eval_functions/config_classes/segmentation.py,sha256=Hk6yDYDwdKgjamfQJEOpyzQLP4zMqcz_I2cLnDBXtz0,13409
77
+ nucleus/validate/scenario_test.py,sha256=1FQanSrvh72TPiJwSAdNRkb6gfNPyauVo-1s8apiZRo,8597
78
+ nucleus/validate/scenario_test_evaluation.py,sha256=Q0WzaEE9uUbPVc4EHlCoKjhJcqMNt4QbyiiJx12VOR0,4075
78
79
  nucleus/validate/scenario_test_metric.py,sha256=AhVFOB1ULwBqlZ2X_Au1TXy4iQELljtzR4ZpeLB35So,1209
79
- nucleus/validate/utils.py,sha256=yq5LCQJ1smoQWEGnIFltNTq2skrRtBWp6iK3E_u2lj0,172
80
- scale_nucleus-0.12b1.dist-info/entry_points.txt,sha256=fmqEzh6NZQyg9eFMILnWabKT8OWQTMSCdDzMiVq2zYs,32
81
- scale_nucleus-0.12b1.dist-info/LICENSE,sha256=jaTGyQSQIZeWMo5iyYqgbAYHR9Bdy7nOzgE-Up3m_-g,1075
82
- scale_nucleus-0.12b1.dist-info/WHEEL,sha256=y3eDiaFVSNTPbgzfNn0nYn5tEn1cX6WrdetDlQM4xWw,83
83
- scale_nucleus-0.12b1.dist-info/METADATA,sha256=cMS28e5K79vaI5JrVaEAkEB2n-52dJT550CxmQi2pTg,7506
84
- scale_nucleus-0.12b1.dist-info/RECORD,,
80
+ nucleus/validate/utils.py,sha256=VjdIJj9Pii4z4L6xbvClAc7ra_J7cX0vWB_J2X6yrGE,185
81
+ scale_nucleus-0.14.14b0.dist-info/entry_points.txt,sha256=fmqEzh6NZQyg9eFMILnWabKT8OWQTMSCdDzMiVq2zYs,32
82
+ scale_nucleus-0.14.14b0.dist-info/LICENSE,sha256=jaTGyQSQIZeWMo5iyYqgbAYHR9Bdy7nOzgE-Up3m_-g,1075
83
+ scale_nucleus-0.14.14b0.dist-info/WHEEL,sha256=DA86_h4QwwzGeRoz62o1svYt5kGEXpoUTuTtwzoTb30,83
84
+ scale_nucleus-0.14.14b0.dist-info/METADATA,sha256=KYRHazVKZ2BXxUYGGCpTbpKrpIOtJtZ8xT4hmXpkIGE,7735
85
+ scale_nucleus-0.14.14b0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry 1.0.7
2
+ Generator: poetry 1.0.8
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any