Skip to content

Commit 3d97700

Browse files
support to read properties, columnBasedTable, and timeSeries as arrays/dict
1 parent 0feb081 commit 3d97700

8 files changed

Lines changed: 537 additions & 94 deletions

File tree

energyml-utils/example/attic/arrays_test.py

Lines changed: 114 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
import logging
2+
from sqlite3 import NotSupportedError
3+
import traceback
24
from typing import List, Optional
35
import numpy as np
46
from energyml.utils.data.helper import _ARRAY_NAMES_, read_array
5-
from energyml.utils.data.mesh import AbstractMesh, SurfaceMesh, PolylineSetMesh, read_mesh_object
7+
from energyml.utils.data.mesh import (
8+
AbstractMesh,
9+
SurfaceMesh,
10+
PolylineSetMesh,
11+
read_column_based_table,
12+
read_mesh_object,
13+
read_property_interpreted_with_cbt,
14+
read_property,
15+
read_time_series,
16+
)
617
from energyml.utils.storage_interface import EnergymlStorageInterface
718
from energyml.utils.epc import Epc
8-
19+
from energyml.utils.epc_stream import EpcStreamReader, RelsUpdateMode
20+
from energyml.utils.introspection import get_obj_title
921
from energyml.resqml.v2_2.resqmlv2 import Point3DLatticeArray
22+
from energyml.eml.v2_3.commonv2 import TimeSeries
23+
from energyml.eml.v2_1.commonv2 import TimeSeries as TimeSeries21
1024

1125
from energyml.utils.serialization import read_energyml_xml_str, serialize_json
1226

@@ -232,27 +246,107 @@ def read_representation_set_representation() -> List[AbstractMesh]:
232246
return read_mesh_object(energyml_object=rep_set_rep, workspace=epc)
233247

234248

249+
def read_props_and_cbt(
250+
epc_path: List[str] = [
251+
"rc/epc/testingPackageCpp22.epc",
252+
"D:/Geosiris/Clients/BRGM/git/csv-to-energyml/rc/output/full-local/attic/result-out-EpcStream-egis-full.epc",
253+
],
254+
p_or_cbt_uuids: List = [
255+
"1c5a3e99-e997-4bd7-a94d-c45d7b7405ce",
256+
"be17c053-9189-4bc0-9db1-75aa51a026cd",
257+
"da73937c-2c60-4e10-8917-5154fde4ded5",
258+
"6561b499-82ed-4233-8a83-ea5d5aaf56a9",
259+
"0d6aba60-b37e-498c-aedc-334561eb0749",
260+
"d64d0ed0-72fa-4495-8e3a-a01175194e25",
261+
"5abecfe6-b951-4802-9002-e597169a9923",
262+
"49207072-563b-404a-9707-9a9b70168d33",
263+
],
264+
) -> None:
265+
266+
epcs = []
267+
for path in epc_path:
268+
epc = EpcStreamReader(
269+
epc_file_path=path,
270+
rels_update_mode=RelsUpdateMode.MANUAL,
271+
)
272+
# epc = Epc.read_file(f"{path}", read_rels_from_files=False, recompute_rels=False)
273+
epcs.append(epc)
274+
275+
for uuid in p_or_cbt_uuids:
276+
read = False
277+
prop_or_cbt = None
278+
for epc in epcs:
279+
try:
280+
prop_or_cbt_lst = epc.get_object_by_uuid(uuid)
281+
if not prop_or_cbt_lst:
282+
continue
283+
prop_or_cbt = prop_or_cbt_lst[0]
284+
array = None
285+
reshaped_array = None
286+
if "column" in str(type(prop_or_cbt)).lower():
287+
array = read_column_based_table(prop_or_cbt, workspace=epc)
288+
elif "time" in str(type(prop_or_cbt)).lower():
289+
array = read_time_series(prop_or_cbt, workspace=epc)
290+
else:
291+
array = read_property(
292+
prop_or_cbt,
293+
workspace=epc,
294+
)
295+
reshaped_array = read_property_interpreted_with_cbt(
296+
prop_or_cbt,
297+
workspace=epc,
298+
_cache_property_arrays=array,
299+
_return_none_if_no_category_lookup=True,
300+
)
301+
print("=" * 40)
302+
print(f"{type(prop_or_cbt)} : {get_obj_title(prop_or_cbt)} - uuid: {uuid}")
303+
print(array)
304+
305+
if reshaped_array is not None:
306+
print(" # => interpreted array:")
307+
print(reshaped_array)
308+
309+
print("\n")
310+
read = True
311+
break
312+
# except NotSupportedError as e:
313+
# print(f"Object with uuid {uuid} found but not supported: {e}")
314+
except Exception as e:
315+
traceback.print_exc()
316+
print(f"Error reading object with uuid {uuid}: {e}")
317+
pass
318+
if not read:
319+
print("[E]" + "=" * 40)
320+
if prop_or_cbt is not None:
321+
print(f"Object with uuid {get_obj_title(prop_or_cbt)} found but could not be read.")
322+
else:
323+
print(f"Object with uuid {uuid} not found in any EPC file.")
324+
print("\n")
325+
326+
235327
if __name__ == "__main__":
236328
logging.basicConfig(level=logging.DEBUG)
237329

