Source code for geoh5py.data.reference_value_map

# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#  Copyright (c) 2025 Mira Geoscience Ltd.                                     '
#                                                                              '
#  This file is part of geoh5py.                                               '
#                                                                              '
#  geoh5py is free software: you can redistribute it and/or modify             '
#  it under the terms of the GNU Lesser General Public License as published by '
#  the Free Software Foundation, either version 3 of the License, or           '
#  (at your option) any later version.                                         '
#                                                                              '
#  geoh5py is distributed in the hope that it will be useful,                  '
#  but WITHOUT ANY WARRANTY; without even the implied warranty of              '
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               '
#  GNU Lesser General Public License for more details.                         '
#                                                                              '
#  You should have received a copy of the GNU Lesser General Public License    '
#  along with geoh5py.  If not, see <https://www.gnu.org/licenses/>.           '
# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


from __future__ import annotations

from abc import ABC

import numpy as np
from h5py import special_dtype


[docs] class ReferenceValueMap(ABC): """Maps from reference index to reference value of ReferencedData.""" MAP_DTYPE = np.dtype([("Key", "<u4"), ("Value", special_dtype(vlen=str))]) def __init__( self, value_map: dict[int, str] | np.ndarray | tuple, name: str = "Value map", ): self._map: np.ndarray = self.validate_value_map(value_map) self.name = name def __getitem__(self, item: int) -> str: return dict(self._map)[item] def __len__(self) -> int: return len(self._map) def __call__(self) -> dict: try: map_string = self._map.astype(np.dtype([("Key", "<u4"), ("Value", "U25")])) except UnicodeDecodeError: map_string = self._map return dict(map_string)
[docs] @classmethod def validate_value_map(cls, value_map: np.ndarray | dict) -> np.ndarray: """ Verify that the key and value are valid. It raises errors if there is an issue :param value_map: Array of key, value pairs. """ if isinstance(value_map, tuple): value_map = dict(value_map) if isinstance(value_map, np.ndarray) and value_map.dtype.names is None: if value_map.ndim == 1: value_map = {i: str(val) for i, val in enumerate(set(value_map))} value_map = dict(value_map) if isinstance(value_map, dict): if not np.all(np.asarray(list(value_map)) >= 0): raise KeyError("Key must be an positive integer") value_list = list(value_map.items()) value_map = np.array( value_list, dtype=[("Key", "<u4"), ("Value", special_dtype(vlen=str))] ) value_map["Value"] = np.char.encode( value_map["Value"].astype("U25"), "utf-8" ) if not isinstance(value_map, np.ndarray): raise TypeError("Value map must be a numpy array or dict.") if value_map.dtype != cls.MAP_DTYPE: raise ValueError(f"Array of 'value_map' must be of dtype = {cls.MAP_DTYPE}") return value_map
@property def map(self) -> np.ndarray: """ A reference array mapping values to strings. The keys are positive integers, and the values description. The key '0' is always 'Unknown'. """ return self._map
BOOLEAN_VALUE_MAP = np.array( [(0, b"False"), (1, b"True")], dtype=ReferenceValueMap.MAP_DTYPE, )