euler-eval 2.33.0__tar.gz → 2.35.0__tar.gz
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.
- {euler_eval-2.33.0/euler_eval.egg-info → euler_eval-2.35.0}/PKG-INFO +1 -1
- {euler_eval-2.33.0 → euler_eval-2.35.0}/docs/configuration.md +15 -12
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/cli.py +27 -18
- {euler_eval-2.33.0 → euler_eval-2.35.0/euler_eval.egg-info}/PKG-INFO +1 -1
- {euler_eval-2.33.0 → euler_eval-2.35.0}/pyproject.toml +1 -1
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_experiments.py +104 -24
- {euler_eval-2.33.0 → euler_eval-2.35.0}/LICENSE +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/MANIFEST.in +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/README.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/docs/README.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/docs/alignment.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/docs/cli.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/docs/distributions.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/docs/feature-request-unified-evaluation-framework.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/docs/metrics.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/docs/output.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/docs/validation.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/THIRD_PARTY_NOTICES.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/__init__.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/calibration.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/config_paths.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/data.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/distribution_contract.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/distributions.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/evaluate.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metric_sets.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/__init__.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/_natural_scene_models.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/absrel.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/daniel_error.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/depth_binned_error.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/depth_edge_f1.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/depth_standard.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/fade.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/fid_kid.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/gpu_depth_batch.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/gpu_image_batch.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/high_freq_energy.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/lpips_metric.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/niqe.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/normal_consistency.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/points3d_cloud.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/points3d_decomposition.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/points3d_distance.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/points3d_geometry.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/psnr.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/rgb_edge_f1.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/rgb_lpips.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/rgb_psnr_ssim.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/rho_a.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/rmse.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/scale_invariant_log.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/sky_iou.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/ssim.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/tail_errors.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/metrics/utils.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/protocol.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/sanity_checker.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/schemas/distribution-v1.schema.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/utils/hierarchy_parser.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval/validation.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval.egg-info/SOURCES.txt +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval.egg-info/dependency_links.txt +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval.egg-info/entry_points.txt +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval.egg-info/requires.txt +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/euler_eval.egg-info/top_level.txt +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/init_cache.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/scripts/generate_distribution_fixtures.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/setup.cfg +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/__init__.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/conftest.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/distribution_contract_utils.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/eval_output.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/README.md +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/counts-depth.eval.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/counts-points3d.eval.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/counts-sparsedepth.eval.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/future-sum-by-depth.eval.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/histogram-only.eval.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/per-file-only.eval.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/scalar-only.eval.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/mock_files/calibration_output.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/mock_files/depth_output.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/mock_files/rgb_output.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/mock_files/segmentation_output.json +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_alignment.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_cli_device.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_cli_sparse_outputs.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_config.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_data.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_data_builders.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_depth_alignment_output.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_depth_standard.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_distribution_contract.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_distributions.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_domain_metrics.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_evaluate_helpers.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_init_cache.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_integration.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_mask_sky_pairing.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_mask_sky_prediction.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_meta_output.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_metrics_utils.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_normal_consistency.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_points_3d.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_points_3d_sparse.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_protocol.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_rgb_fid_output.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_rho_a.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_save_results.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_sky_iou.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_sky_iou_cli.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_sparse_depth.py +0 -0
- {euler_eval-2.33.0 → euler_eval-2.35.0}/tests/test_validation.py +0 -0
|
@@ -272,7 +272,7 @@ command-line flags and under its own name:
|
|
|
272
272
|
|---|---|---|
|
|
273
273
|
| `name` | yes | Evaluation name: results are written as `<name>.json` in each prediction dataset's `.eval/` folder ([where results land](output.md#where-results-land)). Same rules as `--eval-name`; unique |
|
|
274
274
|
| `args` | no | Command-line tokens this experiment adds, exactly as you would type them; numbers may be written as JSON numbers |
|
|
275
|
-
| `modalities` | no | The
|
|
275
|
+
| `modalities` | no | The prediction modalities (`datasets[]` entries) this experiment may load (default: all): `depth` (also covers `relative_depth` and `affine_depth`), `rgb`, `rays`, `points_3d`, `sky_mask`. The `gt` section is always used as configured |
|
|
276
276
|
|
|
277
277
|
- **The command line is the base.** Each experiment runs with the flags given on
|
|
278
278
|
the command line followed by its own `args`, so for a flag that takes a
|
|
@@ -283,17 +283,20 @@ command-line flags and under its own name:
|
|
|
283
283
|
validated before the first one runs. `--eval-name` and `--experiment` are not
|
|
284
284
|
allowed in `args`, and `--eval-name` cannot be combined with an `experiments`
|
|
285
285
|
section, because `name` names the results.
|
|
286
|
-
- **Modalities.** An experiment with `modalities` runs as if the unlisted
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
286
|
+
- **Modalities.** An experiment with `modalities` runs as if the unlisted
|
|
287
|
+
prediction entries were not in `datasets[]`; a `sky_mask` goes with its depth
|
|
288
|
+
prediction. GT inputs are not selected this way: they stay as configured,
|
|
289
|
+
and flags decide which ones an evaluation reads (`--mask-sky` the
|
|
290
|
+
segmentation, for example), so GT names such as `segmentation` or
|
|
291
|
+
`sparse_depth` are rejected. A listed modality is still read only when the
|
|
292
|
+
evaluation needs it, e.g. `sky_mask` only with `--sky-depth`,
|
|
293
|
+
`--mask-sky-prediction` or `--sky-iou`; with just `--mask-sky`, listing
|
|
294
|
+
`sky_mask` changes nothing. This is how to compare runs where a modality's
|
|
295
|
+
presence changes the output: above, `capped_no_mask` caps depth at 80 m
|
|
296
|
+
without filling the predicted sky. A dataset left without a prediction is
|
|
297
|
+
not evaluated in that experiment. Listing a modality no dataset has only
|
|
298
|
+
prints a warning, so one experiment list can serve several generated
|
|
299
|
+
configs.
|
|
297
300
|
- **Selecting experiments.** By default all experiments run, in config order.
|
|
298
301
|
`--experiment NAME` (repeatable) runs only the named ones, e.g. one per task
|
|
299
302
|
of a job array.
|
|
@@ -273,24 +273,28 @@ def _points_3d_eval_axes(*, distributions: bool = False) -> dict[str, AxisDeclar
|
|
|
273
273
|
|
|
274
274
|
_PRED_DEPTH_KEYS = ("depth", "relative_depth", "affine_depth")
|
|
275
275
|
|
|
276
|
-
#:
|
|
277
|
-
#:
|
|
276
|
+
#: Prediction modalities an experiment's ``modalities`` may list, and the
|
|
277
|
+
#: ``datasets[]`` keys each one covers. GT inputs are not selected this way:
|
|
278
|
+
#: they are used as configured, and flags such as ``--mask-sky`` decide
|
|
279
|
+
#: which of them an evaluation reads.
|
|
278
280
|
_EXPERIMENT_MODALITIES = {
|
|
279
281
|
"depth": _PRED_DEPTH_KEYS,
|
|
280
|
-
"sparse_depth": ("sparse_depth",),
|
|
281
282
|
"rgb": ("rgb",),
|
|
282
283
|
"rays": ("rays",),
|
|
283
284
|
"points_3d": ("points_3d",),
|
|
284
285
|
"sky_mask": ("sky_mask",),
|
|
285
|
-
"segmentation": GT_SEGMENTATION_KEYS,
|
|
286
|
-
"calibration": ("calibration",),
|
|
287
|
-
"intrinsics": ("intrinsics",),
|
|
288
|
-
"camera_extrinsics": ("camera_extrinsics",),
|
|
289
|
-
"lidar_extrinsics": ("lidar_extrinsics",),
|
|
290
286
|
}
|
|
291
287
|
_MODALITY_OF_CONFIG_KEY = {
|
|
292
288
|
key: name for name, keys in _EXPERIMENT_MODALITIES.items() for key in keys
|
|
293
289
|
}
|
|
290
|
+
_GT_ONLY_KEYS = (
|
|
291
|
+
"sparse_depth",
|
|
292
|
+
*GT_SEGMENTATION_KEYS,
|
|
293
|
+
"calibration",
|
|
294
|
+
"intrinsics",
|
|
295
|
+
"camera_extrinsics",
|
|
296
|
+
"lidar_extrinsics",
|
|
297
|
+
)
|
|
294
298
|
|
|
295
299
|
# Downstream eval consumers validate metricSet.metricNamespace with a stricter
|
|
296
300
|
# first-segment rule than euler_metric_naming's modality validator. Keep the
|
|
@@ -1166,6 +1170,12 @@ def _validate_experiment_modalities(modalities, label: str) -> None:
|
|
|
1166
1170
|
'e.g. ["depth", "sky_mask"]'
|
|
1167
1171
|
)
|
|
1168
1172
|
for name in modalities:
|
|
1173
|
+
if name in _GT_ONLY_KEYS:
|
|
1174
|
+
raise ValueError(
|
|
1175
|
+
f"{label}.modalities: {name!r} is a GT input; 'modalities' selects "
|
|
1176
|
+
"prediction modalities, and GT inputs are used as configured "
|
|
1177
|
+
"(flags such as --mask-sky decide which ones are read)"
|
|
1178
|
+
)
|
|
1169
1179
|
if name not in _EXPERIMENT_MODALITIES:
|
|
1170
1180
|
covered_by = _MODALITY_OF_CONFIG_KEY.get(name)
|
|
1171
1181
|
hint = f" (use {covered_by!r}, which covers it)" if covered_by else ""
|
|
@@ -1185,21 +1195,21 @@ def _has_prediction(entry: dict) -> bool:
|
|
|
1185
1195
|
|
|
1186
1196
|
|
|
1187
1197
|
def _configured_modalities(config: dict) -> set[str]:
|
|
1188
|
-
sections = [config["gt"], *config["datasets"]]
|
|
1189
1198
|
return {
|
|
1190
1199
|
_MODALITY_OF_CONFIG_KEY[key]
|
|
1191
|
-
for
|
|
1192
|
-
for key in
|
|
1200
|
+
for entry in config["datasets"]
|
|
1201
|
+
for key in entry
|
|
1193
1202
|
if key in _MODALITY_OF_CONFIG_KEY
|
|
1194
1203
|
}
|
|
1195
1204
|
|
|
1196
1205
|
|
|
1197
1206
|
def _experiment_config(config: dict, modalities: list[str] | None) -> dict:
|
|
1198
|
-
"""Return *config*
|
|
1207
|
+
"""Return *config* with only the prediction modalities an experiment lists.
|
|
1199
1208
|
|
|
1200
|
-
Unlisted
|
|
1201
|
-
|
|
1202
|
-
a ``sky_mask`` is dropped with the depth
|
|
1209
|
+
Unlisted ``datasets[]`` entries are left out, as if they were not
|
|
1210
|
+
configured; the ``gt`` section is unchanged. A dataset left without a
|
|
1211
|
+
prediction is not evaluated, and a ``sky_mask`` is dropped with the depth
|
|
1212
|
+
prediction it belongs to.
|
|
1203
1213
|
"""
|
|
1204
1214
|
if modalities is None:
|
|
1205
1215
|
return config
|
|
@@ -1220,7 +1230,7 @@ def _experiment_config(config: dict, modalities: list[str] | None) -> dict:
|
|
|
1220
1230
|
entry.pop("sky_mask", None)
|
|
1221
1231
|
if _has_prediction(entry):
|
|
1222
1232
|
datasets.append(entry)
|
|
1223
|
-
return {**config, "
|
|
1233
|
+
return {**config, "datasets": datasets}
|
|
1224
1234
|
|
|
1225
1235
|
|
|
1226
1236
|
def load_config(config_path: str) -> dict:
|
|
@@ -1652,7 +1662,6 @@ def _experiment_runs(
|
|
|
1652
1662
|
parser.raise_errors = True
|
|
1653
1663
|
try:
|
|
1654
1664
|
if modalities is not None:
|
|
1655
|
-
validate_gt_config(run_config["gt"])
|
|
1656
1665
|
if not run_config["datasets"]:
|
|
1657
1666
|
raise ValueError(
|
|
1658
1667
|
"'modalities' leave no dataset with a prediction to evaluate"
|
|
@@ -1679,7 +1688,7 @@ def _experiment_runs(
|
|
|
1679
1688
|
if run_args.sky_iou and _gt_segmentation_entry(run_config["gt"])[1] is None:
|
|
1680
1689
|
raise ValueError(
|
|
1681
1690
|
"--sky-iou requires gt.segmentation (or its alias "
|
|
1682
|
-
"gt.semantic_segmentation)
|
|
1691
|
+
"gt.semantic_segmentation) in config"
|
|
1683
1692
|
)
|
|
1684
1693
|
runs.append(
|
|
1685
1694
|
_prepare_run(run_args, run_config, name=name, extra_args=tuple(extra))
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"""Config ``experiments``: several named argument sets in one invocation."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
+
import zipfile
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
|
|
6
7
|
import pytest
|
|
7
8
|
|
|
8
9
|
from euler_eval import cli
|
|
9
10
|
from euler_eval.cli import default_eval_path, validate_experiments_config
|
|
11
|
+
from tests.test_cli_sparse_outputs import _sparse_depth_results
|
|
10
12
|
from tests.test_depth_alignment_output import _patch_depth_metrics
|
|
11
13
|
from tests.test_sky_iou_cli import write_gt_segmentation
|
|
12
14
|
|
|
@@ -293,20 +295,20 @@ def test_modalities_decide_whether_the_sky_mask_is_used(
|
|
|
293
295
|
assert capped["meta"]["pred"].get("sky_mask") is None
|
|
294
296
|
|
|
295
297
|
|
|
296
|
-
def
|
|
298
|
+
def test_modalities_keep_every_gt_input(monkeypatch, tmp_path, indexed_sky_prediction):
|
|
299
|
+
"""'modalities' selects predictions; GT segmentation stays for --mask-sky."""
|
|
297
300
|
_patch_depth_metrics(monkeypatch)
|
|
298
301
|
pred = indexed_sky_prediction["pred"]
|
|
299
302
|
seg = write_gt_segmentation(tmp_path / "segmentation")
|
|
300
303
|
_main(monkeypatch, _sky_config(
|
|
301
304
|
tmp_path, indexed_sky_prediction,
|
|
302
|
-
[{"name": "
|
|
305
|
+
[{"name": "eval", "modalities": ["depth"], "args": ["--mask-sky"]}],
|
|
303
306
|
gt_extra={"segmentation": {"path": seg}},
|
|
304
307
|
))
|
|
305
308
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
assert
|
|
309
|
-
assert reduced["reference.segmentation.dataset"] is None
|
|
309
|
+
parameters = _results(pred, "eval")["protocol"]["parameters"]
|
|
310
|
+
assert parameters["population.gt_sky_masking"] is True
|
|
311
|
+
assert parameters["reference.segmentation.dataset"] == "sky_iou_test"
|
|
310
312
|
|
|
311
313
|
|
|
312
314
|
def test_unconfigured_modalities_only_warn(
|
|
@@ -314,40 +316,46 @@ def test_unconfigured_modalities_only_warn(
|
|
|
314
316
|
):
|
|
315
317
|
_patch_depth_metrics(monkeypatch)
|
|
316
318
|
_main(monkeypatch, _sky_config(tmp_path, indexed_sky_prediction, [
|
|
317
|
-
{"name": "eval", "modalities": ["depth", "
|
|
319
|
+
{"name": "eval", "modalities": ["depth", "rays"]},
|
|
318
320
|
]))
|
|
319
321
|
|
|
320
|
-
assert "modalities ['
|
|
322
|
+
assert "modalities ['rays'] are not configured" in capsys.readouterr().err
|
|
321
323
|
assert _results(indexed_sky_prediction["pred"], "eval") is not None
|
|
322
324
|
|
|
323
325
|
|
|
324
326
|
@pytest.mark.parametrize(
|
|
325
|
-
("experiment", "message"),
|
|
327
|
+
("experiment", "with_segmentation", "message"),
|
|
326
328
|
[
|
|
327
329
|
(
|
|
328
330
|
{"name": "iou", "args": ["--sky-iou"], "modalities": ["depth"]},
|
|
331
|
+
False,
|
|
329
332
|
"experiments[0] ('iou'): --sky-iou requires gt.segmentation",
|
|
330
333
|
),
|
|
331
334
|
(
|
|
335
|
+
# A sky_mask is dropped with the depth prediction it belongs to.
|
|
332
336
|
{"name": "masks", "modalities": ["sky_mask"]},
|
|
333
|
-
|
|
337
|
+
True,
|
|
338
|
+
"experiments[0] ('masks'): 'modalities' leave no dataset with a prediction",
|
|
334
339
|
),
|
|
335
340
|
(
|
|
336
341
|
{"name": "rgb", "modalities": ["rgb"]},
|
|
342
|
+
True,
|
|
337
343
|
"experiments[0] ('rgb'): 'modalities' leave no dataset with a prediction",
|
|
338
344
|
),
|
|
339
345
|
],
|
|
340
346
|
)
|
|
341
347
|
def test_modalities_are_checked_before_any_work(
|
|
342
|
-
monkeypatch, capsys, tmp_path, indexed_sky_prediction, experiment,
|
|
348
|
+
monkeypatch, capsys, tmp_path, indexed_sky_prediction, experiment,
|
|
349
|
+
with_segmentation, message,
|
|
343
350
|
):
|
|
344
351
|
monkeypatch.setattr(cli, "evaluate_depth_samples", pytest.fail)
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
352
|
+
gt_extra = {}
|
|
353
|
+
if with_segmentation:
|
|
354
|
+
gt_extra["segmentation"] = {
|
|
355
|
+
"path": write_gt_segmentation(tmp_path / "segmentation")
|
|
356
|
+
}
|
|
348
357
|
config_path = _sky_config(
|
|
349
|
-
tmp_path, indexed_sky_prediction, [experiment],
|
|
350
|
-
gt_extra={"rgb": {"path": str(gt_rgb)}, "segmentation": {"path": seg}},
|
|
358
|
+
tmp_path, indexed_sky_prediction, [experiment], gt_extra=gt_extra
|
|
351
359
|
)
|
|
352
360
|
with pytest.raises(SystemExit) as exc:
|
|
353
361
|
_main(monkeypatch, config_path)
|
|
@@ -356,7 +364,76 @@ def test_modalities_are_checked_before_any_work(
|
|
|
356
364
|
assert f"Error loading config: {message}" in capsys.readouterr().err
|
|
357
365
|
|
|
358
366
|
|
|
359
|
-
def
|
|
367
|
+
def test_sparse_gt_config_with_prediction_modalities(monkeypatch, tmp_path):
|
|
368
|
+
"""The reported MUSES config: experiments choose predictions, GT stays whole."""
|
|
369
|
+
paths = {}
|
|
370
|
+
for name in ("lidar", "camera", "semantic", "depth", "dehazed", "points_3d",
|
|
371
|
+
"sky_mask"):
|
|
372
|
+
paths[name] = tmp_path / f"{name}.zip"
|
|
373
|
+
with zipfile.ZipFile(paths[name], "w") as zf:
|
|
374
|
+
zf.writestr("placeholder", b"data")
|
|
375
|
+
config_path = tmp_path / "config.json"
|
|
376
|
+
config_path.write_text(json.dumps({
|
|
377
|
+
"experiments": [
|
|
378
|
+
{"name": "eval", "modalities": ["depth"], "args": ["--mask-sky"]},
|
|
379
|
+
{"name": "gt_sky_with_mask", "modalities": ["depth", "sky_mask"],
|
|
380
|
+
"args": ["--mask-sky"]},
|
|
381
|
+
{"name": "gt_and_pred_sky", "modalities": ["depth", "sky_mask"],
|
|
382
|
+
"args": ["--mask-sky", "--mask-sky-prediction"]},
|
|
383
|
+
],
|
|
384
|
+
"gt": {
|
|
385
|
+
"sparse_depth": {"path": str(paths["lidar"])},
|
|
386
|
+
"rgb": {"path": f"{paths['camera']}:fog_day"},
|
|
387
|
+
"intrinsics": {"path": f"{paths['camera']}#scope=intrinsics"},
|
|
388
|
+
"camera_extrinsics": {"path": f"{paths['camera']}#scope=camera_extrinsics"},
|
|
389
|
+
"segmentation": {"path": str(paths["semantic"])},
|
|
390
|
+
},
|
|
391
|
+
"datasets": [{
|
|
392
|
+
"name": "SD 2.1. Mari",
|
|
393
|
+
"depth": {"path": str(paths["depth"])},
|
|
394
|
+
"rgb": {"path": str(paths["dehazed"])},
|
|
395
|
+
"points_3d": {"path": str(paths["points_3d"])},
|
|
396
|
+
"sky_mask": {"path": str(paths["sky_mask"])},
|
|
397
|
+
}],
|
|
398
|
+
"distributions": {"n_bins": 30, "scale": "log", "min_error": 0.001,
|
|
399
|
+
"max_error": 240.0},
|
|
400
|
+
}))
|
|
401
|
+
|
|
402
|
+
built, evaluated = [], []
|
|
403
|
+
monkeypatch.setattr(
|
|
404
|
+
cli, "build_sparse_depth_eval_dataset",
|
|
405
|
+
lambda **kwargs: built.append(kwargs) or [object()],
|
|
406
|
+
)
|
|
407
|
+
monkeypatch.setattr(
|
|
408
|
+
cli, "get_sparse_depth_metadata", lambda _ds: {"pred_radial_depth": False}
|
|
409
|
+
)
|
|
410
|
+
monkeypatch.setattr(
|
|
411
|
+
cli, "evaluate_sparse_depth_samples",
|
|
412
|
+
lambda **kwargs: evaluated.append(kwargs) or _sparse_depth_results(),
|
|
413
|
+
)
|
|
414
|
+
for unused in ("evaluate_rgb_samples", "evaluate_points_3d_sparse_samples"):
|
|
415
|
+
monkeypatch.setattr(cli, unused, pytest.fail)
|
|
416
|
+
_main(monkeypatch, config_path)
|
|
417
|
+
|
|
418
|
+
gt_masking = [kwargs["sky_mask_enabled"] for kwargs in evaluated]
|
|
419
|
+
pred_masking = [kwargs["pred_sky_mask_enabled"] for kwargs in evaluated]
|
|
420
|
+
assert gt_masking == [True, True, True]
|
|
421
|
+
assert pred_masking == [False, False, True]
|
|
422
|
+
assert [kwargs["segmentation_path"] for kwargs in built] == [str(paths["semantic"])] * 3
|
|
423
|
+
# The sky_mask is only read by a flag that uses it (here --mask-sky-prediction).
|
|
424
|
+
assert [kwargs["pred_sky_mask_path"] for kwargs in built] == [
|
|
425
|
+
None, None, str(paths["sky_mask"]),
|
|
426
|
+
]
|
|
427
|
+
with zipfile.ZipFile(paths["depth"]) as zf:
|
|
428
|
+
saved = {
|
|
429
|
+
name: json.loads(zf.read(f".eval/{name}.json"))
|
|
430
|
+
for name in ("eval", "gt_sky_with_mask", "gt_and_pred_sky")
|
|
431
|
+
}
|
|
432
|
+
assert [s["protocol"]["parameters"]["method.pred_sky_mask"]
|
|
433
|
+
for s in saved.values()] == [False, False, True]
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def test_experiment_config_keeps_only_listed_predictions():
|
|
360
437
|
config = {
|
|
361
438
|
"gt": {
|
|
362
439
|
"name": "GT",
|
|
@@ -375,17 +452,17 @@ def test_experiment_config_keeps_only_listed_modalities():
|
|
|
375
452
|
"distributions": True,
|
|
376
453
|
}
|
|
377
454
|
|
|
378
|
-
reduced = cli._experiment_config(config, ["depth"
|
|
455
|
+
reduced = cli._experiment_config(config, ["depth"])
|
|
379
456
|
|
|
380
|
-
assert reduced["gt"] ==
|
|
381
|
-
"name": "GT",
|
|
382
|
-
"depth": {"path": "/gt/depth"},
|
|
383
|
-
"semantic_segmentation": {"path": "/gt/seg"},
|
|
384
|
-
}
|
|
457
|
+
assert reduced["gt"] == config["gt"]
|
|
385
458
|
assert reduced["datasets"] == [
|
|
386
459
|
{"name": "a", "output_file": "/out/a.json", "relative_depth": {"path": "/a/depth"}},
|
|
387
460
|
]
|
|
388
461
|
assert reduced["distributions"] is True
|
|
462
|
+
assert cli._experiment_config(config, ["depth", "sky_mask"])["datasets"] == [{
|
|
463
|
+
"name": "a", "output_file": "/out/a.json",
|
|
464
|
+
"relative_depth": {"path": "/a/depth"}, "sky_mask": {"path": "/a/sky"},
|
|
465
|
+
}]
|
|
389
466
|
assert cli._experiment_config(config, ["rgb", "sky_mask"])["datasets"] == [
|
|
390
467
|
{"name": "a", "output_file": "/out/a.json", "rgb": {"path": "/a/rgb"}},
|
|
391
468
|
{"name": "b", "rgb": {"path": "/b/rgb"}},
|
|
@@ -399,7 +476,10 @@ def test_experiment_config_keeps_only_listed_modalities():
|
|
|
399
476
|
([], "non-empty array of modality names"),
|
|
400
477
|
("depth", "non-empty array of modality names"),
|
|
401
478
|
(["relative_depth"], r"unknown modality 'relative_depth' \(use 'depth'"),
|
|
402
|
-
(["
|
|
479
|
+
(["segmentation"], "'segmentation' is a GT input"),
|
|
480
|
+
(["semantic_segmentation"], "'semantic_segmentation' is a GT input"),
|
|
481
|
+
(["sparse_depth"], "'sparse_depth' is a GT input"),
|
|
482
|
+
(["intrinsics"], "'intrinsics' is a GT input"),
|
|
403
483
|
(["normals"], "unknown modality 'normals'"),
|
|
404
484
|
(["depth", "depth"], r"lists \['depth'\] more than once"),
|
|
405
485
|
],
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{euler_eval-2.33.0 → euler_eval-2.35.0}/docs/feature-request-unified-evaluation-framework.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/counts-points3d.eval.json
RENAMED
|
File without changes
|
{euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/counts-sparsedepth.eval.json
RENAMED
|
File without changes
|
{euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/future-sum-by-depth.eval.json
RENAMED
|
File without changes
|
{euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/histogram-only.eval.json
RENAMED
|
File without changes
|
{euler_eval-2.33.0 → euler_eval-2.35.0}/tests/fixtures/distributions/per-file-only.eval.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|