238330
# meshes = read_grid()
239331
# meshes = read_polyline()
240332
# meshes = read_wellbore_frame_repr()
241-
meshes = read_representation_set_representation()
242-
243-
for m in meshes:
244-
print("=" * 40)
245-
print(f"Mesh identifier: {m.identifier}")
246-
print("points:")
247-
print(np.array(m.point_list))
248-
249-
if isinstance(m, SurfaceMesh):
250-
print("face indices:")
251-
print(np.array(m.faces_indices))
252-
elif isinstance(m, PolylineSetMesh):
253-
print("line indices:")
254-
try:
255-
print(np.array(m.line_indices))
256-
except Exception as e:
257-
print(m.line_indices)
258-
raise e
333+
# meshes = read_representation_set_representation()
334+
335+
# for m in meshes:
336+
# print("=" * 40)
337+
# print(f"Mesh identifier: {m.identifier}")
338+
# print("points:")
339+
# print(np.array(m.point_list))
340+
341+
# if isinstance(m, SurfaceMesh):
342+
# print("face indices:")
343+
# print(np.array(m.faces_indices))
344+
# elif isinstance(m, PolylineSetMesh):
345+
# print("line indices:")
346+
# try:
347+
# print(np.array(m.line_indices))
348+
# except Exception as e:
349+
# print(m.line_indices)
350+
# raise e
351+
352+
read_props_and_cbt()

energyml-utils/src/energyml/utils/data/helper.py

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
get_object_attribute,
2424
get_object_attribute_rgx,
2525
get_object_attribute_advanced,
26+
is_primitive,
27+
get_obj_title,
2628
)
2729

2830
from .datasets_io import get_path_in_external_with_path
@@ -382,18 +384,18 @@ def prod_n_tab(val: Union[float, int, str], tab: List[Union[float, int, str]]):
382384
"""
383385
if val is None:
384386
return [None] * len(tab)
385-
logging.debug(f"Multiplying list by {val}: {tab}")
387+
# logging.debug(f"Multiplying list by {val}: {tab}")
386388
# Convert to numpy array for vectorized operations, handling None values
387389
arr = np.array(tab, dtype=object)
388-
logging.debug(f"arr: {arr}")
390+
# logging.debug(f"arr: {arr}")
389391
# Create mask for non-None values
390392
mask = arr != None # noqa: E711
391393
# Create result array filled with None
392394
result = np.full(len(tab), None, dtype=object)
393-
logging.debug(f"result before multiplication: {result}")
395+
# logging.debug(f"result before multiplication: {result}")
394396
# Multiply only non-None values
395397
result[mask] = arr[mask].astype(float) * val
396-
logging.debug(f"result after multiplication: {result}")
398+
# logging.debug(f"result after multiplication: {result}")
397399
return result.tolist()
398400

399401

@@ -453,10 +455,12 @@ def get_crs_obj(
453455
logging.error("@get_crs_obj no Epc file given")
454456
else:
455457
crs_list = search_attribute_matching_name(context_obj, r"\.*Crs", search_in_sub_obj=True, deep_search=False)
456-
if crs_list is not None and len(crs_list) > 0:
458+
if crs_list is not None and len(crs_list) > 0 and crs_list[0] is not None:
457459
# logging.debug(crs_list[0])
460+
# logging.debug(f"CRS found for {get_obj_title(context_obj)} : {crs_list[0]}")
458461
crs = workspace.get_object(get_obj_uri(crs_list[0]))
459462
if crs is None:
463+
# logging.debug(f"CRS {crs_list[0]} not found (or not read correctly)")
460464
crs = workspace.get_object_by_uuid(get_obj_uuid(crs_list[0]))
461465
if crs is None:
462466
logging.error(f"CRS {crs_list[0]} not found (or not read correctly)")
@@ -755,17 +759,19 @@ def _array_name_mapping(array_type_name: str) -> str:
755759
:param array_type_name:
756760
:return:
757761
"""
758-
array_type_name = array_type_name.replace("3D", "3d").replace("2D", "2d")
759-
if array_type_name.endswith("ConstantArray"):
762+
array_type_name = array_type_name.replace("3D", "3d").replace("2D", "2d").lower()
763+
# logging.debug(f"=============> Mapping array type name '{array_type_name}' to reader function name...")
764+
if array_type_name.endswith("constantarray"):
760765
return "ConstantArray"
761-
elif "External" in array_type_name or "Hdf5" in array_type_name:
766+
elif "external" in array_type_name or "hdf5" in array_type_name:
762767
return "ExternalArray"
763-
elif array_type_name.endswith("XmlArray"):
768+
elif "xml" in array_type_name:
769+
# logging.debug("=============> XML array detected, be careful with the performance !")
764770
return "XmlArray"
765-
elif "Jagged" in array_type_name:
771+
elif "jagged" in array_type_name:
766772
return "JaggedArray"
767-
elif "Lattice" in array_type_name:
768-
if "Integer" in array_type_name or "Double" in array_type_name or "FloatingPoint" in array_type_name:
773+
elif "lattice" in array_type_name:
774+
if "integer" in array_type_name or "double" in array_type_name or "floatingpoint" in array_type_name:
769775
return "int_double_lattice_array"
770776
return array_type_name
771777

