Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 76 additions & 6 deletions omf/fileio/geoh5.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,20 @@
from typing import Any

import numpy as np
from geoh5py.data import Data, FloatData, IntegerData, ReferencedData
from geoh5py.groups import PropertyGroup, RootGroup
from geoh5py.data import (
Data,
DataTypeEnum,
FloatData,
IntegerData,
NumericData,
ReferencedData,
)
from geoh5py.groups import ContainerGroup, PropertyGroup, RootGroup
from geoh5py.objects import BlockModel, Curve, Grid2D, ObjectBase, Points, Surface
from geoh5py.shared import FLOAT_NDV, INTEGER_NDV, Entity
from geoh5py.workspace import Workspace

from omf.base import Project, UidModel
from omf.base import ContentModel, Project, UidModel
from omf.data import (
ColorArray,
Int2Array,
Expand Down Expand Up @@ -203,7 +210,7 @@ def from_geoh5(self, entity, **kwargs) -> dict:
@staticmethod
def process_dependents(
element: UidModel | Entity,
parent: Entity,
parent: Entity | None,
workspace: str | Path | Workspace,
compression: int,
) -> list:
Expand Down Expand Up @@ -238,7 +245,11 @@ def process_dependents(
converter = get_conversion_map(
child, workspace, compression=compression, parent=element
)
children += [getattr(converter, method)(child, **kwargs)]
converted = getattr(converter, method)(child, **kwargs)
if isinstance(converted, list):
children += converted
else:
children.append(converted)

if len(children_list) > 1:
_logger.info(
Expand Down Expand Up @@ -368,6 +379,51 @@ def from_geoh5(self, entity: Data, **kwargs) -> UidModel | list: # type: ignore
return element


class ContainerGroupConversion(BaseConversion):
"""
Forward only conversion from :obj:`geoh5py.groups.ContainerGroup` to a flatten
OMF project.

:param obj: Either an omf or geoh5 class.
:param geoh5: Path to a geoh5 or active :obj:`geoh5py.workspace.Workspace`.
:param compression: Compression level for data.
"""

_attribute_map: dict[str, Any] = {
"name": "name",
"uid": "uid",
}

def __init__(
self,
obj: UidModel | Entity,
geoh5: str | Path | Workspace,
compression: int,
**kwargs,
):
super().__init__(obj, geoh5, compression, **kwargs)

def from_omf(self, element: ContentModel, **kwargs) -> Entity | None: # type: ignore
pass

def from_geoh5(self, entity: ObjectBase, **kwargs) -> UidModel: # type: ignore
"""
Convert :obj:`geoh5.objects` object to :obj:`omf.base.Element` class.

:param entity: Input :obj:`geoh5.objects` class.
:param kwargs: Input dictionary of attributes to be appended.

:returns: An OMF Element.
"""
with fetch_h5_handle(self.geoh5) as workspace:
return self.process_dependents(
entity,
None,
workspace,
self.compression, # type: ignore
)


class ElementConversion(BaseConversion):
"""
Conversion between :obj:`omf.pointset.PointSetElement` and
Expand Down Expand Up @@ -492,12 +548,13 @@ def from_geoh5(self, entity: RootGroup, **kwargs) -> Project: # type: ignore
uid = kwargs.pop("uid")
project = self.omf_type(**kwargs)
project._backend.update({"uid": uid}) # pylint: disable=W0212
project.elements = self.process_dependents(
elements = self.process_dependents(
entity,
project,
workspace,
self.compression, # type: ignore
)
project.elements = elements

return project

Expand Down Expand Up @@ -565,6 +622,10 @@ def collect_attributes(
else:
values = getattr(element, "values", None)

if values is None and isinstance(element, NumericData):
dtype = DataTypeEnum[element.entity_type.primitive_type.name].value
values = np.ones(element.n_values, dtype=dtype) * element.ndv

if np.issubdtype(values.dtype, np.floating):
values[np.isclose(values, FLOAT_NDV, atol=2e-45)] = np.nan
else:
Expand Down Expand Up @@ -612,6 +673,10 @@ def collect_attributes(
values = element.array.array
else:
values = getattr(element, "values", None)

if values is None and isinstance(element, NumericData):
values = np.ones(element.n_values, dtype=np.int32) * INTEGER_NDV

values[np.isclose(values, INTEGER_NDV)] = 0

if values is not None:
Expand Down Expand Up @@ -706,6 +771,10 @@ def collect_h5_attributes(
return kwargs

labels = list(element.value_map().values())

if isinstance(labels[0], bytes):
labels = [label.decode("utf-8") for label in labels]

ind = 0
if "Unknown" in labels:
ind = 1
Expand Down Expand Up @@ -1304,6 +1373,7 @@ def block_model_reordering(entity: BlockModel | VolumeElement, values: np.ndarra

_CONVERSION_MAP: dict = {
BlockModel: VolumeConversion,
ContainerGroup: ContainerGroupConversion,
Curve: CurveConversion,
FloatData: ScalarDataConversion,
Grid2D: SurfaceGridConversion,
Expand Down
Loading