euler-loading 1.3.0__tar.gz → 2.1.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_loading-1.3.0 → euler_loading-2.1.0}/PKG-INFO +2 -1
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/__init__.py +1 -0
- euler_loading-2.1.0/euler_loading/_dataset_contract.py +91 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/_ds_crawler_utils.py +4 -19
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/_metadata.py +17 -7
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/_resolution.py +12 -2
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/_writing.py +8 -16
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/dataset.py +30 -7
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/cpu/generic.py +71 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/gpu/generic.py +73 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/pyproject.toml +2 -1
- {euler_loading-1.3.0 → euler_loading-2.1.0}/.github/workflows/workflow.yml +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/.gitignore +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/README.md +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/indexing.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/__init__.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/_annotations.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/_writer_utils.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/contracts.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/cpu/__init__.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/cpu/generic_dense_depth.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/cpu/real_drive_sim.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/cpu/vkitti2.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/generate/__init__.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/generate/__main__.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/generate/loaders.json +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/generic.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/gpu/__init__.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/gpu/generic_dense_depth.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/gpu/real_drive_sim.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/gpu/vkitti2.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/real_drive_sim.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/euler_loading/loaders/vkitti2.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/example.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/package-lock.json +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/sample_rds.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/tests/__init__.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/tests/conftest.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/tests/example_rds_calib.json +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/tests/test_dataset.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/tests/test_indexing.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/tests/test_loaders.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/tests/test_real_dataset.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/tests/test_writing.py +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/vkitti_cpu_example_output.json +0 -0
- {euler_loading-1.3.0 → euler_loading-2.1.0}/vkitti_gpu_example_output.json +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: euler-loading
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Multi-modal PyTorch dataloader using ds-crawler indices
|
|
5
5
|
Requires-Python: >=3.9
|
|
6
6
|
Requires-Dist: ds-crawler
|
|
7
|
+
Requires-Dist: euler-dataset-contract
|
|
7
8
|
Requires-Dist: numpy
|
|
8
9
|
Requires-Dist: pillow
|
|
9
10
|
Provides-Extra: dev
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""euler-loading: Multi-modal PyTorch dataloader using ds-crawler indices."""
|
|
2
2
|
|
|
3
|
+
from . import _dataset_contract # noqa: F401
|
|
3
4
|
from ._resolution import resolve_loader_module, resolve_writer_module
|
|
4
5
|
from ._writing import create_dataset_writer_from_index
|
|
5
6
|
from .dataset import Modality, MultiModalDataset
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from euler_dataset_contract import (
|
|
6
|
+
register_addon_validator,
|
|
7
|
+
validate_addon_version,
|
|
8
|
+
validate_slot,
|
|
9
|
+
validate_string_list,
|
|
10
|
+
validate_token,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
_ALLOWED_USED_AS = {"condition", "input", "output", "target"}
|
|
15
|
+
_ALLOWED_KEYS = {
|
|
16
|
+
"version",
|
|
17
|
+
"used_as",
|
|
18
|
+
"slot",
|
|
19
|
+
"hierarchy_scope",
|
|
20
|
+
"applies_to",
|
|
21
|
+
"task",
|
|
22
|
+
"loader",
|
|
23
|
+
"function",
|
|
24
|
+
"writer_function",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def validate_euler_loading_addon(value: Any, context: str) -> None:
|
|
29
|
+
if not isinstance(value, dict):
|
|
30
|
+
raise ValueError(f"{context} must be an object")
|
|
31
|
+
|
|
32
|
+
unknown = sorted(set(value.keys()) - _ALLOWED_KEYS)
|
|
33
|
+
if unknown:
|
|
34
|
+
joined = ", ".join(unknown)
|
|
35
|
+
raise ValueError(f"Unknown {context} key(s): {joined}")
|
|
36
|
+
|
|
37
|
+
validate_addon_version(value.get("version"), f"{context}.version")
|
|
38
|
+
|
|
39
|
+
used_as = value.get("used_as")
|
|
40
|
+
if used_as is not None:
|
|
41
|
+
if not isinstance(used_as, str) or not used_as:
|
|
42
|
+
raise ValueError(f"{context}.used_as must be a non-empty string")
|
|
43
|
+
if used_as not in _ALLOWED_USED_AS:
|
|
44
|
+
allowed = ", ".join(sorted(_ALLOWED_USED_AS))
|
|
45
|
+
raise ValueError(
|
|
46
|
+
f"{context}.used_as must be one of {{{allowed}}}, got {used_as!r}"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
slot = value.get("slot")
|
|
50
|
+
if slot is not None:
|
|
51
|
+
validate_slot(slot, f"{context}.slot")
|
|
52
|
+
|
|
53
|
+
task = value.get("task")
|
|
54
|
+
if task is not None:
|
|
55
|
+
validate_token(task, f"{context}.task")
|
|
56
|
+
|
|
57
|
+
loader = value.get("loader")
|
|
58
|
+
function = value.get("function")
|
|
59
|
+
if loader is not None:
|
|
60
|
+
validate_token(loader, f"{context}.loader")
|
|
61
|
+
if function is not None:
|
|
62
|
+
validate_token(function, f"{context}.function")
|
|
63
|
+
if (loader is None) != (function is None):
|
|
64
|
+
raise ValueError(
|
|
65
|
+
f"{context}.loader and {context}.function must either both be set "
|
|
66
|
+
"or both be omitted"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
writer_function = value.get("writer_function")
|
|
70
|
+
if writer_function is not None:
|
|
71
|
+
validate_token(writer_function, f"{context}.writer_function")
|
|
72
|
+
|
|
73
|
+
hierarchy_scope = value.get("hierarchy_scope")
|
|
74
|
+
applies_to = value.get("applies_to")
|
|
75
|
+
if hierarchy_scope is not None or applies_to is not None:
|
|
76
|
+
if used_as != "condition":
|
|
77
|
+
raise ValueError(
|
|
78
|
+
f"{context}.hierarchy_scope and {context}.applies_to are only "
|
|
79
|
+
"allowed when used_as is 'condition'"
|
|
80
|
+
)
|
|
81
|
+
if hierarchy_scope is not None:
|
|
82
|
+
validate_token(hierarchy_scope, f"{context}.hierarchy_scope")
|
|
83
|
+
if applies_to is not None:
|
|
84
|
+
validate_string_list(
|
|
85
|
+
applies_to,
|
|
86
|
+
f"{context}.applies_to",
|
|
87
|
+
allow_wildcard=True,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
register_addon_validator("euler_loading", validate_euler_loading_addon, overwrite=True)
|
|
@@ -5,6 +5,7 @@ from collections.abc import Mapping
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
|
+
from ds_crawler import get_dataset_contract
|
|
8
9
|
from ds_crawler.zip_utils import read_metadata_json
|
|
9
10
|
|
|
10
11
|
try:
|
|
@@ -13,19 +14,6 @@ except ImportError:
|
|
|
13
14
|
_load_dataset_split = None
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
DS_CRAWLER_STRUCTURAL_KEYS = frozenset({
|
|
17
|
-
"name",
|
|
18
|
-
"type",
|
|
19
|
-
"id_regex",
|
|
20
|
-
"id_regex_join_char",
|
|
21
|
-
"euler_train",
|
|
22
|
-
"dataset",
|
|
23
|
-
"hierarchy_regex",
|
|
24
|
-
"named_capture_group_value_separator",
|
|
25
|
-
"sampled",
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
|
|
29
17
|
def as_non_empty_str(value: Any) -> str | None:
|
|
30
18
|
if value is None:
|
|
31
19
|
return None
|
|
@@ -61,11 +49,7 @@ def first_non_empty_list(*candidates: list[str] | None) -> list[str]:
|
|
|
61
49
|
|
|
62
50
|
|
|
63
51
|
def extract_ds_crawler_properties(index_output: Mapping[str, Any]) -> dict[str, Any]:
|
|
64
|
-
return
|
|
65
|
-
str(key): value
|
|
66
|
-
for key, value in index_output.items()
|
|
67
|
-
if key not in DS_CRAWLER_STRUCTURAL_KEYS
|
|
68
|
-
}
|
|
52
|
+
return get_dataset_contract(dict(index_output)).to_properties_dict()
|
|
69
53
|
|
|
70
54
|
|
|
71
55
|
_SPLIT_NAME_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.-]*$")
|
|
@@ -164,5 +148,6 @@ def load_index_output(
|
|
|
164
148
|
)
|
|
165
149
|
|
|
166
150
|
result = dict(base_output)
|
|
167
|
-
result["
|
|
151
|
+
result["index"] = split_dataset
|
|
152
|
+
result.pop("dataset", None)
|
|
168
153
|
return result
|
|
@@ -4,6 +4,8 @@ import re
|
|
|
4
4
|
from collections.abc import Mapping
|
|
5
5
|
from typing import TYPE_CHECKING, Any, Callable
|
|
6
6
|
|
|
7
|
+
from ds_crawler import get_dataset_contract
|
|
8
|
+
|
|
7
9
|
from ._ds_crawler_utils import (
|
|
8
10
|
as_non_empty_str,
|
|
9
11
|
as_string_list,
|
|
@@ -44,6 +46,7 @@ def _build_runlog_entry(
|
|
|
44
46
|
as_non_empty_str(
|
|
45
47
|
_resolve_euler_loading_property(euler_loading_properties, "modality_type")
|
|
46
48
|
),
|
|
49
|
+
as_non_empty_str(descriptor.get("modality_key")),
|
|
47
50
|
as_non_empty_str(descriptor.get("modality_type")),
|
|
48
51
|
_infer_modality_type(name=name, path=modality.path),
|
|
49
52
|
)
|
|
@@ -146,12 +149,19 @@ def _read_ds_crawler_descriptor(
|
|
|
146
149
|
|
|
147
150
|
if isinstance(index_output, Mapping):
|
|
148
151
|
properties.update(extract_ds_crawler_properties(index_output))
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if
|
|
154
|
-
descriptor["
|
|
152
|
+
try:
|
|
153
|
+
contract = get_dataset_contract(dict(index_output))
|
|
154
|
+
except Exception:
|
|
155
|
+
contract = None
|
|
156
|
+
if contract is not None:
|
|
157
|
+
descriptor["modality_key"] = contract.modality_key
|
|
158
|
+
indexing = index_output.get("indexing")
|
|
159
|
+
if isinstance(indexing, Mapping):
|
|
160
|
+
hierarchy = indexing.get("hierarchy")
|
|
161
|
+
if isinstance(hierarchy, Mapping):
|
|
162
|
+
hierarchy_regex = as_non_empty_str(hierarchy.get("regex"))
|
|
163
|
+
if hierarchy_regex is not None:
|
|
164
|
+
descriptor["hierarchy_regex"] = hierarchy_regex
|
|
155
165
|
|
|
156
166
|
try:
|
|
157
167
|
cfg = load_dataset_config_fn({"path": path})
|
|
@@ -164,7 +174,7 @@ def _read_ds_crawler_descriptor(
|
|
|
164
174
|
|
|
165
175
|
cfg_type = as_non_empty_str(getattr(cfg, "type", None))
|
|
166
176
|
if cfg_type is not None:
|
|
167
|
-
descriptor["
|
|
177
|
+
descriptor["modality_key"] = cfg_type
|
|
168
178
|
|
|
169
179
|
cfg_hierarchy_regex = as_non_empty_str(getattr(cfg, "hierarchy_regex", None))
|
|
170
180
|
if cfg_hierarchy_regex is not None:
|
|
@@ -6,6 +6,8 @@ from collections.abc import Mapping
|
|
|
6
6
|
from types import ModuleType
|
|
7
7
|
from typing import TYPE_CHECKING, Any, Callable
|
|
8
8
|
|
|
9
|
+
from ds_crawler import get_dataset_contract
|
|
10
|
+
|
|
9
11
|
from ._ds_crawler_utils import as_non_empty_str
|
|
10
12
|
|
|
11
13
|
if TYPE_CHECKING:
|
|
@@ -61,7 +63,11 @@ def _resolve_loader(
|
|
|
61
63
|
if modality.loader is not None:
|
|
62
64
|
return modality.loader
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
try:
|
|
67
|
+
contract = get_dataset_contract(index)
|
|
68
|
+
euler_loading_meta = contract.get_addon("euler_loading")
|
|
69
|
+
except Exception:
|
|
70
|
+
euler_loading_meta = None
|
|
65
71
|
if not isinstance(euler_loading_meta, Mapping):
|
|
66
72
|
raise ValueError(
|
|
67
73
|
f"Modality {modality_name!r}: no explicit loader provided and the "
|
|
@@ -126,7 +132,11 @@ def _resolve_writer(
|
|
|
126
132
|
if modality.writer is not None:
|
|
127
133
|
return modality.writer
|
|
128
134
|
|
|
129
|
-
|
|
135
|
+
try:
|
|
136
|
+
contract = get_dataset_contract(index)
|
|
137
|
+
euler_loading_meta = contract.get_addon("euler_loading")
|
|
138
|
+
except Exception:
|
|
139
|
+
euler_loading_meta = None
|
|
130
140
|
if not isinstance(euler_loading_meta, Mapping):
|
|
131
141
|
return None
|
|
132
142
|
|
|
@@ -7,11 +7,10 @@ from collections.abc import Mapping
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import Any, Callable
|
|
9
9
|
|
|
10
|
-
from ds_crawler import DatasetWriter, ZipDatasetWriter
|
|
10
|
+
from ds_crawler import DatasetWriter, ZipDatasetWriter, get_dataset_contract
|
|
11
11
|
|
|
12
12
|
from ._ds_crawler_utils import (
|
|
13
13
|
as_non_empty_str,
|
|
14
|
-
extract_ds_crawler_properties,
|
|
15
14
|
first_non_empty,
|
|
16
15
|
)
|
|
17
16
|
from .loaders._writer_utils import supports_stream_target
|
|
@@ -30,27 +29,20 @@ def create_dataset_writer_from_index(
|
|
|
30
29
|
zip: bool = False,
|
|
31
30
|
) -> DatasetWriter | ZipDatasetWriter:
|
|
32
31
|
"""Create a ds-crawler writer that mirrors an existing index's metadata."""
|
|
33
|
-
|
|
34
|
-
type_name = as_non_empty_str(index_output.get("type")) or "other"
|
|
35
|
-
euler_train = index_output.get("euler_train")
|
|
36
|
-
if not isinstance(euler_train, Mapping):
|
|
37
|
-
raise ValueError(
|
|
38
|
-
"index_output must contain an 'euler_train' mapping to build a writer."
|
|
39
|
-
)
|
|
32
|
+
contract = get_dataset_contract(dict(index_output))
|
|
40
33
|
|
|
34
|
+
indexing = index_output.get("indexing")
|
|
35
|
+
hierarchy = indexing.get("hierarchy") if isinstance(indexing, Mapping) else None
|
|
36
|
+
id_cfg = indexing.get("id") if isinstance(indexing, Mapping) else None
|
|
41
37
|
separator = first_non_empty(
|
|
42
|
-
as_non_empty_str(
|
|
43
|
-
as_non_empty_str(
|
|
38
|
+
as_non_empty_str(hierarchy.get("separator")) if isinstance(hierarchy, Mapping) else None,
|
|
39
|
+
as_non_empty_str(id_cfg.get("join_char")) if isinstance(id_cfg, Mapping) else None,
|
|
44
40
|
)
|
|
45
|
-
properties = extract_ds_crawler_properties(index_output)
|
|
46
41
|
writer_cls = ZipDatasetWriter if zip else DatasetWriter
|
|
47
42
|
return writer_cls(
|
|
48
43
|
root,
|
|
49
|
-
|
|
50
|
-
type=type_name,
|
|
51
|
-
euler_train=dict(euler_train),
|
|
44
|
+
head=contract.to_mapping(),
|
|
52
45
|
separator=separator,
|
|
53
|
-
**properties,
|
|
54
46
|
)
|
|
55
47
|
|
|
56
48
|
|
|
@@ -18,6 +18,7 @@ except ImportError:
|
|
|
18
18
|
from ds_crawler import (
|
|
19
19
|
DatasetWriter,
|
|
20
20
|
ZipDatasetWriter,
|
|
21
|
+
get_dataset_contract,
|
|
21
22
|
index_dataset_from_path,
|
|
22
23
|
load_dataset_config,
|
|
23
24
|
)
|
|
@@ -319,7 +320,7 @@ class MultiModalDataset(_BaseDataset):
|
|
|
319
320
|
self._resolved_writers[name] = _resolve_writer(
|
|
320
321
|
modality_name=name, modality=modality, index=index,
|
|
321
322
|
)
|
|
322
|
-
records = collect_files(index["
|
|
323
|
+
records = collect_files(index["index"])
|
|
323
324
|
lookup = {
|
|
324
325
|
"/".join(rec.hierarchy_path + (rec.file_entry["id"],)): rec
|
|
325
326
|
for rec in records
|
|
@@ -351,7 +352,7 @@ class MultiModalDataset(_BaseDataset):
|
|
|
351
352
|
self._resolved_writers[name] = _resolve_writer(
|
|
352
353
|
modality_name=name, modality=modality, index=index,
|
|
353
354
|
)
|
|
354
|
-
files_by_level = collect_hierarchical_files(index["
|
|
355
|
+
files_by_level = collect_hierarchical_files(index["index"])
|
|
355
356
|
self._hierarchical_lookups[name] = files_by_level
|
|
356
357
|
total_files = sum(len(f) for f in files_by_level.values())
|
|
357
358
|
logger.info(
|
|
@@ -407,7 +408,11 @@ class MultiModalDataset(_BaseDataset):
|
|
|
407
408
|
|
|
408
409
|
def get_modality_metadata(self, modality_name: str) -> dict[str, Any]:
|
|
409
410
|
"""Return the metadata dict for a given modality name."""
|
|
410
|
-
|
|
411
|
+
index = self._index_outputs.get(modality_name, {})
|
|
412
|
+
try:
|
|
413
|
+
return get_dataset_contract(index).meta or {}
|
|
414
|
+
except Exception:
|
|
415
|
+
return {}
|
|
411
416
|
|
|
412
417
|
def get_modality_index(self, modality_name: str) -> dict[str, Any]:
|
|
413
418
|
"""Return the cached ds-crawler index for a modality."""
|
|
@@ -505,7 +510,12 @@ class MultiModalDataset(_BaseDataset):
|
|
|
505
510
|
output_root=output_root, modality_name=modality_name
|
|
506
511
|
)
|
|
507
512
|
record = self._lookups[modality_name][sample_id]
|
|
508
|
-
|
|
513
|
+
try:
|
|
514
|
+
modality_meta = get_dataset_contract(
|
|
515
|
+
self._index_outputs[modality_name]
|
|
516
|
+
).meta
|
|
517
|
+
except Exception:
|
|
518
|
+
modality_meta = None
|
|
509
519
|
basename = Path(record.file_entry["path"]).name
|
|
510
520
|
relative_path = record.file_entry["path"]
|
|
511
521
|
full_id = _build_writer_full_id(
|
|
@@ -545,7 +555,10 @@ class MultiModalDataset(_BaseDataset):
|
|
|
545
555
|
first_modality: str | None = None
|
|
546
556
|
|
|
547
557
|
for modality_name, index in self._index_outputs.items():
|
|
548
|
-
|
|
558
|
+
try:
|
|
559
|
+
name = get_dataset_contract(index).name
|
|
560
|
+
except Exception:
|
|
561
|
+
name = None
|
|
549
562
|
if name is None:
|
|
550
563
|
continue
|
|
551
564
|
if first_name is None:
|
|
@@ -604,7 +617,12 @@ class MultiModalDataset(_BaseDataset):
|
|
|
604
617
|
|
|
605
618
|
for name, modality in self._modalities.items():
|
|
606
619
|
record = self._lookups[name][sample_id]
|
|
607
|
-
|
|
620
|
+
try:
|
|
621
|
+
modality_meta = get_dataset_contract(
|
|
622
|
+
self._index_outputs[name]
|
|
623
|
+
).meta
|
|
624
|
+
except Exception:
|
|
625
|
+
modality_meta = None
|
|
608
626
|
|
|
609
627
|
if name in self._zip_modalities:
|
|
610
628
|
file_or_path = self._open_from_zip(
|
|
@@ -625,7 +643,12 @@ class MultiModalDataset(_BaseDataset):
|
|
|
625
643
|
for name, modality in self._hierarchical_modalities.items():
|
|
626
644
|
files_by_level = self._hierarchical_lookups[name]
|
|
627
645
|
matched = match_hierarchical_files(hierarchy_path, files_by_level)
|
|
628
|
-
|
|
646
|
+
try:
|
|
647
|
+
modality_meta = get_dataset_contract(
|
|
648
|
+
self._hierarchical_index_outputs[name]
|
|
649
|
+
).meta
|
|
650
|
+
except Exception:
|
|
651
|
+
modality_meta = None
|
|
629
652
|
loaded: dict[str, Any] = {}
|
|
630
653
|
for entry in matched:
|
|
631
654
|
cache_key = f"{modality.path}/{entry['path']}"
|
|
@@ -11,6 +11,8 @@ Supported file extensions:
|
|
|
11
11
|
Return types
|
|
12
12
|
------------
|
|
13
13
|
- **spherical_map** -- ``np.ndarray`` of shape ``(H, W, C)`` float32.
|
|
14
|
+
- **intrinsics** -- ``np.ndarray`` of shape ``(3, 3)`` float32.
|
|
15
|
+
- **sh_coeffs** -- ``np.ndarray`` of shape ``(N, 3)`` float32.
|
|
14
16
|
|
|
15
17
|
Usage::
|
|
16
18
|
|
|
@@ -18,6 +20,8 @@ Usage::
|
|
|
18
20
|
from euler_loading import Modality
|
|
19
21
|
|
|
20
22
|
Modality("/data/my_dataset/spherical_map", loader=generic.spherical_map)
|
|
23
|
+
Modality("/data/my_dataset/intrinsics", loader=generic.intrinsics)
|
|
24
|
+
Modality("/data/my_dataset/sh_coeffs", loader=generic.sh_coeffs)
|
|
21
25
|
"""
|
|
22
26
|
|
|
23
27
|
from __future__ import annotations
|
|
@@ -60,6 +64,22 @@ def _load_numpy(path: Union[str, BinaryIO]) -> np.ndarray:
|
|
|
60
64
|
return arr.astype(np.float32)
|
|
61
65
|
|
|
62
66
|
|
|
67
|
+
def _write_numpy(path: Union[str, BinaryIO], value: Any) -> None:
|
|
68
|
+
"""Write an array to ``.npy`` or ``.npz`` based on extension."""
|
|
69
|
+
ensure_parent(path)
|
|
70
|
+
ext = os.path.splitext(_get_name(path))[1].lower()
|
|
71
|
+
arr = to_numpy(value).astype(np.float32)
|
|
72
|
+
|
|
73
|
+
if ext == _NPY_EXTENSION:
|
|
74
|
+
np.save(path, arr)
|
|
75
|
+
return
|
|
76
|
+
if ext == _NPZ_EXTENSION:
|
|
77
|
+
np.savez_compressed(path, data=arr)
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
raise ValueError(f"Unsupported output extension: {ext}")
|
|
81
|
+
|
|
82
|
+
|
|
63
83
|
# ---------------------------------------------------------------------------
|
|
64
84
|
# Public loaders
|
|
65
85
|
# ---------------------------------------------------------------------------
|
|
@@ -86,6 +106,45 @@ def spherical_map(path: Union[str, BinaryIO], meta: dict[str, Any] | None = None
|
|
|
86
106
|
# ---------------------------------------------------------------------------
|
|
87
107
|
|
|
88
108
|
|
|
109
|
+
@modality_meta(
|
|
110
|
+
modality_type="intrinsics",
|
|
111
|
+
dtype="float32",
|
|
112
|
+
shape="3x3",
|
|
113
|
+
file_formats=[".npy", ".npz"],
|
|
114
|
+
)
|
|
115
|
+
def intrinsics(path: Union[str, BinaryIO], meta: dict[str, Any] | None = None) -> np.ndarray:
|
|
116
|
+
"""Load a camera intrinsics matrix as a ``(3, 3)`` float32 array.
|
|
117
|
+
|
|
118
|
+
The file is expected to contain a ``(3, 3)`` array::
|
|
119
|
+
|
|
120
|
+
[[fx, 0, cx],
|
|
121
|
+
[ 0, fy, cy],
|
|
122
|
+
[ 0, 0, 1]]
|
|
123
|
+
"""
|
|
124
|
+
return _load_numpy(path)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@modality_meta(
|
|
128
|
+
modality_type="sh_coeffs",
|
|
129
|
+
dtype="float32",
|
|
130
|
+
shape="NC",
|
|
131
|
+
file_formats=[".npy", ".npz"],
|
|
132
|
+
)
|
|
133
|
+
def sh_coeffs(path: Union[str, BinaryIO], meta: dict[str, Any] | None = None) -> np.ndarray:
|
|
134
|
+
"""Load spherical-harmonic coefficients as an ``(N, 3)`` float32 array.
|
|
135
|
+
|
|
136
|
+
*N* is the number of SH basis functions (e.g. 15 for degree-3 SH with
|
|
137
|
+
the constant term removed). Each row is a 3-vector (one per spatial
|
|
138
|
+
dimension).
|
|
139
|
+
"""
|
|
140
|
+
return _load_numpy(path)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# ---------------------------------------------------------------------------
|
|
144
|
+
# Writers
|
|
145
|
+
# ---------------------------------------------------------------------------
|
|
146
|
+
|
|
147
|
+
|
|
89
148
|
@mark_stream_supported
|
|
90
149
|
def write_spherical_map(path: Union[str, BinaryIO], value: Any, meta: dict[str, Any] | None = None) -> None:
|
|
91
150
|
"""Write spherical-map data to NumPy formats based on extension.
|
|
@@ -107,3 +166,15 @@ def write_spherical_map(path: Union[str, BinaryIO], value: Any, meta: dict[str,
|
|
|
107
166
|
return
|
|
108
167
|
|
|
109
168
|
raise ValueError(f"Unsupported spherical-map output extension: {ext}")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@mark_stream_supported
|
|
172
|
+
def write_intrinsics(path: Union[str, BinaryIO], value: Any, meta: dict[str, Any] | None = None) -> None:
|
|
173
|
+
"""Write a ``(3, 3)`` intrinsics matrix to a NumPy file."""
|
|
174
|
+
_write_numpy(path, value)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@mark_stream_supported
|
|
178
|
+
def write_sh_coeffs(path: Union[str, BinaryIO], value: Any, meta: dict[str, Any] | None = None) -> None:
|
|
179
|
+
"""Write ``(N, 3)`` spherical-harmonic coefficients to a NumPy file."""
|
|
180
|
+
_write_numpy(path, value)
|
|
@@ -11,6 +11,8 @@ Supported file extensions:
|
|
|
11
11
|
Return types
|
|
12
12
|
------------
|
|
13
13
|
- **spherical_map** -- ``torch.FloatTensor`` of shape ``(C, H, W)``.
|
|
14
|
+
- **intrinsics** -- ``torch.FloatTensor`` of shape ``(3, 3)``.
|
|
15
|
+
- **sh_coeffs** -- ``torch.FloatTensor`` of shape ``(N, 3)``.
|
|
14
16
|
|
|
15
17
|
Usage::
|
|
16
18
|
|
|
@@ -18,6 +20,8 @@ Usage::
|
|
|
18
20
|
from euler_loading import Modality
|
|
19
21
|
|
|
20
22
|
Modality("/data/my_dataset/spherical_map", loader=generic.spherical_map)
|
|
23
|
+
Modality("/data/my_dataset/intrinsics", loader=generic.intrinsics)
|
|
24
|
+
Modality("/data/my_dataset/sh_coeffs", loader=generic.sh_coeffs)
|
|
21
25
|
"""
|
|
22
26
|
|
|
23
27
|
from __future__ import annotations
|
|
@@ -61,6 +65,22 @@ def _load_numpy(path: Union[str, BinaryIO]) -> np.ndarray:
|
|
|
61
65
|
return arr.astype(np.float32)
|
|
62
66
|
|
|
63
67
|
|
|
68
|
+
def _write_numpy(path: Union[str, BinaryIO], value: Any) -> None:
|
|
69
|
+
"""Write an array to ``.npy`` or ``.npz`` based on extension."""
|
|
70
|
+
ensure_parent(path)
|
|
71
|
+
ext = os.path.splitext(_get_name(path))[1].lower()
|
|
72
|
+
arr = to_numpy(value).astype(np.float32)
|
|
73
|
+
|
|
74
|
+
if ext == _NPY_EXTENSION:
|
|
75
|
+
np.save(path, arr)
|
|
76
|
+
return
|
|
77
|
+
if ext == _NPZ_EXTENSION:
|
|
78
|
+
np.savez_compressed(path, data=arr)
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
raise ValueError(f"Unsupported output extension: {ext}")
|
|
82
|
+
|
|
83
|
+
|
|
64
84
|
# ---------------------------------------------------------------------------
|
|
65
85
|
# Public loaders
|
|
66
86
|
# ---------------------------------------------------------------------------
|
|
@@ -86,6 +106,47 @@ def spherical_map(path: Union[str, BinaryIO], meta: dict[str, Any] | None = None
|
|
|
86
106
|
# ---------------------------------------------------------------------------
|
|
87
107
|
|
|
88
108
|
|
|
109
|
+
@modality_meta(
|
|
110
|
+
modality_type="intrinsics",
|
|
111
|
+
dtype="float32",
|
|
112
|
+
shape="3x3",
|
|
113
|
+
file_formats=[".npy", ".npz"],
|
|
114
|
+
)
|
|
115
|
+
def intrinsics(path: Union[str, BinaryIO], meta: dict[str, Any] | None = None) -> torch.Tensor:
|
|
116
|
+
"""Load a camera intrinsics matrix as a ``(3, 3)`` float32 tensor.
|
|
117
|
+
|
|
118
|
+
The file is expected to contain a ``(3, 3)`` array::
|
|
119
|
+
|
|
120
|
+
[[fx, 0, cx],
|
|
121
|
+
[ 0, fy, cy],
|
|
122
|
+
[ 0, 0, 1]]
|
|
123
|
+
"""
|
|
124
|
+
arr = _load_numpy(path)
|
|
125
|
+
return torch.from_numpy(arr).contiguous()
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@modality_meta(
|
|
129
|
+
modality_type="sh_coeffs",
|
|
130
|
+
dtype="float32",
|
|
131
|
+
shape="NC",
|
|
132
|
+
file_formats=[".npy", ".npz"],
|
|
133
|
+
)
|
|
134
|
+
def sh_coeffs(path: Union[str, BinaryIO], meta: dict[str, Any] | None = None) -> torch.Tensor:
|
|
135
|
+
"""Load spherical-harmonic coefficients as an ``(N, 3)`` float32 tensor.
|
|
136
|
+
|
|
137
|
+
*N* is the number of SH basis functions (e.g. 15 for degree-3 SH with
|
|
138
|
+
the constant term removed). Each row is a 3-vector (one per spatial
|
|
139
|
+
dimension).
|
|
140
|
+
"""
|
|
141
|
+
arr = _load_numpy(path)
|
|
142
|
+
return torch.from_numpy(arr).contiguous()
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# ---------------------------------------------------------------------------
|
|
146
|
+
# Writers
|
|
147
|
+
# ---------------------------------------------------------------------------
|
|
148
|
+
|
|
149
|
+
|
|
89
150
|
@mark_stream_supported
|
|
90
151
|
def write_spherical_map(path: Union[str, BinaryIO], value: Any, meta: dict[str, Any] | None = None) -> None:
|
|
91
152
|
"""Write spherical-map data to NumPy formats based on extension."""
|
|
@@ -101,3 +162,15 @@ def write_spherical_map(path: Union[str, BinaryIO], value: Any, meta: dict[str,
|
|
|
101
162
|
return
|
|
102
163
|
|
|
103
164
|
raise ValueError(f"Unsupported spherical-map output extension: {ext}")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@mark_stream_supported
|
|
168
|
+
def write_intrinsics(path: Union[str, BinaryIO], value: Any, meta: dict[str, Any] | None = None) -> None:
|
|
169
|
+
"""Write a ``(3, 3)`` intrinsics matrix to a NumPy file."""
|
|
170
|
+
_write_numpy(path, value)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@mark_stream_supported
|
|
174
|
+
def write_sh_coeffs(path: Union[str, BinaryIO], value: Any, meta: dict[str, Any] | None = None) -> None:
|
|
175
|
+
"""Write ``(N, 3)`` spherical-harmonic coefficients to a NumPy file."""
|
|
176
|
+
_write_numpy(path, value)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "euler-loading"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "2.1.0"
|
|
4
4
|
description = "Multi-modal PyTorch dataloader using ds-crawler indices"
|
|
5
5
|
requires-python = ">=3.9"
|
|
6
6
|
dependencies = [
|
|
7
7
|
"numpy",
|
|
8
8
|
"Pillow",
|
|
9
9
|
"ds-crawler",
|
|
10
|
+
"euler-dataset-contract",
|
|
10
11
|
]
|
|
11
12
|
|
|
12
13
|
[project.optional-dependencies]
|
|
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-1.3.0 → euler_loading-2.1.0}/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
|
{euler_loading-1.3.0 → euler_loading-2.1.0}/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
|