euler-loading 2.2.0__tar.gz → 2.2.2__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_loading-2.2.0 → euler_loading-2.2.2}/PKG-INFO +1 -1
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/dataset.py +37 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/preprocessing.py +63 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/pyproject.toml +1 -1
- {euler_loading-2.2.0 → euler_loading-2.2.2}/tests/test_preprocessing.py +50 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/.github/workflows/workflow.yml +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/.gitignore +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/README.md +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/__init__.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/_dataset_contract.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/_ds_crawler_utils.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/_metadata.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/_resolution.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/_writing.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/indexing.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/__init__.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/_annotations.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/_writer_utils.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/contracts.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/cpu/__init__.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/cpu/generic.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/cpu/generic_dense_depth.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/cpu/real_drive_sim.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/cpu/vkitti2.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/generate/__init__.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/generate/__main__.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/generate/loaders.json +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/generic.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/gpu/__init__.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/gpu/generic.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/gpu/generic_dense_depth.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/gpu/real_drive_sim.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/gpu/vkitti2.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/real_drive_sim.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/vkitti2.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/example.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/package-lock.json +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/sample_rds.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/tests/__init__.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/tests/conftest.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/tests/example_rds_calib.json +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/tests/test_dataset.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/tests/test_indexing.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/tests/test_loaders.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/tests/test_real_dataset.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/tests/test_writing.py +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/vkitti_cpu_example_output.json +0 -0
- {euler_loading-2.2.0 → euler_loading-2.2.2}/vkitti_gpu_example_output.json +0 -0
|
@@ -59,6 +59,32 @@ __all__ = [
|
|
|
59
59
|
]
|
|
60
60
|
|
|
61
61
|
|
|
62
|
+
def _callable_name(value: Any) -> str:
|
|
63
|
+
module = getattr(value, "__module__", None)
|
|
64
|
+
qualname = getattr(value, "__qualname__", None)
|
|
65
|
+
if module and qualname:
|
|
66
|
+
return f"{module}.{qualname}"
|
|
67
|
+
name = getattr(value, "__name__", None)
|
|
68
|
+
if module and name:
|
|
69
|
+
return f"{module}.{name}"
|
|
70
|
+
cls = value.__class__
|
|
71
|
+
return f"{cls.__module__}.{cls.__qualname__}"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _describe_transform(transform: Any) -> str:
|
|
75
|
+
describe = getattr(transform, "describe", None)
|
|
76
|
+
if callable(describe):
|
|
77
|
+
try:
|
|
78
|
+
return str(describe())
|
|
79
|
+
except Exception:
|
|
80
|
+
logger.debug(
|
|
81
|
+
"Failed to describe transform %s; falling back to callable name.",
|
|
82
|
+
_callable_name(transform),
|
|
83
|
+
exc_info=True,
|
|
84
|
+
)
|
|
85
|
+
return _callable_name(transform)
|
|
86
|
+
|
|
87
|
+
|
|
62
88
|
def _get_index_tree(index_output: Mapping[str, Any]) -> dict[str, Any]:
|
|
63
89
|
"""Return the dataset tree from a ds-crawler output payload."""
|
|
64
90
|
index_tree = index_output.get("index")
|
|
@@ -444,6 +470,17 @@ class MultiModalDataset(_BaseDataset):
|
|
|
444
470
|
bind = getattr(transform, "bind_to_dataset", None)
|
|
445
471
|
if callable(bind):
|
|
446
472
|
bind(self)
|
|
473
|
+
if self._transforms:
|
|
474
|
+
logger.warning("Configured %d sample transform(s):", len(self._transforms))
|
|
475
|
+
for idx, transform in enumerate(self._transforms, start=1):
|
|
476
|
+
logger.warning(
|
|
477
|
+
"Transform %d/%d: %s",
|
|
478
|
+
idx,
|
|
479
|
+
len(self._transforms),
|
|
480
|
+
_describe_transform(transform),
|
|
481
|
+
)
|
|
482
|
+
else:
|
|
483
|
+
logger.warning("Configured 0 sample transforms.")
|
|
447
484
|
|
|
448
485
|
def get_modality_metadata(self, modality_name: str) -> dict[str, Any]:
|
|
449
486
|
"""Return the metadata dict for a given modality name."""
|
|
@@ -186,6 +186,30 @@ class FieldSpec:
|
|
|
186
186
|
def is_passthrough(self) -> bool:
|
|
187
187
|
return self.kind == "passthrough"
|
|
188
188
|
|
|
189
|
+
def describe(self, *, include_defaults: bool = True) -> str:
|
|
190
|
+
"""Return a concise human-readable description of this field policy."""
|
|
191
|
+
parts = [f"kind={self.kind}"]
|
|
192
|
+
if self.layout is not None:
|
|
193
|
+
parts.append(f"layout={self.layout}")
|
|
194
|
+
|
|
195
|
+
interpolation = self.interpolation
|
|
196
|
+
if include_defaults and interpolation is None:
|
|
197
|
+
interpolation = _DEFAULT_INTERPOLATION[self.kind]
|
|
198
|
+
if interpolation is not None:
|
|
199
|
+
parts.append(f"interpolation={interpolation}")
|
|
200
|
+
|
|
201
|
+
normalize_vectors = self.normalize_vectors
|
|
202
|
+
if include_defaults and normalize_vectors is None:
|
|
203
|
+
normalize_vectors = self.kind == "ray_map"
|
|
204
|
+
if normalize_vectors is not None:
|
|
205
|
+
parts.append(f"normalize_vectors={bool(normalize_vectors)}")
|
|
206
|
+
|
|
207
|
+
if self.kind == "mask" or self.threshold != 0.5:
|
|
208
|
+
parts.append(f"threshold={self.threshold:g}")
|
|
209
|
+
if self.reduce is not None:
|
|
210
|
+
parts.append(f"reduce={self.reduce}")
|
|
211
|
+
return ", ".join(parts)
|
|
212
|
+
|
|
189
213
|
|
|
190
214
|
@dataclass(frozen=True)
|
|
191
215
|
class Resize:
|
|
@@ -202,6 +226,10 @@ class Resize:
|
|
|
202
226
|
def from_config(cls, cfg: Any) -> "Resize":
|
|
203
227
|
return cls(size=_parse_size(cfg, context="Resize"))
|
|
204
228
|
|
|
229
|
+
def describe(self) -> str:
|
|
230
|
+
height, width = self.size
|
|
231
|
+
return f"resize({height}x{width})"
|
|
232
|
+
|
|
205
233
|
|
|
206
234
|
@dataclass(frozen=True)
|
|
207
235
|
class Crop:
|
|
@@ -246,6 +274,13 @@ class Crop:
|
|
|
246
274
|
)
|
|
247
275
|
return cls(size=_parse_size(cfg, context="Crop"))
|
|
248
276
|
|
|
277
|
+
def describe(self) -> str:
|
|
278
|
+
height, width = self.size
|
|
279
|
+
parts = [f"crop({height}x{width})", f"anchor={self.anchor}"]
|
|
280
|
+
if self.offset is not None:
|
|
281
|
+
parts.append(f"offset={self.offset}")
|
|
282
|
+
return ", ".join(parts)
|
|
283
|
+
|
|
249
284
|
def resolve_box(self, source_size: tuple[int, int]) -> tuple[int, int, int, int]:
|
|
250
285
|
source_h, source_w = source_size
|
|
251
286
|
target_h, target_w = self.size
|
|
@@ -687,6 +722,34 @@ class SamplePreprocessor:
|
|
|
687
722
|
bind_group(getattr(dataset, "_hierarchical_modalities", {}))
|
|
688
723
|
self._bound_field_specs = bound_specs
|
|
689
724
|
|
|
725
|
+
def describe(self) -> str:
|
|
726
|
+
"""Return a concise summary suitable for initialization logging."""
|
|
727
|
+
operations = ", ".join(
|
|
728
|
+
operation.describe() if hasattr(operation, "describe") else repr(operation)
|
|
729
|
+
for operation in self.operations
|
|
730
|
+
) or "none"
|
|
731
|
+
|
|
732
|
+
active_specs = self._bound_field_specs or self.field_specs
|
|
733
|
+
if active_specs:
|
|
734
|
+
field_parts = [
|
|
735
|
+
f"{name}: {spec.describe()}"
|
|
736
|
+
for name, spec in sorted(active_specs.items())
|
|
737
|
+
]
|
|
738
|
+
fields_text = "; ".join(field_parts)
|
|
739
|
+
elif self.infer_fields:
|
|
740
|
+
fields_text = "inferred from modality_type/name heuristics"
|
|
741
|
+
else:
|
|
742
|
+
fields_text = "none"
|
|
743
|
+
|
|
744
|
+
reference = self.reference_field or "auto"
|
|
745
|
+
return (
|
|
746
|
+
"SamplePreprocessor("
|
|
747
|
+
f"operations=[{operations}], "
|
|
748
|
+
f"reference_field={reference}, "
|
|
749
|
+
f"infer_fields={self.infer_fields}, "
|
|
750
|
+
f"fields={fields_text})"
|
|
751
|
+
)
|
|
752
|
+
|
|
690
753
|
def _resolve_field_spec(self, key: str, value: Any) -> FieldSpec | None:
|
|
691
754
|
if key in self._bound_field_specs:
|
|
692
755
|
return self._bound_field_specs[key]
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import logging
|
|
5
6
|
from unittest.mock import patch
|
|
6
7
|
|
|
7
8
|
import numpy as np
|
|
@@ -183,3 +184,52 @@ class TestDatasetTransformBinding:
|
|
|
183
184
|
sample = dataset[0]
|
|
184
185
|
assert sample["rgb"].shape == (3, 2, 3)
|
|
185
186
|
assert sample["metric_depth"].shape == (1, 2, 3)
|
|
187
|
+
|
|
188
|
+
def test_dataset_logs_transform_behaviour_once_on_init(self, caplog):
|
|
189
|
+
rgb_index = _flat_index("rgb", ["f001"])
|
|
190
|
+
|
|
191
|
+
def rgb_loader(path, meta=None):
|
|
192
|
+
return torch.ones((3, 4, 6), dtype=torch.float32)
|
|
193
|
+
|
|
194
|
+
def identity(sample):
|
|
195
|
+
return sample
|
|
196
|
+
|
|
197
|
+
preprocessor = SamplePreprocessor.from_config(
|
|
198
|
+
{
|
|
199
|
+
"resize": [2, 3],
|
|
200
|
+
"infer_fields": False,
|
|
201
|
+
"fields": {
|
|
202
|
+
"valid_mask": {"kind": "mask"},
|
|
203
|
+
"intrinsics": {"kind": "intrinsics", "reduce": "first"},
|
|
204
|
+
},
|
|
205
|
+
}
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
with patch(
|
|
209
|
+
"euler_loading.dataset.index_dataset_from_path",
|
|
210
|
+
return_value=rgb_index,
|
|
211
|
+
), caplog.at_level(logging.WARNING, logger="euler_loading.dataset"):
|
|
212
|
+
MultiModalDataset(
|
|
213
|
+
modalities={
|
|
214
|
+
"rgb": Modality(
|
|
215
|
+
"/data/rgb",
|
|
216
|
+
loader=rgb_loader,
|
|
217
|
+
modality_type="rgb",
|
|
218
|
+
),
|
|
219
|
+
},
|
|
220
|
+
transforms=[preprocessor, identity],
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
messages = [record.message for record in caplog.records]
|
|
224
|
+
assert messages.count("Configured 2 sample transform(s):") == 1
|
|
225
|
+
assert all(record.levelno == logging.WARNING for record in caplog.records)
|
|
226
|
+
|
|
227
|
+
joined = "\n".join(messages)
|
|
228
|
+
assert "SamplePreprocessor(" in joined
|
|
229
|
+
assert "resize(2x3)" in joined
|
|
230
|
+
assert "rgb: kind=image" in joined
|
|
231
|
+
assert "valid_mask: kind=mask" in joined
|
|
232
|
+
assert "interpolation=nearest" in joined
|
|
233
|
+
assert "intrinsics: kind=intrinsics" in joined
|
|
234
|
+
assert "reduce=first" in joined
|
|
235
|
+
assert "identity" in joined
|
|
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_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/cpu/generic_dense_depth.py
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
|
{euler_loading-2.2.0 → euler_loading-2.2.2}/euler_loading/loaders/gpu/generic_dense_depth.py
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
|