Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
    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)
Example #9
0
    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
Example #10
0
File: _mesh.py Project: bp/resqpy
    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)
Example #11
0
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)
Example #12
0
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())