pyetp 0.0.28__py3-none-any.whl → 0.0.30__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.
- pyetp/client.py +48 -36
- pyetp/uri.py +11 -9
- pyetp/utils_xml.py +309 -34
- {pyetp-0.0.28.dist-info → pyetp-0.0.30.dist-info}/METADATA +1 -1
- {pyetp-0.0.28.dist-info → pyetp-0.0.30.dist-info}/RECORD +7 -7
- {pyetp-0.0.28.dist-info → pyetp-0.0.30.dist-info}/LICENSE.md +0 -0
- {pyetp-0.0.28.dist-info → pyetp-0.0.30.dist-info}/WHEEL +0 -0
pyetp/client.py
CHANGED
|
@@ -7,6 +7,7 @@ import uuid
|
|
|
7
7
|
from collections import defaultdict
|
|
8
8
|
from contextlib import asynccontextmanager
|
|
9
9
|
from types import TracebackType
|
|
10
|
+
import time
|
|
10
11
|
|
|
11
12
|
import numpy as np
|
|
12
13
|
import websockets
|
|
@@ -148,6 +149,7 @@ class ETPClient(ETPConnection):
|
|
|
148
149
|
# ok
|
|
149
150
|
return bodies[0]
|
|
150
151
|
|
|
152
|
+
|
|
151
153
|
@staticmethod
|
|
152
154
|
def _parse_error_info(bodies: list[ETPModel]) -> list[ErrorInfo]:
|
|
153
155
|
# returns all error infos from bodies
|
|
@@ -379,12 +381,9 @@ class ETPClient(ETPConnection):
|
|
|
379
381
|
async def put_resqml_objects(self, *objs: ro.AbstractObject, dataspace: T.Union[DataspaceURI, str, None] = None):
|
|
380
382
|
from etptypes.energistics.etp.v12.datatypes.object.resource import \
|
|
381
383
|
Resource
|
|
382
|
-
|
|
383
384
|
time = self.timestamp
|
|
384
385
|
duri = self.get_dataspace_or_default_uri(dataspace)
|
|
385
|
-
|
|
386
386
|
uris = [DataObjectURI.from_obj(duri, obj) for obj in objs]
|
|
387
|
-
|
|
388
387
|
dobjs = [DataObject(
|
|
389
388
|
format="xml",
|
|
390
389
|
data=utils_xml.resqml_to_xml(obj),
|
|
@@ -448,7 +447,7 @@ class ETPClient(ETPConnection):
|
|
|
448
447
|
return round(x_ind), round(y_ind)
|
|
449
448
|
|
|
450
449
|
async def get_surface_value_x_y(self, epc_uri: T.Union[DataObjectURI, str], gri_uri: T.Union[DataObjectURI, str], x: T.Union[int, float], y: T.Union[int, float], method: T.Literal["bilinear", "nearest"]):
|
|
451
|
-
gri, = await self.get_resqml_objects(gri_uri)
|
|
450
|
+
gri, = await self.get_resqml_objects(gri_uri) # parallelized using subarray
|
|
452
451
|
xori = gri.grid2d_patch.geometry.points.supporting_geometry.origin.coordinate1
|
|
453
452
|
yori = gri.grid2d_patch.geometry.points.supporting_geometry.origin.coordinate2
|
|
454
453
|
xinc = gri.grid2d_patch.geometry.points.supporting_geometry.offset[0].spacing.value
|
|
@@ -460,8 +459,8 @@ class ETPClient(ETPConnection):
|
|
|
460
459
|
logger.info(f"Points not inside {x}:{y} {gri}")
|
|
461
460
|
return
|
|
462
461
|
uid = DataArrayIdentifier(
|
|
463
|
-
|
|
464
|
-
|
|
462
|
+
uri=str(epc_uri), pathInResource=gri.grid2d_patch.geometry.points.zvalues.values.path_in_hdf_file
|
|
463
|
+
)
|
|
465
464
|
if max_x_index_in_gri <= 10 or max_y_index_in_gri <= 10:
|
|
466
465
|
surf = await self.get_xtgeo_surface(epc_uri, gri_uri)
|
|
467
466
|
return surf.get_value_from_xy((x, y), sampling=method)
|
|
@@ -632,7 +631,7 @@ class ETPClient(ETPConnection):
|
|
|
632
631
|
async def get_epc_mesh_property_x_y(self, epc_uri: T.Union[DataObjectURI, str], uns_uri: T.Union[DataObjectURI, str], prop_uri: T.Union[DataObjectURI, str], x: float, y: float):
|
|
633
632
|
uns, = await self.get_resqml_objects(uns_uri)
|
|
634
633
|
points = await self.get_array(
|
|
635
|
-
|
|
634
|
+
DataArrayIdentifier(uri=str(epc_uri), pathInResource=uns.geometry.points.coordinates.path_in_hdf_file))
|
|
636
635
|
chk = self.check_bound(points, x, y)
|
|
637
636
|
if chk == False:
|
|
638
637
|
return None
|
|
@@ -671,7 +670,7 @@ class ETPClient(ETPConnection):
|
|
|
671
670
|
cprop, = await self.get_resqml_objects(prop_uri)
|
|
672
671
|
assert str(cprop.indexable_element) == 'IndexableElements.NODES'
|
|
673
672
|
props_uid = DataArrayIdentifier(
|
|
674
|
-
|
|
673
|
+
uri=str(epc_uri), pathInResource=cprop.patch_of_values[0].values.values.path_in_hdf_file)
|
|
675
674
|
meta, = await self.get_array_metadata(props_uid)
|
|
676
675
|
filtered_points = np.zeros((total_points_filtered, 3), dtype=np.float64)
|
|
677
676
|
all_values = np.empty(total_points_filtered, dtype=np.float64)
|
|
@@ -704,8 +703,35 @@ class ETPClient(ETPConnection):
|
|
|
704
703
|
response_filtered = response[:, ~np.isnan(response[1])]
|
|
705
704
|
return {"depth": response_filtered[0], "values": response_filtered[1]}
|
|
706
705
|
|
|
706
|
+
async def put_rddms_property(self, epc_uri: T.Union[DataObjectURI , str],
|
|
707
|
+
cprop0: T.Union[ro.ContinuousProperty, ro.DiscreteProperty],
|
|
708
|
+
propertykind0: ro.PropertyKind,
|
|
709
|
+
array_ref: np.ndarray, dataspace: T.Union[DataspaceURI , str , None] ):
|
|
710
|
+
|
|
711
|
+
assert isinstance(cprop0, ro.ContinuousProperty) or isinstance(cprop0, ro.DiscreteProperty), "prop must be a Property"
|
|
712
|
+
assert len(cprop0.patch_of_values) == 1, "property obj must have exactly one patch of values"
|
|
713
|
+
|
|
714
|
+
st = time.time()
|
|
715
|
+
propkind_uri = [""] if (propertykind0 is None) else (await self.put_resqml_objects(propertykind0, dataspace=dataspace))
|
|
716
|
+
cprop_uri = await self.put_resqml_objects(cprop0, dataspace=dataspace)
|
|
717
|
+
delay = time.time() - st
|
|
718
|
+
logger.debug(f"pyetp: put_rddms_property: put objects took {delay} s")
|
|
719
|
+
|
|
720
|
+
st = time.time()
|
|
721
|
+
response = await self.put_array(
|
|
722
|
+
DataArrayIdentifier(
|
|
723
|
+
uri=epc_uri.raw_uri if isinstance(epc_uri, DataObjectURI) else epc_uri,
|
|
724
|
+
pathInResource=cprop0.patch_of_values[0].values.values.path_in_hdf_file,
|
|
725
|
+
),
|
|
726
|
+
array_ref, # type: ignore
|
|
727
|
+
)
|
|
728
|
+
delay = time.time() - st
|
|
729
|
+
logger.debug(f"pyetp: put_rddms_property: put array ({array_ref.shape}) took {delay} s")
|
|
730
|
+
return cprop_uri, propkind_uri
|
|
731
|
+
|
|
707
732
|
async def put_epc_mesh(
|
|
708
|
-
self, epc_filename, title_in, property_titles, projected_epsg,
|
|
733
|
+
self, epc_filename: str, title_in: str, property_titles: T.List[str], projected_epsg: int,
|
|
734
|
+
dataspace: T.Union[DataspaceURI , str , None]
|
|
709
735
|
):
|
|
710
736
|
uns, crs, epc, timeseries, hexa = utils_xml.convert_epc_mesh_to_resqml_mesh(epc_filename, title_in, projected_epsg)
|
|
711
737
|
epc_uri, crs_uri, uns_uri = await self.put_resqml_objects(epc, crs, uns, dataspace=dataspace)
|
|
@@ -713,9 +739,7 @@ class ETPClient(ETPConnection):
|
|
|
713
739
|
if timeseries is not None:
|
|
714
740
|
timeseries_uris = await self.put_resqml_objects(timeseries, dataspace=dataspace)
|
|
715
741
|
timeseries_uri = list(timeseries_uris)[0] if (len(list(timeseries_uris)) > 0) else ""
|
|
716
|
-
|
|
717
|
-
logger.debug(f"put_epc_mesh property_titles {property_titles}")
|
|
718
|
-
|
|
742
|
+
|
|
719
743
|
#
|
|
720
744
|
# mesh geometry (six arrays)
|
|
721
745
|
#
|
|
@@ -784,19 +808,7 @@ class ETPClient(ETPConnection):
|
|
|
784
808
|
|
|
785
809
|
cprop_uris = []
|
|
786
810
|
for cprop0, prop, time_index in zip(cprop0s, props, time_indices):
|
|
787
|
-
|
|
788
|
-
assert len(cprop0.patch_of_values) == 1, "property obj must have exactly one patch of values"
|
|
789
|
-
|
|
790
|
-
propkind_uri = [""] if (propertykind0 is None) else (await self.put_resqml_objects(propertykind0, dataspace=dataspace))
|
|
791
|
-
cprop_uri = await self.put_resqml_objects(cprop0, dataspace=dataspace)
|
|
792
|
-
|
|
793
|
-
response = await self.put_array(
|
|
794
|
-
DataArrayIdentifier(
|
|
795
|
-
uri=epc_uri.raw_uri if isinstance(epc_uri, DataObjectURI) else epc_uri,
|
|
796
|
-
pathInResource=cprop0.patch_of_values[0].values.values.path_in_hdf_file,
|
|
797
|
-
),
|
|
798
|
-
prop.array_ref(), # type: ignore
|
|
799
|
-
)
|
|
811
|
+
cprop_uri, propkind_uri = await self.put_rddms_property(epc_uri, cprop0, propertykind0, prop.array_ref(), dataspace)
|
|
800
812
|
cprop_uris.extend(cprop_uri)
|
|
801
813
|
prop_rddms_uris[propname] = [propkind_uri, cprop_uris]
|
|
802
814
|
|
|
@@ -805,10 +817,10 @@ class ETPClient(ETPConnection):
|
|
|
805
817
|
async def get_mesh_points(self, epc_uri: T.Union[DataObjectURI, str], uns_uri: T.Union[DataObjectURI, str]):
|
|
806
818
|
uns, = await self.get_resqml_objects(uns_uri)
|
|
807
819
|
points = await self.get_array(
|
|
808
|
-
|
|
809
|
-
|
|
820
|
+
DataArrayIdentifier(
|
|
821
|
+
uri=str(epc_uri), pathInResource=uns.geometry.points.coordinates.path_in_hdf_file
|
|
822
|
+
)
|
|
810
823
|
)
|
|
811
|
-
)
|
|
812
824
|
return points
|
|
813
825
|
|
|
814
826
|
async def get_epc_property_surface_slice_node(self, epc_uri: T.Union[DataObjectURI, str], cprop0: ro.AbstractObject, points: np.ndarray, node_index: int, n_node_per_pos: int):
|
|
@@ -816,8 +828,8 @@ class ETPClient(ETPConnection):
|
|
|
816
828
|
indexing_array = np.arange(node_index, points.shape[0], n_node_per_pos, dtype=np.int32)
|
|
817
829
|
results = points[indexing_array, :]
|
|
818
830
|
arr = await asyncio.gather(*[self.get_subarray(DataArrayIdentifier(
|
|
819
|
-
|
|
820
|
-
|
|
831
|
+
uri=str(epc_uri), pathInResource=cprop0.patch_of_values[0].values.values.path_in_hdf_file,),
|
|
832
|
+
[i], [1]) for i in indexing_array])
|
|
821
833
|
arr = np.array(arr).flatten()
|
|
822
834
|
assert results.shape[0] == arr.size
|
|
823
835
|
results[:, 2] = arr
|
|
@@ -825,7 +837,7 @@ class ETPClient(ETPConnection):
|
|
|
825
837
|
|
|
826
838
|
async def get_epc_property_surface_slice_cell(self, epc_uri: T.Union[DataObjectURI, str], cprop0: ro.AbstractObject, points: np.ndarray, node_index: int, n_node_per_pos: int, get_cell_pos=True):
|
|
827
839
|
m, = await self.get_array_metadata(DataArrayIdentifier(
|
|
828
|
-
|
|
840
|
+
uri=str(epc_uri), pathInResource=cprop0.patch_of_values[0].values.values.path_in_hdf_file,))
|
|
829
841
|
n_cells = m.dimensions[0]
|
|
830
842
|
layers_per_sediment_unit = 2
|
|
831
843
|
n_cell_per_pos = n_node_per_pos - 1
|
|
@@ -835,8 +847,8 @@ class ETPClient(ETPConnection):
|
|
|
835
847
|
else:
|
|
836
848
|
results = np.zeros((int(n_cells/n_cell_per_pos), 3), dtype=np.float64)
|
|
837
849
|
arr = await asyncio.gather(*[self.get_subarray(DataArrayIdentifier(
|
|
838
|
-
|
|
839
|
-
|
|
850
|
+
uri=str(epc_uri), pathInResource=cprop0.patch_of_values[0].values.values.path_in_hdf_file,),
|
|
851
|
+
[i], [1]) for i in indexing_array])
|
|
840
852
|
arr = np.array(arr).flatten()
|
|
841
853
|
assert results.shape[0] == arr.size
|
|
842
854
|
results[:, 2] = arr
|
|
@@ -960,9 +972,9 @@ class ETPClient(ETPConnection):
|
|
|
960
972
|
|
|
961
973
|
# starts [start_X, starts_Y]
|
|
962
974
|
# counts [count_X, count_Y]
|
|
963
|
-
starts = np.array(starts).astype(np.int64)
|
|
964
|
-
counts = np.array(counts).astype(np.int64)
|
|
965
|
-
ends = starts + counts
|
|
975
|
+
starts = np.array(starts).astype(np.int64) # len = 2 [x_start_index, y_start_index]
|
|
976
|
+
counts = np.array(counts).astype(np.int64) # len = 2
|
|
977
|
+
ends = starts + counts # len = 2
|
|
966
978
|
if put_uninitialized:
|
|
967
979
|
transport_array_type = utils_arrays.get_transport(data.dtype)
|
|
968
980
|
await self._put_uninitialized_data_array(uid, data.shape, transport_array_type=transport_array_type)
|
pyetp/uri.py
CHANGED
|
@@ -69,16 +69,18 @@ class DataObjectURI(_DataObjectURI, _Mixin):
|
|
|
69
69
|
def from_obj(cls, dataspace: Union[DataspaceURI , str], obj: ro.AbstractObject):
|
|
70
70
|
|
|
71
71
|
objname = obj.__class__.__name__
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
if getattr(obj, 'Meta', None):
|
|
73
|
+
namespace: str = getattr(obj.Meta, 'namespace', None) or getattr(obj.Meta, 'target_namespace')
|
|
74
|
+
namespace = namespace.lower()
|
|
75
|
+
# TODO: we can rather look at citation.format - which could be used for xmlformat ? - however to be backward capatiable we check namespaces instead
|
|
76
|
+
if namespace.endswith('resqmlv2'):
|
|
77
|
+
domain = "resqml20"
|
|
78
|
+
elif namespace.endswith('data/commonv2'):
|
|
79
|
+
domain = "eml20"
|
|
80
|
+
else:
|
|
81
|
+
raise TypeError(f"Could not parse domain from namespace ({namespace})")
|
|
80
82
|
else:
|
|
81
|
-
|
|
83
|
+
domain = "eml20" # fallback to eml20 for backwards compatibility.
|
|
82
84
|
|
|
83
85
|
return cls.from_parts(dataspace, domain, objname, obj.uuid)
|
|
84
86
|
|
pyetp/utils_xml.py
CHANGED
|
@@ -208,6 +208,312 @@ def instantiate_resqml_grid(name: str, rotation: float, x0: float, y0: float, dx
|
|
|
208
208
|
return epc, crs, gri
|
|
209
209
|
|
|
210
210
|
|
|
211
|
+
def uom_for_prop_title(pt: str):
|
|
212
|
+
if (pt == "Age"):
|
|
213
|
+
return ro.ResqmlUom.A_1
|
|
214
|
+
if (pt == "Temperature"):
|
|
215
|
+
return ro.ResqmlUom.DEG_C
|
|
216
|
+
if (pt == "LayerID"):
|
|
217
|
+
return ro.ResqmlUom.EUC
|
|
218
|
+
if (pt == "Porosity_initial"):
|
|
219
|
+
return ro.ResqmlUom.M3_M3
|
|
220
|
+
if (pt == "Porosity_decay"):
|
|
221
|
+
return ro.ResqmlUom.VALUE_1_M
|
|
222
|
+
if (pt == "Density_solid"):
|
|
223
|
+
return ro.ResqmlUom.KG_M3
|
|
224
|
+
if (pt == "insulance_thermal"):
|
|
225
|
+
return ro.ThermalInsulanceUom.DELTA_K_M2_W
|
|
226
|
+
if (pt == "Radiogenic_heat_production"):
|
|
227
|
+
return ro.ResqmlUom.U_W_M3
|
|
228
|
+
if (pt == 'dynamic nodes') or (pt=='points'):
|
|
229
|
+
return ro.ResqmlUom.M
|
|
230
|
+
if (pt == 'thermal_conductivity'):
|
|
231
|
+
return ro.ResqmlUom.W_M_K
|
|
232
|
+
if (pt == 'Vitrinite reflectance' or pt == '%Ro'):
|
|
233
|
+
return ro.ResqmlUom.VALUE
|
|
234
|
+
if ("Expelled" in pt):
|
|
235
|
+
return ro.ResqmlUom.KG_M3
|
|
236
|
+
if ("Transformation" in pt):
|
|
237
|
+
return ro.ResqmlUom.VALUE
|
|
238
|
+
return ro.ResqmlUom.EUC
|
|
239
|
+
|
|
240
|
+
def create_resqml_property(prop_title, continuous, indexable_element, uns, epc, min_val=0.0, max_val=1.0,
|
|
241
|
+
timeseries=None, time_index=-1, pre_existing_propertykind = None):
|
|
242
|
+
timeindex_ref = None
|
|
243
|
+
use_timeseries = timeseries is not None
|
|
244
|
+
if use_timeseries:
|
|
245
|
+
# time_index = time_indices[i]
|
|
246
|
+
timeindex_ref = ro.TimeIndex(
|
|
247
|
+
index = time_index,
|
|
248
|
+
time_series = ro.DataObjectReference(
|
|
249
|
+
content_type=f"application/x-resqml+xml;version={schema_version};type={get_data_object_type(timeseries)}",
|
|
250
|
+
title=timeseries.citation.title,
|
|
251
|
+
uuid=timeseries.uuid,
|
|
252
|
+
)
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
r_uom = ro.ResqmlUom( value= uom_for_prop_title(prop_title) )
|
|
256
|
+
# r_uom = ro.ResqmlUom( uom )
|
|
257
|
+
|
|
258
|
+
if (pre_existing_propertykind is None):
|
|
259
|
+
pk_uuid = uuid4()
|
|
260
|
+
propertykind0 = ro.PropertyKind(
|
|
261
|
+
schema_version=schema_version,
|
|
262
|
+
citation=create_common_citation(f"{prop_title}"),
|
|
263
|
+
naming_system="urn:resqml:bp.com:resqpy",
|
|
264
|
+
is_abstract=False,
|
|
265
|
+
representative_uom=uom_for_prop_title(prop_title),
|
|
266
|
+
parent_property_kind=ro.StandardPropertyKind(
|
|
267
|
+
kind=ro.ResqmlPropertyKind.CONTINUOUS if continuous else ro.ResqmlPropertyKind.DISCRETE
|
|
268
|
+
),
|
|
269
|
+
uuid=str(pk_uuid),
|
|
270
|
+
)
|
|
271
|
+
else:
|
|
272
|
+
propertykind0 = pre_existing_propertykind
|
|
273
|
+
|
|
274
|
+
prop_uuid = uuid4()
|
|
275
|
+
|
|
276
|
+
pov = ro.PatchOfValues(
|
|
277
|
+
values=ro.DoubleHdf5Array(
|
|
278
|
+
values=ro.Hdf5Dataset(
|
|
279
|
+
path_in_hdf_file=f"/RESQML/{str(prop_uuid)}/values",
|
|
280
|
+
hdf_proxy=ro.DataObjectReference(
|
|
281
|
+
content_type=f"application/x-eml+xml;version={schema_version};type={get_data_object_type(epc)}",
|
|
282
|
+
title=epc.citation.title,
|
|
283
|
+
uuid=str(epc.uuid),
|
|
284
|
+
),
|
|
285
|
+
)
|
|
286
|
+
) if continuous else
|
|
287
|
+
ro.IntegerHdf5Array(
|
|
288
|
+
values=ro.Hdf5Dataset(
|
|
289
|
+
path_in_hdf_file=f"/RESQML/{str(prop_uuid)}/values",
|
|
290
|
+
hdf_proxy=ro.DataObjectReference(
|
|
291
|
+
content_type=f"application/x-eml+xml;version={schema_version};type={get_data_object_type(epc)}",
|
|
292
|
+
title=epc.citation.title,
|
|
293
|
+
uuid=str(epc.uuid),
|
|
294
|
+
),
|
|
295
|
+
),
|
|
296
|
+
null_value=int(1e30),
|
|
297
|
+
)
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
if (continuous):
|
|
301
|
+
cprop0 = ro.ContinuousProperty(
|
|
302
|
+
schema_version=schema_version,
|
|
303
|
+
citation=create_common_citation(f"{prop_title}"),
|
|
304
|
+
uuid=str(prop_uuid),
|
|
305
|
+
uom = r_uom,
|
|
306
|
+
count=1,
|
|
307
|
+
indexable_element=indexable_element,
|
|
308
|
+
supporting_representation=ro.DataObjectReference(
|
|
309
|
+
content_type=f"application/x-resqml+xml;version={schema_version};type={get_data_object_type(uns)}",
|
|
310
|
+
title=uns.citation.title,
|
|
311
|
+
uuid=uns.uuid,
|
|
312
|
+
),
|
|
313
|
+
property_kind= propertykind0 if pre_existing_propertykind is True else ro.LocalPropertyKind(
|
|
314
|
+
local_property_kind=ro.DataObjectReference(
|
|
315
|
+
content_type=f"application/x-resqml+xml;version={schema_version};type={get_data_object_type(propertykind0)}",
|
|
316
|
+
title=propertykind0.citation.title,
|
|
317
|
+
uuid=propertykind0.uuid,
|
|
318
|
+
)
|
|
319
|
+
), # if (propertykind0 is not None) else ro.StandardPropertyKind(kind=prop.property_kind()),
|
|
320
|
+
minimum_value=[min_val],
|
|
321
|
+
maximum_value=[max_val],
|
|
322
|
+
facet=[ro.PropertyKindFacet(
|
|
323
|
+
facet=ro.Facet.WHAT,
|
|
324
|
+
value=prop_title, # prop.facet(),
|
|
325
|
+
)],
|
|
326
|
+
patch_of_values=[pov],
|
|
327
|
+
time_index=timeindex_ref,
|
|
328
|
+
)
|
|
329
|
+
else:
|
|
330
|
+
cprop0 = ro.DiscreteProperty(
|
|
331
|
+
schema_version=schema_version,
|
|
332
|
+
citation=create_common_citation(f"{prop_title}"),
|
|
333
|
+
uuid=str(prop_uuid),
|
|
334
|
+
# uom = prop.uom(),
|
|
335
|
+
count=1,
|
|
336
|
+
indexable_element=indexable_element,
|
|
337
|
+
supporting_representation=ro.DataObjectReference(
|
|
338
|
+
content_type=f"application/x-resqml+xml;version={schema_version};type={get_data_object_type(uns)}",
|
|
339
|
+
title=uns.citation.title,
|
|
340
|
+
uuid=uns.uuid,
|
|
341
|
+
),
|
|
342
|
+
property_kind=propertykind0 if pre_existing_propertykind is True else ro.LocalPropertyKind(
|
|
343
|
+
local_property_kind=ro.DataObjectReference(
|
|
344
|
+
content_type=f"application/x-resqml+xml;version={schema_version};type={get_data_object_type(propertykind0)}",
|
|
345
|
+
title=propertykind0.citation.title,
|
|
346
|
+
uuid=propertykind0.uuid,
|
|
347
|
+
)
|
|
348
|
+
), # if (propertykind0 is not None) else ro.StandardPropertyKind(kind=prop.property_kind()),
|
|
349
|
+
minimum_value=[int(min_val)],
|
|
350
|
+
maximum_value=[int(max_val)],
|
|
351
|
+
facet=[ro.PropertyKindFacet(
|
|
352
|
+
facet=ro.Facet.WHAT,
|
|
353
|
+
value=prop_title, # prop.facet(),
|
|
354
|
+
)],
|
|
355
|
+
patch_of_values=[pov],
|
|
356
|
+
time_index=timeindex_ref,
|
|
357
|
+
)
|
|
358
|
+
return cprop0, propertykind0
|
|
359
|
+
|
|
360
|
+
def create_resqml_mesh(rmdi, rmdts, geotimes, projected_epsg): #(rddms_mesh_data_initial, rddms_upload_data_timestep)
|
|
361
|
+
import numpy as np
|
|
362
|
+
ro_timestamps = []
|
|
363
|
+
for i in geotimes:
|
|
364
|
+
ro_timestamps.append(
|
|
365
|
+
ro.Timestamp(
|
|
366
|
+
date_time=XmlDateTime.from_string("0001-01-01T00:00:00.00+00:00"),
|
|
367
|
+
year_offset=int(i),
|
|
368
|
+
)
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
gts_citation_title = "warmth simulation"
|
|
372
|
+
gts_uuid = uuid4()
|
|
373
|
+
|
|
374
|
+
timeseries = ro.TimeSeries(
|
|
375
|
+
citation=create_common_citation(str(gts_citation_title)),
|
|
376
|
+
schema_version=schema_version,
|
|
377
|
+
uuid=str(gts_uuid),
|
|
378
|
+
time = ro_timestamps,
|
|
379
|
+
)
|
|
380
|
+
crs = create_common_crs(gts_citation_title, projected_epsg)
|
|
381
|
+
epc = ro.EpcExternalPartReference(
|
|
382
|
+
citation=create_common_citation("Hdf Proxy"),
|
|
383
|
+
schema_version=schema_version,
|
|
384
|
+
uuid=str(uuid4()),
|
|
385
|
+
mime_type="application/x-hdf5",
|
|
386
|
+
)
|
|
387
|
+
cellshape = ro.CellShape.HEXAHEDRAL ## if (hexa.cell_shape == "hexahedral") else ro.CellShape.TETRAHEDRAL
|
|
388
|
+
cells = rmdi.hexa_renumbered
|
|
389
|
+
nodes_time_0 = rmdts.points_cached
|
|
390
|
+
node_count = nodes_time_0.shape[0]
|
|
391
|
+
faces_per_cell = []
|
|
392
|
+
nodes_per_face = []
|
|
393
|
+
faces_dict = {}
|
|
394
|
+
faces_repeat = np.zeros(node_count*100, dtype = bool)
|
|
395
|
+
cell_face_is_right_handed = np.zeros( len(cells)*6, dtype = bool)
|
|
396
|
+
|
|
397
|
+
for ih,hexa in enumerate(cells):
|
|
398
|
+
faces= [[0,3,2,1], [0,1,5,4], [1,2,6,5], [2,3,7,6], [3,0,4,7], [4,5,6,7]]
|
|
399
|
+
for iq,quad in enumerate(faces):
|
|
400
|
+
face0 = [hexa[x] for x in quad ]
|
|
401
|
+
assert -1 not in face0
|
|
402
|
+
fkey0 = ( x for x in sorted(face0) )
|
|
403
|
+
#
|
|
404
|
+
# keep track of which faces are encountered once vs. more than once
|
|
405
|
+
# faces that are encountered the second time will need to use the reverse handedness
|
|
406
|
+
#
|
|
407
|
+
face_is_repeated = False
|
|
408
|
+
if (fkey0 not in faces_dict):
|
|
409
|
+
faces_dict[fkey0] = len(nodes_per_face)
|
|
410
|
+
nodes_per_face.extend(face0)
|
|
411
|
+
cell_face_is_right_handed[(ih*6 + iq)] = False
|
|
412
|
+
else:
|
|
413
|
+
face_is_repeated = True
|
|
414
|
+
cell_face_is_right_handed[(ih*6 + iq)] = True
|
|
415
|
+
fidx0 = faces_dict.get(fkey0)
|
|
416
|
+
faces_per_cell.append(fidx0/4)
|
|
417
|
+
faces_repeat[int(fidx0/4)] = face_is_repeated
|
|
418
|
+
set_cell_count = int(len(faces_per_cell)/6)
|
|
419
|
+
face_count = int(len(nodes_per_face)/4)
|
|
420
|
+
|
|
421
|
+
node_count=node_count
|
|
422
|
+
face_count=face_count
|
|
423
|
+
cell_count=set_cell_count
|
|
424
|
+
|
|
425
|
+
hexa_uuid = uuid4()
|
|
426
|
+
geom = ro.UnstructuredGridGeometry(
|
|
427
|
+
local_crs=ro.DataObjectReference(
|
|
428
|
+
content_type=f"application/x-resqml+xml;version={schema_version};type={get_data_object_type(crs)}",
|
|
429
|
+
title=crs.citation.title,
|
|
430
|
+
uuid=crs.uuid,
|
|
431
|
+
),
|
|
432
|
+
node_count=node_count,
|
|
433
|
+
face_count=face_count,
|
|
434
|
+
cell_shape=cellshape,
|
|
435
|
+
points=ro.Point3dHdf5Array(
|
|
436
|
+
coordinates=ro.Hdf5Dataset(
|
|
437
|
+
path_in_hdf_file=f"/RESQML/{str(hexa_uuid)}/points",
|
|
438
|
+
hdf_proxy=ro.DataObjectReference(
|
|
439
|
+
content_type=f"application/x-eml+xml;version={schema_version};type={get_data_object_type(epc)}",
|
|
440
|
+
title=epc.citation.title,
|
|
441
|
+
uuid=str(epc.uuid),
|
|
442
|
+
),
|
|
443
|
+
)
|
|
444
|
+
),
|
|
445
|
+
nodes_per_face=ro.ResqmlJaggedArray(
|
|
446
|
+
elements=ro.IntegerHdf5Array(
|
|
447
|
+
null_value=-1,
|
|
448
|
+
values=ro.Hdf5Dataset(
|
|
449
|
+
path_in_hdf_file=f"/RESQML/{str(hexa_uuid)}/nodes_per_face",
|
|
450
|
+
hdf_proxy=ro.DataObjectReference(
|
|
451
|
+
content_type=f"application/x-eml+xml;version={schema_version};type={get_data_object_type(epc)}",
|
|
452
|
+
title=epc.citation.title,
|
|
453
|
+
uuid=str(epc.uuid),
|
|
454
|
+
),
|
|
455
|
+
)
|
|
456
|
+
),
|
|
457
|
+
cumulative_length=ro.IntegerHdf5Array(
|
|
458
|
+
null_value=-1,
|
|
459
|
+
values=ro.Hdf5Dataset(
|
|
460
|
+
path_in_hdf_file=f"/RESQML/{str(hexa_uuid)}/nodes_per_face_cl",
|
|
461
|
+
hdf_proxy=ro.DataObjectReference(
|
|
462
|
+
content_type=f"application/x-eml+xml;version={schema_version};type={get_data_object_type(epc)}",
|
|
463
|
+
title=epc.citation.title,
|
|
464
|
+
uuid=str(epc.uuid),
|
|
465
|
+
),
|
|
466
|
+
)
|
|
467
|
+
),
|
|
468
|
+
),
|
|
469
|
+
faces_per_cell=ro.ResqmlJaggedArray(
|
|
470
|
+
elements=ro.IntegerHdf5Array(
|
|
471
|
+
null_value=-1,
|
|
472
|
+
values=ro.Hdf5Dataset(
|
|
473
|
+
path_in_hdf_file=f"/RESQML/{str(hexa_uuid)}/faces_per_cell",
|
|
474
|
+
hdf_proxy=ro.DataObjectReference(
|
|
475
|
+
content_type=f"application/x-eml+xml;version={schema_version};type={get_data_object_type(epc)}",
|
|
476
|
+
title=epc.citation.title,
|
|
477
|
+
uuid=str(epc.uuid),
|
|
478
|
+
),
|
|
479
|
+
)
|
|
480
|
+
),
|
|
481
|
+
cumulative_length=ro.IntegerHdf5Array(
|
|
482
|
+
null_value=-1,
|
|
483
|
+
values=ro.Hdf5Dataset(
|
|
484
|
+
path_in_hdf_file=f"/RESQML/{str(hexa_uuid)}/faces_per_cell_cl",
|
|
485
|
+
hdf_proxy=ro.DataObjectReference(
|
|
486
|
+
content_type=f"application/x-eml+xml;version={schema_version};type={get_data_object_type(epc)}",
|
|
487
|
+
title=epc.citation.title,
|
|
488
|
+
uuid=str(epc.uuid),
|
|
489
|
+
),
|
|
490
|
+
)
|
|
491
|
+
),
|
|
492
|
+
),
|
|
493
|
+
cell_face_is_right_handed=ro.BooleanHdf5Array(
|
|
494
|
+
values=ro.Hdf5Dataset(
|
|
495
|
+
path_in_hdf_file=f"/RESQML/{str(hexa_uuid)}/cell_face_is_right_handed",
|
|
496
|
+
hdf_proxy=ro.DataObjectReference(
|
|
497
|
+
content_type=f"application/x-eml+xml;version={schema_version};type={get_data_object_type(epc)}",
|
|
498
|
+
title=epc.citation.title,
|
|
499
|
+
uuid=str(epc.uuid),
|
|
500
|
+
),
|
|
501
|
+
)
|
|
502
|
+
)
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
#
|
|
506
|
+
uns = ro.UnstructuredGridRepresentation(
|
|
507
|
+
uuid=str(hexa_uuid),
|
|
508
|
+
schema_version=schema_version,
|
|
509
|
+
# surface_role=resqml_objects.SurfaceRole.MAP,
|
|
510
|
+
citation=create_common_citation(gts_citation_title),
|
|
511
|
+
cell_count=cell_count,
|
|
512
|
+
geometry=geom,
|
|
513
|
+
)
|
|
514
|
+
return uns, crs, epc, timeseries
|
|
515
|
+
|
|
516
|
+
|
|
211
517
|
def convert_epc_mesh_to_resqml_mesh(epc_filename, title_in, projected_epsg):
|
|
212
518
|
import resqpy.model as rq
|
|
213
519
|
import resqpy.time_series as rts
|
|
@@ -232,12 +538,9 @@ def convert_epc_mesh_to_resqml_mesh(epc_filename, title_in, projected_epsg):
|
|
|
232
538
|
# ts_uuid_2 = model.uuid(obj_type='GeologicTimeSeries')
|
|
233
539
|
# logger.debug(f"TS UUIDs: {ts_uuid} {ts_uuid_2}")
|
|
234
540
|
gts = rts.GeologicTimeSeries(model, uuid=ts_uuid)
|
|
235
|
-
|
|
236
541
|
logger.debug(f"gts: {gts}")
|
|
237
542
|
timeseries = None
|
|
238
|
-
# dynamic_points = []
|
|
239
543
|
if (ts_uuid is not None) and (gts is not None):
|
|
240
|
-
|
|
241
544
|
ro_timestamps = []
|
|
242
545
|
for i in gts.iter_timestamps(as_string=False):
|
|
243
546
|
ro_timestamps.append(
|
|
@@ -246,9 +549,7 @@ def convert_epc_mesh_to_resqml_mesh(epc_filename, title_in, projected_epsg):
|
|
|
246
549
|
year_offset=int(i),
|
|
247
550
|
)
|
|
248
551
|
)
|
|
249
|
-
|
|
250
552
|
logger.info(f"Generating time series with {len(ro_timestamps)} indices, year offsets: {ro_timestamps[0].year_offset} -- {ro_timestamps[-1].year_offset}.")
|
|
251
|
-
|
|
252
553
|
timeseries = ro.TimeSeries(
|
|
253
554
|
citation=create_common_citation(str(gts.citation_title)),
|
|
254
555
|
schema_version=schema_version,
|
|
@@ -256,6 +557,7 @@ def convert_epc_mesh_to_resqml_mesh(epc_filename, title_in, projected_epsg):
|
|
|
256
557
|
time=ro_timestamps,
|
|
257
558
|
)
|
|
258
559
|
|
|
560
|
+
|
|
259
561
|
crs = create_common_crs(title, projected_epsg)
|
|
260
562
|
|
|
261
563
|
epc = ro.EpcExternalPartReference(
|
|
@@ -363,35 +665,6 @@ def convert_epc_mesh_property_to_resqml_mesh(epc_filename, hexa, prop_title, uns
|
|
|
363
665
|
import resqpy.model as rq
|
|
364
666
|
import resqpy.property as rqp
|
|
365
667
|
|
|
366
|
-
def uom_for_prop_title(pt: str):
|
|
367
|
-
if (pt == "Age"):
|
|
368
|
-
return ro.ResqmlUom.A_1
|
|
369
|
-
if (pt == "Temperature"):
|
|
370
|
-
return ro.ResqmlUom.DEG_C
|
|
371
|
-
if (pt == "LayerID"):
|
|
372
|
-
return ro.ResqmlUom.EUC
|
|
373
|
-
if (pt == "Porosity_initial"):
|
|
374
|
-
return ro.ResqmlUom.M3_M3
|
|
375
|
-
if (pt == "Porosity_decay"):
|
|
376
|
-
return ro.ResqmlUom.VALUE_1_M
|
|
377
|
-
if (pt == "Density_solid"):
|
|
378
|
-
return ro.ResqmlUom.KG_M3
|
|
379
|
-
if (pt == "insulance_thermal"):
|
|
380
|
-
return ro.ThermalInsulanceUom.DELTA_K_M2_W
|
|
381
|
-
if (pt == "Radiogenic_heat_production"):
|
|
382
|
-
return ro.ResqmlUom.U_W_M3
|
|
383
|
-
if (pt == 'dynamic nodes') or (pt == 'points'):
|
|
384
|
-
return ro.ResqmlUom.M
|
|
385
|
-
if (pt == 'thermal_conductivity'):
|
|
386
|
-
return ro.ResqmlUom.W_M_K
|
|
387
|
-
if (pt == 'Vitrinite reflectance' or pt == '%Ro'):
|
|
388
|
-
return ro.ResqmlUom.VALUE
|
|
389
|
-
if ("Expelled" in pt):
|
|
390
|
-
return ro.ResqmlUom.KG_M3
|
|
391
|
-
if ("Transformation" in pt):
|
|
392
|
-
return ro.ResqmlUom.VALUE
|
|
393
|
-
return ro.ResqmlUom.EUC
|
|
394
|
-
|
|
395
668
|
model = rq.Model(epc_filename)
|
|
396
669
|
assert model is not None
|
|
397
670
|
prop_types = ['obj_ContinuousProperty', 'obj_DiscreteProperty', 'obj_CategoricalProperty', 'obj_PointsProperty']
|
|
@@ -438,6 +711,8 @@ def convert_epc_mesh_property_to_resqml_mesh(epc_filename, hexa, prop_title, uns
|
|
|
438
711
|
prop_uuid = prop_uuids[time_indices[i]]
|
|
439
712
|
prop = rqp.Property(model, uuid=prop_uuid)
|
|
440
713
|
|
|
714
|
+
# def create_resqml_property(prop_title, continuous, indexable_element, uns, epc, min_val=0.0, max_val=1.0, timeseries=None, time_index=-1):
|
|
715
|
+
|
|
441
716
|
pov = ro.PatchOfValues(
|
|
442
717
|
values=ro.DoubleHdf5Array(
|
|
443
718
|
values=ro.Hdf5Dataset(
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
pyetp/__init__.py,sha256=FSlPJ3AXoMe3vDQ0z8k417aKJWwt7sxbNPsLgdc21tI,123
|
|
2
|
-
pyetp/client.py,sha256=
|
|
2
|
+
pyetp/client.py,sha256=MJmS-HfQKmbcfMriakDcwwoBdVgMQAF6LcpgdFx20TU,49638
|
|
3
3
|
pyetp/config.py,sha256=Z0Q3dH0olM4CKLckDA_EV23XK_al2Ey8D9JrKb3s5R0,949
|
|
4
4
|
pyetp/resqml_objects/__init__.py,sha256=Sr_1bktzS8JMmE9oi6pcW6BuERm7gH0u50rBs58zI7Q,50492
|
|
5
5
|
pyetp/resqml_objects/generated.py,sha256=P-hfL8btOE6uAmtaGXbSdWMl8Z9iJx-r6FRzSvmzHvU,783914
|
|
6
6
|
pyetp/types.py,sha256=E-CvzI74kiQ52J42DQ-5wGUC84l3-glYs3NQ36HIs1I,2559
|
|
7
|
-
pyetp/uri.py,sha256=
|
|
7
|
+
pyetp/uri.py,sha256=57wTOH7EAGXluDiGxIe34DAiftPR91jEnbRB5thaG8k,2963
|
|
8
8
|
pyetp/utils.py,sha256=WxfG13bItprl457H3EEsckF1uDwF-hzPhVG7QRX0LB8,158
|
|
9
9
|
pyetp/utils_arrays.py,sha256=HHhw23La4SG7UJyd5Q_OJ5WlMq98QpwHBk553YyyYOk,4331
|
|
10
|
-
pyetp/utils_xml.py,sha256=
|
|
11
|
-
pyetp-0.0.
|
|
12
|
-
pyetp-0.0.
|
|
13
|
-
pyetp-0.0.
|
|
14
|
-
pyetp-0.0.
|
|
10
|
+
pyetp/utils_xml.py,sha256=_sczOVws6h60dQXkUyV7z_OJrVgcGQw2zQlvUA8jI4A,33639
|
|
11
|
+
pyetp-0.0.30.dist-info/LICENSE.md,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
12
|
+
pyetp-0.0.30.dist-info/METADATA,sha256=xF1KaKkQuMw4nY_XDpD54KMpgQk71aoRdpbc15pP01M,2393
|
|
13
|
+
pyetp-0.0.30.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
14
|
+
pyetp-0.0.30.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|