tensogram-xarray 0.14.0__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.
- tensogram_xarray/__init__.py +24 -0
- tensogram_xarray/array.py +408 -0
- tensogram_xarray/backend.py +139 -0
- tensogram_xarray/coords.py +113 -0
- tensogram_xarray/mapping.py +91 -0
- tensogram_xarray/merge.py +832 -0
- tensogram_xarray/scanner.py +196 -0
- tensogram_xarray/store.py +383 -0
- tensogram_xarray-0.14.0.dist-info/METADATA +23 -0
- tensogram_xarray-0.14.0.dist-info/RECORD +12 -0
- tensogram_xarray-0.14.0.dist-info/WHEEL +4 -0
- tensogram_xarray-0.14.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# (C) Copyright 2026- ECMWF and individual contributors.
|
|
2
|
+
#
|
|
3
|
+
# This software is licensed under the terms of the Apache Licence Version 2.0
|
|
4
|
+
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
5
|
+
# In applying this licence, ECMWF does not waive the privileges and immunities
|
|
6
|
+
# granted to it by virtue of its status as an intergovernmental organisation nor
|
|
7
|
+
# does it submit to any jurisdiction.
|
|
8
|
+
|
|
9
|
+
"""User-specified dimension and variable mapping.
|
|
10
|
+
|
|
11
|
+
Handles the ``dim_names`` and ``variable_key`` parameters that let callers
|
|
12
|
+
control how tensogram data maps to xarray dimensions and variable names.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from collections.abc import Sequence
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def resolve_dim_names(
|
|
22
|
+
ndim: int,
|
|
23
|
+
user_dim_names: Sequence[str] | None,
|
|
24
|
+
) -> list[str]:
|
|
25
|
+
"""Return dimension names for a tensor with *ndim* axes.
|
|
26
|
+
|
|
27
|
+
If *user_dim_names* is provided, it must have exactly *ndim* entries.
|
|
28
|
+
Otherwise generic ``dim_0``, ``dim_1``, ... names are generated.
|
|
29
|
+
"""
|
|
30
|
+
if user_dim_names is not None:
|
|
31
|
+
names = list(user_dim_names)
|
|
32
|
+
if len(names) != ndim:
|
|
33
|
+
msg = (
|
|
34
|
+
f"dim_names has {len(names)} entries but tensor has {ndim} "
|
|
35
|
+
f"dimensions. Provide exactly {ndim} names."
|
|
36
|
+
)
|
|
37
|
+
raise ValueError(msg)
|
|
38
|
+
return names
|
|
39
|
+
return [f"dim_{i}" for i in range(ndim)]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _resolve_dotted(meta: dict[str, Any], dotted_key: str) -> Any:
|
|
43
|
+
"""Resolve a dotted key path like ``mars.param`` in a nested dict."""
|
|
44
|
+
parts = dotted_key.split(".")
|
|
45
|
+
current: Any = meta
|
|
46
|
+
for part in parts:
|
|
47
|
+
if not isinstance(current, dict) or part not in current:
|
|
48
|
+
return None
|
|
49
|
+
current = current[part]
|
|
50
|
+
return current
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Dotted-path metadata keys to try for variable naming, in priority order.
|
|
54
|
+
# Must match the priority chain in tensogram-zarr's mapping.py.
|
|
55
|
+
_VARIABLE_NAME_KEYS = [
|
|
56
|
+
"name",
|
|
57
|
+
"mars.param",
|
|
58
|
+
"param",
|
|
59
|
+
"mars.shortName",
|
|
60
|
+
"shortName",
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def resolve_variable_name(
|
|
65
|
+
obj_index: int,
|
|
66
|
+
per_object_meta: dict[str, Any],
|
|
67
|
+
variable_key: str | None,
|
|
68
|
+
) -> str:
|
|
69
|
+
"""Determine the xarray variable name for a data object.
|
|
70
|
+
|
|
71
|
+
If *variable_key* is given (e.g. ``"mars.param"``), the value at that
|
|
72
|
+
dotted path in the per-object metadata is used. Otherwise the function
|
|
73
|
+
tries ``_VARIABLE_NAME_KEYS`` in priority order, then falls back to a
|
|
74
|
+
generic ``"object_<index>"`` name.
|
|
75
|
+
|
|
76
|
+
The priority chain matches ``tensogram-zarr``'s ``resolve_variable_name``
|
|
77
|
+
so that the same ``.tgm`` file produces consistent variable names
|
|
78
|
+
regardless of which backend opens it.
|
|
79
|
+
"""
|
|
80
|
+
source = per_object_meta or {}
|
|
81
|
+
|
|
82
|
+
# Try explicit key first, then the standard priority chain.
|
|
83
|
+
keys_to_try = [variable_key] if variable_key else []
|
|
84
|
+
keys_to_try.extend(_VARIABLE_NAME_KEYS)
|
|
85
|
+
|
|
86
|
+
for key in keys_to_try:
|
|
87
|
+
val = _resolve_dotted(source, key)
|
|
88
|
+
if val is not None:
|
|
89
|
+
return str(val)
|
|
90
|
+
|
|
91
|
+
return f"object_{obj_index}"
|