resqpy 4.14.1__py3-none-any.whl → 5.1.5__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.
- resqpy/__init__.py +1 -1
- resqpy/fault/_gcs_functions.py +10 -10
- resqpy/fault/_grid_connection_set.py +277 -113
- resqpy/grid/__init__.py +2 -3
- resqpy/grid/_defined_geometry.py +3 -3
- resqpy/grid/_extract_functions.py +2 -1
- resqpy/grid/_grid.py +95 -12
- resqpy/grid/_grid_types.py +22 -7
- resqpy/grid/_points_functions.py +1 -1
- resqpy/grid/_regular_grid.py +6 -2
- resqpy/grid_surface/__init__.py +17 -38
- resqpy/grid_surface/_blocked_well_populate.py +5 -5
- resqpy/grid_surface/_find_faces.py +1349 -253
- resqpy/lines/_polyline.py +24 -33
- resqpy/model/_catalogue.py +9 -0
- resqpy/model/_forestry.py +18 -14
- resqpy/model/_hdf5.py +11 -3
- resqpy/model/_model.py +85 -10
- resqpy/model/_xml.py +38 -13
- resqpy/multi_processing/wrappers/grid_surface_mp.py +92 -37
- resqpy/olio/read_nexus_fault.py +8 -2
- resqpy/olio/relperm.py +1 -1
- resqpy/olio/transmission.py +8 -8
- resqpy/olio/triangulation.py +36 -30
- resqpy/olio/vector_utilities.py +340 -6
- resqpy/olio/volume.py +0 -20
- resqpy/olio/wellspec_keywords.py +19 -13
- resqpy/olio/write_hdf5.py +1 -1
- resqpy/olio/xml_et.py +12 -0
- resqpy/property/__init__.py +6 -4
- resqpy/property/_collection_add_part.py +4 -3
- resqpy/property/_collection_create_xml.py +4 -2
- resqpy/property/_collection_get_attributes.py +4 -0
- resqpy/property/attribute_property_set.py +311 -0
- resqpy/property/grid_property_collection.py +11 -11
- resqpy/property/property_collection.py +79 -31
- resqpy/property/property_common.py +3 -8
- resqpy/rq_import/_add_surfaces.py +34 -14
- resqpy/rq_import/_grid_from_cp.py +2 -2
- resqpy/rq_import/_import_nexus.py +75 -48
- resqpy/rq_import/_import_vdb_all_grids.py +64 -52
- resqpy/rq_import/_import_vdb_ensemble.py +12 -13
- resqpy/surface/_mesh.py +4 -0
- resqpy/surface/_surface.py +593 -118
- resqpy/surface/_tri_mesh.py +22 -12
- resqpy/surface/_tri_mesh_stencil.py +4 -4
- resqpy/surface/_triangulated_patch.py +71 -51
- resqpy/time_series/_any_time_series.py +7 -4
- resqpy/time_series/_geologic_time_series.py +1 -1
- resqpy/unstructured/_hexa_grid.py +6 -2
- resqpy/unstructured/_prism_grid.py +13 -5
- resqpy/unstructured/_pyramid_grid.py +6 -2
- resqpy/unstructured/_tetra_grid.py +6 -2
- resqpy/unstructured/_unstructured_grid.py +6 -2
- resqpy/well/_blocked_well.py +1986 -1946
- resqpy/well/_deviation_survey.py +3 -3
- resqpy/well/_md_datum.py +11 -21
- resqpy/well/_trajectory.py +10 -5
- resqpy/well/_wellbore_frame.py +10 -2
- resqpy/well/blocked_well_frame.py +3 -3
- resqpy/well/well_object_funcs.py +7 -9
- resqpy/well/well_utils.py +33 -0
- {resqpy-4.14.1.dist-info → resqpy-5.1.5.dist-info}/METADATA +8 -9
- {resqpy-4.14.1.dist-info → resqpy-5.1.5.dist-info}/RECORD +66 -66
- {resqpy-4.14.1.dist-info → resqpy-5.1.5.dist-info}/WHEEL +1 -1
- resqpy/grid/_moved_functions.py +0 -15
- {resqpy-4.14.1.dist-info → resqpy-5.1.5.dist-info}/LICENSE +0 -0
resqpy/lines/_polyline.py
CHANGED
@@ -25,25 +25,22 @@ class Polyline(rql_c._BasePolyline):
|
|
25
25
|
|
26
26
|
resqml_type = 'PolylineRepresentation'
|
27
27
|
|
28
|
-
def __init__(
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
originator = None,
|
39
|
-
extra_metadata = None):
|
28
|
+
def __init__(self,
|
29
|
+
parent_model,
|
30
|
+
uuid = None,
|
31
|
+
set_coord = None,
|
32
|
+
set_crs = None,
|
33
|
+
is_closed = None,
|
34
|
+
title = None,
|
35
|
+
rep_int_root = None,
|
36
|
+
originator = None,
|
37
|
+
extra_metadata = None):
|
40
38
|
"""Initialises a new polyline object.
|
41
39
|
|
42
40
|
arguments:
|
43
41
|
parent_model (model.Model object): the model which the new PolylineRepresentation belongs to
|
44
42
|
uuid (uuid.UUID, optional): the uuid of an existing RESQML PolylineRepresentation from which
|
45
43
|
to initialise the resqpy Polyline
|
46
|
-
set_bool (boolean, optional): DEPRECATED: synonym for is_closed argument
|
47
44
|
set_coord (numpy float array, optional): an ordered set of xyz values used to define a new polyline;
|
48
45
|
last dimension of array must have extent 3; ignored if uuid is not None
|
49
46
|
set_crs (uuid.UUID, optional): the uuid of a crs to be used when initialising from coordinates;
|
@@ -65,10 +62,6 @@ class Polyline(rql_c._BasePolyline):
|
|
65
62
|
"""
|
66
63
|
|
67
64
|
self.model = parent_model
|
68
|
-
if set_bool is not None:
|
69
|
-
warnings.warn('DEPRECATED: use is_closed argument instead of set_bool, in Polyline initialisation')
|
70
|
-
if is_closed is None:
|
71
|
-
is_closed = set_bool
|
72
65
|
self.isclosed = is_closed
|
73
66
|
self.nodepatch = None
|
74
67
|
self.crs_uuid = set_crs
|
@@ -466,22 +459,20 @@ class Polyline(rql_c._BasePolyline):
|
|
466
459
|
if cache and self.centre is not None:
|
467
460
|
return self.centre
|
468
461
|
assert mode in ['weighted', 'sampled']
|
469
|
-
if mode
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
seg_count
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
sum += (p1 + p2) * vu.naive_length(p2 - p1)
|
484
|
-
centre = sum / (2.0 * self.full_length(in_xy = in_xy))
|
462
|
+
if mode != 'weighted': # ignore any other mode, ie. sampled
|
463
|
+
warnings.warn('DEPRECATED: weighted mode is only mode now supported for Polyline.balanced_centre()')
|
464
|
+
sum = np.zeros(3)
|
465
|
+
seg_count = len(self.coordinates) - 1
|
466
|
+
if self.isclosed:
|
467
|
+
seg_count += 1
|
468
|
+
d = 2 if in_xy else 3
|
469
|
+
p1 = np.zeros(3)
|
470
|
+
p2 = np.zeros(3)
|
471
|
+
for seg_index in range(seg_count):
|
472
|
+
successor = (seg_index + 1) % len(self.coordinates)
|
473
|
+
p1[:d], p2[:d] = self.coordinates[seg_index, :d], self.coordinates[successor, :d]
|
474
|
+
sum += (p1 + p2) * vu.naive_length(p2 - p1)
|
475
|
+
centre = sum / (2.0 * self.full_length(in_xy = in_xy))
|
485
476
|
if cache:
|
486
477
|
self.centre = centre
|
487
478
|
return centre
|
resqpy/model/_catalogue.py
CHANGED
@@ -553,6 +553,15 @@ def _citation_title_for_part(model, part): # duplicate functionality to title_f
|
|
553
553
|
return title
|
554
554
|
|
555
555
|
|
556
|
+
def _source_for_part(model, part):
|
557
|
+
"""Returns the source string from the part's extra metadata, if present, else None."""
|
558
|
+
|
559
|
+
part_extra = rqet.load_metadata_from_xml(_root_for_part(model, part))
|
560
|
+
if not part_extra:
|
561
|
+
return None
|
562
|
+
return part_extra.get('source')
|
563
|
+
|
564
|
+
|
556
565
|
def _root_for_time_series(model, uuid = None):
|
557
566
|
"""Return root for time series part."""
|
558
567
|
|
resqpy/model/_forestry.py
CHANGED
@@ -200,8 +200,8 @@ def _load_epc(model, epc_file, full_load = True, epc_subdir = None, copy_from =
|
|
200
200
|
def _add_uuid_soft_relations(model, uuid_int, part):
|
201
201
|
if "EpcExternalPart" in part:
|
202
202
|
return
|
203
|
-
|
204
|
-
if
|
203
|
+
rels_part = rqet.rels_part_name_for_part(part)
|
204
|
+
if rels_part in model.rels_forest:
|
205
205
|
rels_root = m_c._root_for_part(model, rqet.rels_part_name_for_part(part), is_rels = True)
|
206
206
|
if rels_root is not None:
|
207
207
|
for relation_node in rels_root:
|
@@ -214,9 +214,10 @@ def _add_uuid_soft_relations(model, uuid_int, part):
|
|
214
214
|
if relation_uuid_str is None:
|
215
215
|
return # probably HDF5 external resource
|
216
216
|
relation_uuid_int = _hex_to_int(relation_uuid_str)
|
217
|
-
|
218
|
-
if
|
219
|
-
|
217
|
+
rels_sets = model.uuid_rels_dict.get(uuid_int)
|
218
|
+
if rels_sets is not None and relation_uuid_int not in rels_sets[
|
219
|
+
0] and relation_uuid_int not in rels_sets[1]:
|
220
|
+
rels_sets[2].add(relation_uuid_int)
|
220
221
|
|
221
222
|
|
222
223
|
def _add_uuid_relations(model, uuid_int, part):
|
@@ -685,17 +686,23 @@ def _copy_referenced_parts(model, other_model, realization, consolidate, force,
|
|
685
686
|
resident_uuid_int = model.consolidation.map[ref_uuid_int]
|
686
687
|
assert resident_uuid_int is not None
|
687
688
|
# find referring node for ref_uuid_int and modify its reference to resident_uuid_int
|
688
|
-
if reference_node_dict is None:
|
689
|
+
if reference_node_dict is None: # now mapping uuid int to list of nodes
|
689
690
|
ref_nodes = rqet.list_obj_references(root_node)
|
690
691
|
reference_node_dict = {}
|
691
692
|
for ref_node in ref_nodes:
|
692
693
|
uuid_node = rqet.find_tag(ref_node, 'UUID')
|
693
694
|
uuid_int = bu.uuid_from_string(uuid_node.text).int
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
695
|
+
if uuid_int in reference_node_dict:
|
696
|
+
reference_node_dict[uuid_int].append(uuid_node)
|
697
|
+
else:
|
698
|
+
reference_node_dict[uuid_int] = [uuid_node]
|
699
|
+
uuid_node_list = reference_node_dict.pop(ref_uuid_int)
|
700
|
+
for uuid_node in uuid_node_list:
|
701
|
+
uuid_node.text = str(bu.uuid_from_int(resident_uuid_int))
|
702
|
+
if resident_uuid_int in reference_node_dict:
|
703
|
+
reference_node_dict[resident_uuid_int] += uuid_node_list
|
704
|
+
else:
|
705
|
+
reference_node_dict[resident_uuid_int] = uuid_node_list
|
699
706
|
|
700
707
|
|
701
708
|
def _copy_relationships_for_present_targets(model, other_model, consolidate, force, resident_uuid, root_node):
|
@@ -719,9 +726,6 @@ def _copy_relationships_for_present_targets(model, other_model, consolidate, for
|
|
719
726
|
continue
|
720
727
|
else:
|
721
728
|
continue
|
722
|
-
if not force and resident_related_part in m_c._parts_list_filtered_by_related_uuid(
|
723
|
-
model, m_c._list_of_parts(model), resident_uuid):
|
724
|
-
continue
|
725
729
|
related_node = m_c._root_for_part(model, resident_related_part)
|
726
730
|
assert related_node is not None
|
727
731
|
|
resqpy/model/_hdf5.py
CHANGED
@@ -262,11 +262,11 @@ def _h5_array_element(model,
|
|
262
262
|
if dtype is None:
|
263
263
|
return result
|
264
264
|
if result.size == 1:
|
265
|
-
if dtype is float or (isinstance(dtype, str) and
|
265
|
+
if dtype is float or (isinstance(dtype, str) and ('float' in dtype)):
|
266
266
|
return float(result)
|
267
|
-
elif dtype is int or (isinstance(dtype, str) and
|
267
|
+
elif dtype is int or (isinstance(dtype, str) and ('int' in dtype)):
|
268
268
|
return int(result)
|
269
|
-
elif dtype is bool or (isinstance(dtype, str) and
|
269
|
+
elif dtype is bool or (isinstance(dtype, str) and ('bool' in dtype)):
|
270
270
|
return bool(result)
|
271
271
|
return np.array(result, dtype = dtype)
|
272
272
|
|
@@ -286,6 +286,14 @@ def _h5_overwrite_array_slice(model, h5_key_pair, slice_tuple, array_slice):
|
|
286
286
|
dset[slice_tuple] = array_slice
|
287
287
|
|
288
288
|
|
289
|
+
def _h5_overwrite_array(model, h5_key_pair, array):
|
290
|
+
"""Overwrites (updates) the whole of an hdf5 array."""
|
291
|
+
|
292
|
+
h5_root = _h5_access(model, h5_key_pair[0], mode = 'a')
|
293
|
+
dset = h5_root[h5_key_pair[1]]
|
294
|
+
dset[...] = array
|
295
|
+
|
296
|
+
|
289
297
|
def h5_clear_filename_cache(model):
|
290
298
|
"""Clears the cached filenames associated with all ext uuids."""
|
291
299
|
|
resqpy/model/_model.py
CHANGED
@@ -1108,6 +1108,66 @@ class Model():
|
|
1108
1108
|
|
1109
1109
|
return m_c._citation_title_for_part(self, part)
|
1110
1110
|
|
1111
|
+
def source_for_part(self, part):
|
1112
|
+
"""Returns the source string from the part's extra metadata, if present, else None.
|
1113
|
+
|
1114
|
+
arguments:
|
1115
|
+
part (str): the part for which the source information is required
|
1116
|
+
|
1117
|
+
returns:
|
1118
|
+
str being the text of the source field in the xml extra metadata of the part, or None
|
1119
|
+
"""
|
1120
|
+
|
1121
|
+
return m_c._source_for_part(self, part)
|
1122
|
+
|
1123
|
+
def set_source_for_part(self, part, source):
|
1124
|
+
"""Sets the source string in the part's extra metadata.
|
1125
|
+
|
1126
|
+
arguments:
|
1127
|
+
part (str): the part for which the source information is to be set
|
1128
|
+
source (str): text for the extra metadata source item
|
1129
|
+
|
1130
|
+
notes:
|
1131
|
+
this function adds the source item to the in-memory xml extra metadata;
|
1132
|
+
any previous text for the source item (if present) will be replaced;
|
1133
|
+
it will be included in the epc if store_epc() is subsequently called
|
1134
|
+
"""
|
1135
|
+
|
1136
|
+
m_x._create_source(source, root = m_c._root_for_part(self, part))
|
1137
|
+
self.set_modified()
|
1138
|
+
|
1139
|
+
def source_for_obj(self, obj):
|
1140
|
+
"""Returns the source string from the object's extra metadata, if present, else None.
|
1141
|
+
|
1142
|
+
arguments:
|
1143
|
+
obj (BaseResqpy): any high level resqpy object (eg. Surface)
|
1144
|
+
|
1145
|
+
returns:
|
1146
|
+
str being the text of the source extra metadata item for the object, or None
|
1147
|
+
"""
|
1148
|
+
|
1149
|
+
return m_c._source_for_part(self, obj.part)
|
1150
|
+
|
1151
|
+
def set_source_for_obj(self, obj, source):
|
1152
|
+
"""Sets the source string in the object's extra metadata.
|
1153
|
+
|
1154
|
+
arguments:
|
1155
|
+
part (str): the part for which the source information is to be set
|
1156
|
+
source (str): text for the extra metadata source item
|
1157
|
+
|
1158
|
+
notes:
|
1159
|
+
this function adds the source item to the in-memory xml extra metadata as well as
|
1160
|
+
the object's extra_metadata dictionary
|
1161
|
+
any previous text for the source item (if present) will be replaced;
|
1162
|
+
it will be included in the epc if store_epc() is subsequently called
|
1163
|
+
"""
|
1164
|
+
|
1165
|
+
m_x._create_source(source, root = obj.root)
|
1166
|
+
if not hasattr(obj, 'extra_metadata') or obj.extra_metadata is None:
|
1167
|
+
obj.extra_metadata = {}
|
1168
|
+
obj.extra_metadata['source'] = str(source)
|
1169
|
+
self.set_modified()
|
1170
|
+
|
1111
1171
|
def root_for_time_series(self, uuid = None):
|
1112
1172
|
"""Return root for time series part.
|
1113
1173
|
|
@@ -1280,7 +1340,8 @@ class Model():
|
|
1280
1340
|
an hdf5 file name is cached once determined for a given ext uuid; to clear the cache,
|
1281
1341
|
call the h5_clear_filename_cache() method
|
1282
1342
|
"""
|
1283
|
-
|
1343
|
+
if isinstance(override, bool):
|
1344
|
+
warnings.warn('DEPRECATED: boolean override argument to Model.h5_file_name(); use string instead')
|
1284
1345
|
return m_h._h5_file_name(self, uuid = uuid, override = override, file_must_exist = file_must_exist)
|
1285
1346
|
|
1286
1347
|
def h5_access(self, uuid = None, mode = 'r', override = 'default', file_path = None):
|
@@ -1306,7 +1367,8 @@ class Model():
|
|
1306
1367
|
an exception will be raised if the hdf5 file cannot be opened; note that sometimes another
|
1307
1368
|
piece of code accessing the file might cause a 'resource unavailable' exception
|
1308
1369
|
"""
|
1309
|
-
|
1370
|
+
if isinstance(override, bool):
|
1371
|
+
warnings.warn('DEPRECATED: boolean override argument to Model.h5_access(); use string instead')
|
1310
1372
|
return m_h._h5_access(self, uuid = uuid, mode = mode, override = override, file_path = file_path)
|
1311
1373
|
|
1312
1374
|
def h5_release(self):
|
@@ -1339,7 +1401,7 @@ class Model():
|
|
1339
1401
|
cache_array = False,
|
1340
1402
|
object = None,
|
1341
1403
|
array_attribute = None,
|
1342
|
-
dtype =
|
1404
|
+
dtype = None,
|
1343
1405
|
required_shape = None):
|
1344
1406
|
"""Returns one element from an hdf5 array and/or caches the array.
|
1345
1407
|
|
@@ -1415,6 +1477,21 @@ class Model():
|
|
1415
1477
|
|
1416
1478
|
return m_h._h5_overwrite_array_slice(self, h5_key_pair, slice_tuple, array_slice)
|
1417
1479
|
|
1480
|
+
def h5_overwrite_array(self, h5_key_pair, array):
|
1481
|
+
"""Overwrites (updates) the whole of an hdf5 array.
|
1482
|
+
|
1483
|
+
arguments:
|
1484
|
+
h5_key_pair (uuid, string): the uuid of the hdf5 ext part and the hdf5 internal path to the
|
1485
|
+
required hdf5 array
|
1486
|
+
array (numpy array of shape to match existing hdf5 dataset): the data to write
|
1487
|
+
|
1488
|
+
notes:
|
1489
|
+
this method naively updates an hdf5 array without using mpi to look after parallel updates;
|
1490
|
+
metadata (such as uuid or property min, max values) is not modified in any way by the method
|
1491
|
+
"""
|
1492
|
+
|
1493
|
+
return m_h._h5_overwrite_array(self, h5_key_pair, array)
|
1494
|
+
|
1418
1495
|
def h5_clear_filename_cache(self):
|
1419
1496
|
"""Clears the cached filenames associated with all ext uuids."""
|
1420
1497
|
|
@@ -2023,6 +2100,11 @@ class Model():
|
|
2023
2100
|
if other_model is self:
|
2024
2101
|
return part
|
2025
2102
|
assert part is not None
|
2103
|
+
# check whether already existing in this model
|
2104
|
+
if part in self.parts_forest.keys():
|
2105
|
+
return part
|
2106
|
+
if m_c._type_of_part(other_model, part) == 'obj_EpcExternalPartReference':
|
2107
|
+
return None
|
2026
2108
|
if realization is not None:
|
2027
2109
|
assert isinstance(realization, int) and realization >= 0
|
2028
2110
|
if force:
|
@@ -2033,13 +2115,6 @@ class Model():
|
|
2033
2115
|
self_h5_file_name = self.h5_file_name(file_must_exist = False)
|
2034
2116
|
hdf5_copy_needed = not os.path.samefile(self_h5_file_name, other_h5_file_name)
|
2035
2117
|
|
2036
|
-
# check whether already existing in this model
|
2037
|
-
if part in self.parts_forest.keys():
|
2038
|
-
return part
|
2039
|
-
|
2040
|
-
if m_c._type_of_part(other_model, part) == 'obj_EpcExternalPartReference':
|
2041
|
-
return None
|
2042
|
-
|
2043
2118
|
return m_f._copy_part_from_other_model(self,
|
2044
2119
|
other_model,
|
2045
2120
|
part,
|
resqpy/model/_xml.py
CHANGED
@@ -420,22 +420,39 @@ def _create_supporting_representation(model,
|
|
420
420
|
|
421
421
|
|
422
422
|
def _create_source(source, root = None):
|
423
|
-
"""Create an extra meta data node holding information on the source of the data, optionally add to root.
|
423
|
+
"""Create an extra meta data node holding information on the source of the data, optionally add to root.
|
424
424
|
|
425
|
-
|
426
|
-
|
427
|
-
|
425
|
+
note:
|
426
|
+
if the root already contains a 'source' extra metadata item, its text field is updated and the
|
427
|
+
existing extra metadata xml node is returned
|
428
|
+
"""
|
428
429
|
|
429
|
-
|
430
|
-
|
431
|
-
|
430
|
+
emd_node = None
|
431
|
+
if root is not None:
|
432
|
+
emd_node = rqet.find_metadata_item_node_in_xml(root, 'source')
|
432
433
|
|
433
|
-
|
434
|
-
value_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string')
|
435
|
-
value_node.text = source
|
434
|
+
if emd_node is None:
|
436
435
|
|
437
|
-
|
438
|
-
|
436
|
+
emd_node = rqet.Element(ns['resqml2'] + 'ExtraMetadata')
|
437
|
+
emd_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'NameValuePair')
|
438
|
+
emd_node.text = rqet.null_xml_text
|
439
|
+
|
440
|
+
name_node = rqet.SubElement(emd_node, ns['resqml2'] + 'Name')
|
441
|
+
name_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string')
|
442
|
+
name_node.text = 'source'
|
443
|
+
|
444
|
+
value_node = rqet.SubElement(emd_node, ns['resqml2'] + 'Value')
|
445
|
+
value_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string')
|
446
|
+
value_node.text = str(source)
|
447
|
+
|
448
|
+
if root is not None:
|
449
|
+
root.append(emd_node)
|
450
|
+
|
451
|
+
else:
|
452
|
+
|
453
|
+
value_node = rqet.find_tag(emd_node, 'Value')
|
454
|
+
assert value_node is not None
|
455
|
+
value_node.text = str(source)
|
439
456
|
|
440
457
|
return emd_node
|
441
458
|
|
@@ -457,7 +474,9 @@ def _create_patch(model,
|
|
457
474
|
assert ext_uuid is not None
|
458
475
|
else:
|
459
476
|
assert const_count is not None and const_count > 0
|
460
|
-
if
|
477
|
+
if isinstance(const_value, bool):
|
478
|
+
hdf5_type = 'BooleanConstantArray' # not actually stored in hdf5
|
479
|
+
elif hdf5_type.endswith('Hdf5Array'):
|
461
480
|
hdf5_type = hdf5_type[:-9] + 'ConstantArray'
|
462
481
|
|
463
482
|
lxt = str(xsd_type).lower()
|
@@ -488,6 +507,7 @@ def _create_patch(model,
|
|
488
507
|
outer_values_node.text = rqet.null_xml_text
|
489
508
|
|
490
509
|
if discrete and const_value is None:
|
510
|
+
|
491
511
|
if null_value is None:
|
492
512
|
if str(xsd_type).startswith('u'):
|
493
513
|
null_value = 4294967295 # 2^32 - 1, used as default even for 64 bit data!
|
@@ -507,6 +527,11 @@ def _create_patch(model,
|
|
507
527
|
|
508
528
|
else:
|
509
529
|
|
530
|
+
# TODO: handle bool const_value as special case
|
531
|
+
if isinstance(const_value, bool):
|
532
|
+
const_value = str(const_value).lower()
|
533
|
+
xsd_type = 'boolean'
|
534
|
+
|
510
535
|
const_value_node = rqet.SubElement(outer_values_node, ns['resqml2'] + 'Value')
|
511
536
|
const_value_node.set(ns['xsi'] + 'type', ns['xsd'] + xsd_type)
|
512
537
|
const_value_node.text = str(const_value)
|