def write_hdf5(self, file_name = None, mode = 'a'): """Create or append to an hdf5 file, writing datasets for the measured depths, azimuths, and inclinations.""" # NB: array data must all have been set up prior to calling this function h5_reg = rwh5.H5Register(self.model) h5_reg.register_dataset(self.uuid, 'Mds', self.measured_depths, dtype = float) h5_reg.register_dataset(self.uuid, 'Azimuths', self.azimuths, dtype = float) h5_reg.register_dataset(self.uuid, 'Inclinations', self.inclinations, dtype = float) h5_reg.write(file = file_name, mode = mode)
def write_hdf5(self, file_name=None, mode='a'): """Writes the hdf5 array associated with this object (the measured depth data). arguments: file_name (string): the name of the hdf5 file, or None, in which case the model's default will be used mode (string, default 'a'): the write mode for the hdf5, either 'w' or 'a' """ h5_reg = rwh5.H5Register(self.model) h5_reg.register_dataset(self.uuid, 'Mds', self.node_mds) h5_reg.write(file=file_name, mode=mode)
def write_hdf5(self, file_name=None, mode='a'): """Create or append to an hdf5 file, writing datasets for the measured depths.""" # NB: array data must have been set up prior to calling this function if self.uuid is None: self.uuid = bu.new_uuid() h5_reg = rwh5.H5Register(self.model) h5_reg.register_dataset(self.uuid, 'NodeMd', self.node_mds) h5_reg.write(file=file_name, mode=mode)
def write_hdf5(self, file_name=None, mode='a'): """Create or append the coordinates hdf5 array to hdf5 file. :meta common: """ if self.uuid is None: self.uuid = bu.new_uuid() h5_reg = rwh5.H5Register(self.model) h5_reg.register_dataset(self.uuid, 'points_patch0', self.coordinates) h5_reg.write(file_name, mode=mode)
def write_hdf5(self, file_name = None, mode = 'a'): """Create or append to an hdf5 file, writing datasets for the point set patches after caching arrays. :meta common: """ if not file_name: file_name = self.model.h5_file_name() if self.uuid is None: self.uuid = bu.new_uuid() # NB: patch arrays must all have been set up prior to calling this function h5_reg = rwh5.H5Register(self.model) for patch_index in range(self.patch_count): h5_reg.register_dataset(self.uuid, 'points_{}'.format(patch_index), self.patch_array_list[patch_index]) h5_reg.write(file_name, mode = mode)
def write_hdf5(self, file_name=None, mode='a'): """Create or append to an hdf5 file, writing datasets for the triangulated patches after caching arrays. :meta common: """ if self.uuid is None: self.uuid = bu.new_uuid() # NB: patch arrays must all have been set up prior to calling this function h5_reg = rwh5.H5Register(self.model) # todo: sort patches by patch index and check sequence for triangulated_patch in self.patch_list: (t, p) = triangulated_patch.triangles_and_points() h5_reg.register_dataset( self.uuid, 'points_patch{}'.format(triangulated_patch.patch_index), p) h5_reg.register_dataset( self.uuid, 'triangles_patch{}'.format(triangulated_patch.patch_index), t) h5_reg.write(file_name, mode=mode)
def write_hdf5(self, file_name=None, mode='a'): """Create or append to an hdf5 file, writing datasets for the measured depths, control points and tangent vectors. :meta common: """ # NB: array data must all have been set up prior to calling this function if self.uuid is None: self.uuid = bu.new_uuid() h5_reg = rwh5.H5Register(self.model) h5_reg.register_dataset(self.uuid, 'controlPointParameters', self.measured_depths) h5_reg.register_dataset(self.uuid, 'controlPoints', self.control_points) if self.tangent_vectors is not None: h5_reg.register_dataset(self.uuid, 'tangentVectors', self.tangent_vectors) h5_reg.write(file=file_name, mode=mode)
def write_hdf5(self, file_name = None, mode = 'a', save_polylines = False): """Create or append the coordinates, counts and indices hdf5 arrays to hdf5 file. :meta common: """ if self.uuid is None: self.uuid = bu.new_uuid() self.combine_polylines(self.polys) self.bool_array_format(self.closed_array) self.save_polys = save_polylines if self.save_polys: for poly in self.polys: poly.write_hdf5(file_name) h5_reg = rwh5.H5Register(self.model) h5_reg.register_dataset(self.uuid, 'points_patch0', self.coordinates) h5_reg.register_dataset(self.uuid, 'NodeCountPerPolyline_patch0', self.count_perpol.astype(np.int32)) if self.boolnotconstant: h5_reg.register_dataset(self.uuid, 'indices_patch0', self.indices) h5_reg.write(file_name, mode = mode)
def set_tangents(self, force=False, write_hdf5=False, weight='cube'): """Calculates tangent vectors based on control points. arguments: force (boolean, default False): if False and tangent vectors already exist then the existing ones are used; if True or no tangents vectors exist then they are computed write_hdf5 (boolean, default False): if True and new tangent vectors are computed then the array is also written directly to the hdf5 file weight (string, default 'linear'): one of 'linear', 'square', 'cube'; if linear, each tangent is the mean of the direction vectors of the two trjectory segments which meet at the knot; the square and cube options give increased weight to the direction vector of shorter segments (usually better) returns: numpy float array of shape (knot_count, 3) being the tangents in xyz, 'pointing' in the direction of increased knot index; the tangents are also stored as an attribute of the object note: the write_hdf5() method writes all the array data for the trajectory, including the tangent vectors; only set the write_hdf5 argument to this method to True if the other arrays for the trajectory already exist in the hdf5 file """ if self.tangent_vectors is not None and not force: return self.tangent_vectors assert self.knot_count is not None and self.knot_count >= 2 assert self.control_points is not None and len( self.control_points) == self.knot_count self.tangent_vectors = rql.tangents(self.control_points, weight=weight) if write_hdf5: h5_reg = rwh5.H5Register(self.model) h5_reg.register_dataset(self.uuid, 'tangentVectors', self.tangent_vectors) h5_reg.write(file=self.model.h5_filename(), mode='a') return self.tangent_vectors
def write_hdf5(self, file_name=None, mode='a', use_xy_only=False): """Create or append to an hdf5 file, writing datasets for the mesh depending on flavour.""" if not file_name: file_name = self.model.h5_file_name() if self.uuid is None: self.uuid = bu.new_uuid() if self.flavour == 'regular': return # NB: arrays must have been set up prior to calling this function h5_reg = rwh5.H5Register(self.model) a = self.full_array_ref() if self.flavour == 'explicit': if use_xy_only: h5_reg.register_dataset( self.uuid, 'points', a[..., :2]) # todo: check what others use here else: h5_reg.register_dataset(self.uuid, 'points', a) elif self.flavour == 'ref&z' or self.flavour == 'reg&z': h5_reg.register_dataset(self.uuid, 'zvalues', a[..., 2]) else: log.error('bad mesh flavour when writing hdf5 array') h5_reg.write(file_name, mode=mode)
def _write_hdf5_from_caches(grid, file = None, mode = 'a', geometry = True, imported_properties = None, write_active = None, stratigraphy = True, expand_const_arrays = False): """Create or append to an hdf5 file. Writes datasets for the grid geometry (and parent grid mapping) and properties from cached arrays. """ # NB: when writing a new geometry, all arrays must be set up and exist as the appropriate attributes prior to calling this function # if saving properties, active cell array should be added to imported_properties based on logical negation of inactive attribute # xml is not created here for property objects if write_active is None: write_active = geometry if geometry: grid.cache_all_geometry_arrays() if not file: file = grid.model.h5_file_name() h5_reg = rwh5.H5Register(grid.model) if stratigraphy and grid.stratigraphic_units is not None: h5_reg.register_dataset(grid.uuid, 'unitIndices', grid.stratigraphic_units, dtype = 'uint32') if geometry: __write_geometry(grid, h5_reg) if write_active and grid.inactive is not None: if imported_properties is None: imported_properties = rprop.PropertyCollection() imported_properties.set_support(support = grid) else: filtered_list = [] for entry in imported_properties.imported_list: if (entry[2].upper() == 'ACTIVE' or entry[10] == 'active') and entry[14] == 'cells': continue # keyword or property kind filtered_list.append(entry) imported_properties.imported_list = filtered_list # might have unintended side effects elsewhere active_mask = np.logical_not(grid.inactive) imported_properties.add_cached_array_to_imported_list(active_mask, 'active cell mask', 'ACTIVE', discrete = True, property_kind = 'active') if imported_properties is not None and imported_properties.imported_list is not None: for entry in imported_properties.imported_list: tail = 'points_patch0' if entry[18] else 'values_patch0' # expand constant arrays if required if not hasattr(imported_properties, entry[3]) and expand_const_arrays and entry[17] is not None: value = float(entry[17]) if isinstance(entry[17], str) else entry[17] assert entry[14] == 'cells' and entry[15] == 1 imported_properties.__dict__[entry[3]] = np.full(grid.extent_kji, value) if hasattr(imported_properties, entry[3]): # otherwise constant array not being expanded h5_reg.register_dataset(entry[0], tail, imported_properties.__dict__[entry[3]]) if entry[10] == 'active': grid.active_property_uuid = entry[0] h5_reg.write(file, mode = mode)
def test_model_copy_all_parts_non_resqpy_hdf5_paths( example_model_with_properties): # this test uses low level methods to override the hdf5 internal paths for some new objects epc = example_model_with_properties.epc_file dir = example_model_with_properties.epc_directory copied_epc = os.path.join(dir, 'copied.epc') extent_kji = (3, 5, 5) # needs to match extent of grid in example model # add some properties with bespoke internal hdf5 paths original = rq.Model(epc) assert original is not None grid_uuid = original.uuid(obj_type='IjkGridRepresentation') assert grid_uuid is not None data = np.linspace(0.0, 1000.0, num=75).reshape(extent_kji) hdf5_paths = [ '/RESQML/uuid_waffle/values', '/RESQML/waffle_uuid/unusual_name', 'RESQML/class_uuid_waffle/values0', 'RESQML/something_interesting/array', '/RESQML/abrupt', 'no_resqml/uuid/values' ] prop_list = [] path_list = [] # elements will have 'uuid' replaced with uuid string h5_reg = rwh5.H5Register(original) for i, hdf5_path in enumerate(hdf5_paths): prop = rqp.Property(original, support_uuid=grid_uuid) if 'uuid' in hdf5_path: path = hdf5_path.replace('uuid', str(prop.uuid)) else: path = hdf5_path prop.prepare_import(cached_array=data, source_info='test data', keyword=f'TEST{i}', property_kind='continuous', uom='m') for entry in prop.collection.imported_list: # only one entry # override internal hdf5 path h5_reg.register_dataset(entry[0], 'values_patch0', prop.collection.__dict__[entry[3]], hdf5_path=path) prop_list.append(prop) path_list.append(path) h5_reg.write(mode='a') for prop, hdf5_path in zip(prop_list, path_list): root_node = prop.create_xml(find_local_property_kind=False) assert root_node is not None # override the hdf5 internal path in the xml tree path_node = rqet.find_nested_tags( root_node, ['PatchOfValues', 'Values', 'Values', 'PathInHdfFile']) assert path_node is not None path_node.text = hdf5_path # rewrite model original.store_epc() # re-open model and test copying original = rq.Model(epc) assert original is not None copied = rq.new_model(copied_epc) copied.copy_all_parts_from_other_model(original, consolidate=False) assert set(original.uuids()) == set(copied.uuids()) assert set(original.parts()) == set(copied.parts())