@@ -879,7 +885,7 @@ def read_external_array(
879885
for ext_part in external_parts:
880886
start_indices, counts, external_uri = _extract_external_data_array_part_params(ext_part)
881887
pief_list = get_path_in_external_with_path(obj=ext_part)
882-
888+
# logging.debug(f"Pief : {pief_list}")
883889
for pief_path_in_obj, pief in pief_list:
884890
arr = workspace.read_array(
885891
proxy=crs or root_obj,
@@ -890,6 +896,7 @@ def read_external_array(
890896
)
891897
if arr is not None:
892898
array = arr if array is None else np.concatenate((array, arr))
899+
# logging.debug(f"\t ExternalDataArrayPart read successfully. arr : {arr} : array : {array}")
893900
else:
894901
# RESQML v2.0.1: Extract count from parent object, no StartIndex or URI
895902
counts = None
@@ -933,6 +940,7 @@ def read_external_array(
933940
# Fallback for non-numpy arrays
934941
array = [array[idx] for idx in sub_indices]
935942

943+
# logging.debug(f"External array read successfully. => {array}")
936944
return array
937945

938946

@@ -964,8 +972,26 @@ def read_array(
964972
:param sub_indices: for SubRepresentation
965973
:return:
966974
"""
967-
if isinstance(energyml_array, list):
975+
if isinstance(energyml_array, np.ndarray):
976+
# if isinstance(energyml_array, list):
968977
return energyml_array
978+
elif isinstance(energyml_array, list):
979+
# logging.debug("Warning: the array is a list, not a numpy array, be careful with the performance !")
980+
# logging.debug(energyml_array)
981+
if len(energyml_array) > 0 and is_primitive(energyml_array[0]):
982+
return energyml_array
983+
else:
984+
return [
985+
read_array(
986+
energyml_array=elem,
987+
root_obj=root_obj,
988+
path_in_root=path_in_root,
989+
workspace=workspace,
990+
sub_indices=sub_indices,
991+
)
992+
for elem in energyml_array
993+
if elem is not None
994+
]
969995
array_type_name = _array_name_mapping(type(energyml_array).__name__)
970996

971997
reader_func = get_array_reader_function(array_type_name)
@@ -1030,8 +1056,10 @@ def read_xml_array(
10301056
:param sub_indices:
10311057
:return:
10321058
"""
1059+
10331060
values = get_object_attribute_no_verif(energyml_array, "values")
10341061
# count = get_object_attribute_no_verif(energyml_array, "count_per_value")
1062+
# logging.debug("values: ", values)
10351063

10361064
if sub_indices is not None and len(sub_indices) > 0:
10371065
if isinstance(values, np.ndarray):

0 commit comments

Comments
 (0)