Example #1
0
 def _load_from_xml(self):
     root_node = self.root
     assert root_node is not None
     flavour = rqet.node_type(root_node)
     assert flavour in ['obj_LocalDepth3dCrs', 'obj_LocalTime3dCrs'
                        ], f'bad crs node type: {flavour}'
     if flavour == 'obj_LocalTime3dCrs':
         self.time_units = rqet.find_tag_text(root_node, 'TimeUom')
         assert self.time_units
     else:
         self.time_units = None
     self.xy_units = rqet.find_tag_text(root_node, 'ProjectedUom')
     self.axis_order = rqet.find_tag_text(root_node, 'ProjectedAxisOrder')
     self.z_units = rqet.find_tag_text(root_node, 'VerticalUom')
     self.z_inc_down = rqet.find_tag_bool(root_node, 'ZIncreasingDownward')
     self.x_offset = rqet.find_tag_float(root_node, 'XOffset')
     self.y_offset = rqet.find_tag_float(root_node, 'YOffset')
     self.z_offset = rqet.find_tag_float(root_node, 'ZOffset')
     self.rotation = rqet.find_tag_float(root_node, 'ArealRotation')
     rotation_node = rqet.find_tag(root_node, 'ArealRotation')
     self.rotation_units = rotation_node.attrib.get('uom')
     parent_xy_crs = rqet.find_tag(root_node, 'ProjectedCrs')
     if parent_xy_crs is not None and rqet.node_type(
             parent_xy_crs) == 'ProjectedCrsEpsgCode':
         self.epsg_code = rqet.find_tag_text(
             parent_xy_crs, 'EpsgCode')  # should be an integer?
     else:
         self.epsg_code = None
Example #2
0
    def _load_from_xml(self, bci_node):
        """Populates this binary contact interpretation based on existing xml.

        arguments:
           bci_node (lxml.etree._Element): the root xml node for the binary contact interpretation sub-tree
        """

        assert bci_node is not None

        self.contact_relationship = rqet.find_tag_text(bci_node, 'ContactRelationship')
        assert self.contact_relationship in valid_contact_relationships,  \
           f'missing or invalid contact relationship {self.contact_relationship} in xml for binary contact interpretation'

        self.index = rqet.find_tag_int(bci_node, 'Index')
        assert self.index is not None, 'missing index in xml for binary contact interpretation'

        self.part_of_uuid = bu.uuid_from_string(rqet.find_nested_tags_text(bci_node, ['PartOf', 'UUID']))

        sr_node = rqet.find_tag(bci_node, 'Subject')
        assert sr_node is not None, 'missing subject in xml for binary contact interpretation'
        self.subject_uuid = bu.uuid_from_string(rqet.find_tag_text(sr_node, 'UUID'))
        assert self.subject_uuid is not None
        self.subject_contact_side = rqet.find_tag_text(sr_node, 'Qualifier')
        self.subject_contact_mode = rqet.find_tag_text(sr_node, 'SecondaryQualifier')

        dor_node = rqet.find_tag(bci_node, 'DirectObject')
        assert dor_node is not None, 'missing direct object in xml for binary contact interpretation'
        self.direct_object_uuid = bu.uuid_from_string(rqet.find_tag_text(dor_node, 'UUID'))
        assert self.direct_object_uuid is not None
        self.direct_object_contact_side = rqet.find_tag_text(dor_node, 'Qualifier')
        self.direct_object_contact_mode = rqet.find_tag_text(dor_node, 'SecondaryQualifier')

        self.verb = rqet.find_tag_text(bci_node, 'Verb')
        assert self.verb in valid_contact_verbs,  \
           f'missing or invalid contact verb {self.verb} in xml for binary contact interpretation'
Example #3
0
def _add_part_to_dict_get_property_kind(xml_node, citation_title):
    perm_synonyms = ['permeability rock', 'rock permeability']
    (p_kind_from_keyword, facet_type,
     facet) = property_kind_and_facet_from_keyword(citation_title)
    prop_kind_node = rqet.find_tag(xml_node, 'PropertyKind')
    assert (prop_kind_node is not None)
    kind_node = rqet.find_tag(prop_kind_node, 'Kind')
    property_kind_uuid = None  # only used for bespoke (local) property kinds
    if kind_node is not None:
        property_kind = kind_node.text  # could check for consistency with that derived from citation title
        lpk_node = None
    else:
        lpk_node = rqet.find_tag(prop_kind_node, 'LocalPropertyKind')
        if lpk_node is not None:
            property_kind = rqet.find_tag_text(lpk_node, 'Title')
            property_kind_uuid = rqet.find_tag_text(lpk_node, 'UUID')
    assert property_kind is not None and len(property_kind) > 0
    if (p_kind_from_keyword and p_kind_from_keyword != property_kind and
        (p_kind_from_keyword not in ['cell length', 'length', 'thickness']
         or property_kind not in ['cell length', 'length', 'thickness'])):
        if property_kind not in perm_synonyms or p_kind_from_keyword not in perm_synonyms:
            log.warning(
                f'property kind {property_kind} not the expected {p_kind_from_keyword} for keyword {citation_title}'
            )
    return property_kind, property_kind_uuid, lpk_node
Example #4
0
    def _load_from_xml(self):

        assert self.root is not None  # polyline xml node is specified
        poly_root = self.root

        self.title = rqet.citation_title_for_node(poly_root)

        self.extra_metadata = rqet.load_metadata_from_xml(self.root)

        self.isclosed = rqet.bool_from_text(
            rqet.node_text(rqet.find_tag(poly_root, 'IsClosed')))
        assert self.isclosed is not None  # Required field

        patch_node = rqet.find_tag(poly_root, 'NodePatch')
        assert patch_node is not None  # Required field

        geometry_node = rqet.find_tag(patch_node, 'Geometry')
        assert geometry_node is not None  # Required field

        self.crs_uuid = bu.uuid_from_string(
            rqet.find_nested_tags_text(geometry_node, ['LocalCrs', 'UUID']))
        assert self.crs_uuid is not None  # Required field

        points_node = rqet.find_tag(geometry_node, 'Points')
        assert points_node is not None  # Required field
        load_hdf5_array(self, points_node, 'coordinates', tag='Coordinates')

        self.nodepatch = (rqet.find_tag_int(patch_node, 'PatchIndex'),
                          rqet.find_tag_int(patch_node, 'Count'))
        assert not any(
            map(lambda x: x is None,
                self.nodepatch))  # Required fields - assert neither are None

        self.rep_int_root = self.model.referenced_node(
            rqet.find_tag(poly_root, 'RepresentedInterpretation'))
Example #5
0
File: schema.py Project: bp/resqpy
 def _process_complex_types(schema, complex_types):
     for completon in rqet.list_of_tag(schema, 'complexType'):
         name = completon.attrib['name']
         doc = rqet.find_nested_tags_text(completon,
                                          ['annotation', 'documentation'])
         content = rqet.find_tag(completon, 'complexContent')
         extension = rqet.find_tag(content, 'extension')
         if extension is None:
             e_base = None
         else:
             e_base = extension.attrib['base']
             content = extension
         if content is None:
             content = completon
         sequence = rqet.find_tag(content, 'sequence')
         if sequence is None:
             sequence = content
         element_list = []
         e_nodes = rqet.list_of_tag(sequence, 'element')
         if e_nodes is not None:
             for element in e_nodes:
                 e_name = element.attrib['name']
                 flavour = element.attrib[
                     'type']  # could strip prefix here?
                 min_occurs = element.get('minOccurs')
                 max_occurs = element.get('maxOccurs')
                 element_list.append(
                     (e_name, flavour, min_occurs, max_occurs))
         complex_types[name] = (e_base, element_list, doc)
Example #6
0
File: _xml.py Project: bp/resqpy
def _referenced_node(model, ref_node, consolidate=False):
    """For a given xml reference node, returns the node for the object referred to, if present."""

    # log.debug(f'ref node called for: {ref_node}')
    if ref_node is None:
        return None
    # content_type = rqet.find_tag_text(ref_node, 'ContentType')
    # log.debug(f'ref node title: {rqet.citation_title_for_node(rqet.find_tag(ref_node, "Title"))}')
    uuid = bu.uuid_from_string(rqet.find_tag_text(ref_node, 'UUID'))
    # log.debug(f'ref node uuid: {uuid}')
    if uuid is None:
        return None
    # return model.root_for_part(model.parts_list_of_type(type_of_interest = content_type, uuid = uuid))
    if consolidate and model.consolidation is not None and uuid in model.consolidation.map:
        resident_uuid = model.consolidation.map[uuid]
        if resident_uuid is None:
            return None
        node = model.root_for_part(model.part_for_uuid(resident_uuid))
        if node is not None:
            # patch resident uuid and title into ref node!
            uuid_node = rqet.find_tag(ref_node, 'UUID')
            uuid_node.text = str(resident_uuid)
            title_node = rqet.find_tag(ref_node, 'Title')
            if title_node is not None:
                title = rqet.citation_title_for_node(node)
                if title:
                    title_node.text = str(title)
    else:
        node = model.root_for_part(model.part_for_uuid(uuid))
    # log.debug(f'ref_node return node: {node}')
    return node
Example #7
0
def _title_for_root(model, root=None):
    """Returns the Title text from the Citation within the given root node."""

    title = rqet.find_tag(rqet.find_tag(root, 'Citation'), 'Title')
    if title is None:
        return None

    return title.text
Example #8
0
    def _load_from_xml(self):
        """Loads the trajectory object from an xml node (and associated hdf5 data)."""

        node = self.root
        assert node is not None
        self.start_md = float(
            rqet.node_text(rqet.find_tag(node, 'StartMd')).strip())
        self.finish_md = float(
            rqet.node_text(rqet.find_tag(node, 'FinishMd')).strip())
        self.md_uom = rqet.length_units_from_node(rqet.find_tag(node, 'MdUom'))
        self.md_domain = rqet.node_text(rqet.find_tag(node, 'MdDomain'))
        geometry_node = rqet.find_tag(node, 'Geometry')
        self.crs_uuid = bu.uuid_from_string(
            rqet.find_nested_tags_text(geometry_node, ['LocalCrs', 'UUID']))
        self.knot_count = int(
            rqet.node_text(rqet.find_tag(geometry_node, 'KnotCount')).strip())
        self.line_kind_index = int(
            rqet.node_text(rqet.find_tag(geometry_node,
                                         'LineKindIndex')).strip())
        mds_node = rqet.find_tag(geometry_node, 'ControlPointParameters')
        if mds_node is not None:  # not required for vertical or z linear cubic spline
            load_hdf5_array(self, mds_node, 'measured_depths')
        control_points_node = rqet.find_tag(geometry_node, 'ControlPoints')
        load_hdf5_array(self,
                        control_points_node,
                        'control_points',
                        tag='Coordinates')
        tangents_node = rqet.find_tag(geometry_node, 'TangentVectors')
        if tangents_node is not None:
            load_hdf5_array(self,
                            tangents_node,
                            'tangent_vectors',
                            tag='Coordinates')
        relatives_model = self.model  # if hdf5_source_model is None else hdf5_source_model
        # md_datum - separate part, referred to in this tree
        md_datum_uuid = bu.uuid_from_string(
            rqet.find_nested_tags_text(node, ['MdDatum', 'UUID']))
        assert md_datum_uuid is not None, 'failed to fetch uuid of md datum for trajectory'
        md_datum_part = relatives_model.part_for_uuid(md_datum_uuid)
        assert md_datum_part, 'md datum part not found in model'
        self.md_datum = MdDatum(
            self.model, uuid=relatives_model.uuid_for_part(md_datum_part))
        ds_uuid = bu.uuid_from_string(
            rqet.find_nested_tags_text(node, ['DeviationSurvey', 'UUID']))
        if ds_uuid is not None:  # this will probably not work when relatives model is different from self.model
            ds_uuid = self.model.uuid(obj_type='DeviationSurveyRepresentation',
                                      uuid=ds_uuid)  # check part is present
            if ds_uuid is not None:
                self.deviation_survey = DeviationSurvey(self.model,
                                                        uuid=ds_uuid)
        interp_uuid = rqet.find_nested_tags_text(
            node, ['RepresentedInterpretation', 'UUID'])
        if interp_uuid is None:
            self.wellbore_interpretation = None
        else:
            self.wellbore_interpretation = rqo.WellboreInterpretation(
                self.model, uuid=interp_uuid)
Example #9
0
def extract_grid_parent(grid):
    """Returns the uuid of the parent grid for the supplied grid"""
    if grid.extent_kji is None:
        grid.extract_extent_kji()
    if grid.parent_grid_uuid is not None:
        return grid.parent_grid_uuid
    grid.parent_window = None  # FineCoarse cell index mapping info with respect to parent
    grid.is_refinement = None
    pw_node = rqet.find_tag(grid.root, 'ParentWindow')
    if pw_node is None:
        return None
    # load a FineCoarse object as parent_window attribute and set parent_grid_uuid attribute
    grid.parent_grid_uuid = bu.uuid_from_string(rqet.find_nested_tags_text(pw_node, ['ParentGrid', 'UUID']))
    assert grid.parent_grid_uuid is not None
    parent_grid_root = grid.model.root(uuid = grid.parent_grid_uuid)
    if parent_grid_root is None:
        log.warning('parent grid not present in model, unable to treat as local grid')
        return None
    # etxract parent grid extent directly from xml to avoid risk of circular references
    parent_grid_extent_kji = np.array((rqet.find_tag_int(
        parent_grid_root, 'Nk'), rqet.find_tag_int(parent_grid_root, 'Nj'), rqet.find_tag_int(parent_grid_root, 'Ni')),
                                      dtype = int)
    parent_initials = []
    intervals_count_list = []
    parent_count_list_list = []
    child_count_list_list = []
    child_weight_list_list = []
    refining_flag = None  # gets set True if local grid is a refinement, False if a coarsening
    parent_box = np.zeros((2, 3), dtype = int)
    for axis in range(3):
        refining_flag = __process_axis(axis, child_count_list_list, child_weight_list_list, grid, intervals_count_list,
                                       parent_box, parent_count_list_list, parent_grid_extent_kji, parent_initials,
                                       pw_node, refining_flag)
    cell_overlap_node = rqet.find_tag(pw_node, 'CellOverlap')
    if cell_overlap_node is not None:
        log.warning('ignoring cell overlap information in grid relationship')
    omit_node = rqet.find_tag(pw_node, 'OmitParentCells')
    if omit_node is not None:
        log.warning('unable to handle parent cell omissions in local grid definition – ignoring')
    # todo: handle omissions

    if refining_flag is None:
        log.warning('local grid has no refinement nor coarsening – treating as a refined grid')
        refining_flag = True
    grid.is_refinement = refining_flag

    if refining_flag:  # local grid is a refinement
        __extract_refined_parent(child_count_list_list, child_weight_list_list, grid, intervals_count_list, parent_box,
                                 parent_count_list_list)

    else:  # local grid is a coarsening
        __extract_coarsening_parent(child_count_list_list, child_weight_list_list, grid, intervals_count_list,
                                    parent_box, parent_count_list_list)

    grid.parent_window.assert_valid()

    return grid.parent_grid_uuid
Example #10
0
    def extract_crs_uuid(self):
        """Returns uuid for coordinate reference system, as stored in reference node of this md datum's xml tree."""

        if self.crs_uuid is not None:
            return self.crs_uuid
        crs_root = rqet.find_tag(self.root, 'LocalCrs')
        uuid_str = rqet.find_tag(crs_root, 'UUID').text
        self.crs_uuid = bu.uuid_from_string(uuid_str)
        return self.crs_uuid
Example #11
0
    def create_xml(self, parent_node, title='wellbore marker'):
        """Creates the xml tree for this wellbore marker.

        arguments:
           parent_node (xml node): the root node of the WellboreMarkerFrame object to which the newly created node will be appended
           title (string, optional): the citation title of the newly created node
             note: if not None, self.title will be used instead of "wellbore marker"

        returns:
           the newly created xml node
        """

        assert self.uuid is not None
        wbm_node = self.model.new_obj_node('WellboreMarker',
                                           is_top_lvl_obj=False)
        wbm_node.set('uuid', str(self.uuid))

        # Citation block
        if self.title is not None:
            title = self.title
        citation = self.model.create_citation(root=wbm_node,
                                              title=title,
                                              originator=self.originator)

        # Add sub-elements to root node
        for k, v in WellboreMarker.boundary_feature_dict.items():
            if self.marker_type in v:
                boundary_kind = k
                break

        wbm_gb_node = rqet.SubElement(wbm_node, ns['resqml2'] + boundary_kind)
        # wbm_gb_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string')
        wbm_gb_node.set(ns['xsi'] + 'type',
                        ns['resqml2'] + 'GeologicBoundaryKind')
        wbm_gb_node.text = str(self.marker_type)

        if self.interpretation_uuid is not None:
            interp_content_type = 'obj_' + self.marker_type.capitalize(
            ) + 'Interpretation'
            interp_root = self.model.root_for_uuid(
                uuid=self.interpretation_uuid)
            self.model.create_ref_node(
                flavour='Interpretation',
                title=rqet.find_tag(rqet.find_tag(interp_root, 'Citation'),
                                    'Title').text,
                uuid=self.interpretation_uuid,
                content_type=interp_content_type,
                root=wbm_node)
        # Extra metadata
        if hasattr(self, 'extra_metadata') and self.extra_metadata:
            rqet.create_metadata_xml(node=wbm_node,
                                     extra_metadata=self.extra_metadata)

        if parent_node is not None:
            parent_node.append(wbm_node)

        return wbm_node
Example #12
0
 def _load_from_xml(self):
     root_node = self.root
     self.is_abstract = rqet.find_tag_bool(root_node, 'IsAbstract')
     self.naming_system = rqet.find_tag_text(root_node, 'NamingSystem')
     self.example_uom = rqet.find_tag_text(root_node, 'RepresentativeUom')
     ppk_node = rqet.find_tag(root_node, 'ParentPropertyKind')
     assert ppk_node is not None
     ppk_kind_node = rqet.find_tag(ppk_node, 'Kind')
     assert ppk_kind_node is not None, 'only standard property kinds supported as parent kind'
     self.parent_kind = ppk_kind_node.text
Example #13
0
def _add_part_to_dict_get_count_and_indexable(xml_node):
    count_node = rqet.find_tag(xml_node, 'Count')
    assert count_node is not None
    count = int(count_node.text)

    indexable_node = rqet.find_tag(xml_node, 'IndexableElement')
    assert indexable_node is not None
    indexable = indexable_node.text

    return count, indexable
Example #14
0
def _add_part_to_dict_get_timeseries(xml_node):
    time_series_uuid = None
    time_index = None
    time_node = rqet.find_tag(xml_node, 'TimeIndex')
    if time_node is not None:
        time_index = int(rqet.find_tag(time_node, 'Index').text)
        time_series_uuid = bu.uuid_from_string(
            rqet.find_tag(rqet.find_tag(time_node, 'TimeSeries'), 'UUID').text)

    return time_series_uuid, time_index
Example #15
0
    def _load_related_datum(self):
        """Return related MdDatum object from XML if present."""

        md_datum_uuid = bu.uuid_from_string(rqet.find_tag(rqet.find_tag(self.root, 'MdDatum'), 'UUID'))
        if md_datum_uuid is not None:
            md_datum_part = 'obj_MdDatum_' + str(md_datum_uuid) + '.xml'
            md_datum = MdDatum(self.model, md_datum_root = self.model.root_for_part(md_datum_part, is_rels = False))
        else:
            md_datum = None
        return md_datum
Example #16
0
 def _load_from_xml(self):
     md_datum_root = self.root
     assert md_datum_root is not None
     location_node = rqet.find_tag(md_datum_root, 'Location')
     self.location = (rqet.find_tag_float(location_node, 'Coordinate1'),
                      rqet.find_tag_float(location_node, 'Coordinate2'),
                      rqet.find_tag_float(location_node, 'Coordinate3'))
     self.md_reference = rqet.node_text(
         rqet.find_tag(md_datum_root, 'MdReference')).strip().lower()
     assert self.md_reference in valid_md_reference_list
     self.crs_uuid = self.extract_crs_uuid()
Example #17
0
File: _hdf5.py Project: bp/resqpy
def _h5_uuid_and_path_for_node(model, node, tag='Values'):
    """Returns a (hdf5_uuid, hdf5_internal_path) pair for an xml array node."""

    child = rqet.find_tag(node, tag)
    if child is None:
        return None
    assert rqet.node_type(child) == 'Hdf5Dataset'
    h5_path = rqet.find_tag(child, 'PathInHdfFile').text
    h5_uuid = bu.uuid_from_string(
        rqet.find_nested_tags_text(child, ['HdfProxy', 'UUID']))
    return (h5_uuid, h5_path)
Example #18
0
def _crs_m_or_ft(
        crs_node):  # NB. models not-so-rarely use metres for xy and feet for z
    if crs_node is None:
        return None
    xy_units = rqet.find_tag(crs_node, 'ProjectedUom').text.lower()
    z_units = rqet.find_tag(crs_node, 'VerticalUom').text.lower()
    if xy_units == 'm' and z_units == 'm':
        return 'm'
    if xy_units == 'ft' and z_units == 'ft':
        return 'ft'
    return None
Example #19
0
def _add_part_to_dict_get_minmax(xml_node):
    minimum = None
    min_node = rqet.find_tag(xml_node, 'MinimumValue')
    if min_node is not None:
        minimum = min_node.text  # NB: left as text
    maximum = None
    max_node = rqet.find_tag(xml_node, 'MaximumValue')
    if max_node is not None:
        maximum = max_node.text  # NB: left as text

    return minimum, maximum
Example #20
0
    def create_xml(self,
                   ext_uuid=None,
                   add_as_part=True,
                   add_relationships=True,
                   title='wellbore marker framework',
                   originator=None):
        """Creates the xml tree for this wellbore marker frame and optionally adds as a part to the model."""

        assert type(add_as_part) is bool

        if not self.title:
            self.title = title

        if ext_uuid is None:
            ext_uuid = self.model.h5_uuid()

        wbm_node = super().create_xml(originator=originator, add_as_part=False)
        node_count, nodeMd, md_values_node = self.__add_sub_elements_to_root_node(
            wbm_node=wbm_node)
        self.model.create_hdf5_dataset_ref(ext_uuid,
                                           self.uuid,
                                           'Mds',
                                           root=md_values_node)

        if self.trajectory is not None:
            traj_root = self.trajectory.root
            self.model.create_ref_node(
                'Trajectory',
                rqet.find_tag(rqet.find_tag(traj_root, 'Citation'),
                              'Title').text,
                bu.uuid_from_string(traj_root.attrib['uuid']),
                content_type='obj_WellboreTrajectoryRepresentation',
                root=wbm_node)
        else:
            log.error('trajectory object is missing and must be included')

        # fill wellbore marker
        if self.marker_list is not None:
            for marker in self.marker_list:
                title = self.__get_wbm_node_title(marker)
                wbm_node_obj = marker.create_xml(parent_node=wbm_node,
                                                 title=title)
                assert wbm_node_obj is not None

        # add as part
        self.__add_as_part_and_add_relationships(
            wbm_node=wbm_node,
            ext_uuid=ext_uuid,
            add_as_part=add_as_part,
            add_relationships=add_relationships)

        return wbm_node
Example #21
0
def _add_part_to_dict_get_facet(xml_node):
    facet_type = None
    facet = None
    facet_node = rqet.find_tag(
        xml_node, 'Facet')  # todo: handle more than one facet for a property
    if facet_node is not None:
        facet_type = rqet.find_tag(facet_node, 'Facet').text
        facet = rqet.find_tag(facet_node, 'Value').text
        if facet_type is not None and facet_type == '':
            facet_type = None
        if facet is not None and facet == '':
            facet = None
    return facet_type, facet
Example #22
0
    def triangles_and_points(self):
        """Returns arrays representing the patch.

        Returns:
           Tuple (triangles, points):

           * triangles (int array of shape[:, 3]): integer indices into points array,
             being the nodes of the corners of the triangles
           * points (float array of shape[:, 3]): flat array of xyz points, indexed by triangles
        """
        if self.triangles is not None:
            return (self.triangles, self.points)
        assert self.triangle_count is not None and self.node_count is not None

        geometry_node = rqet.find_tag(self.node, 'Geometry')
        assert geometry_node is not None
        p_root = rqet.find_tag(geometry_node, 'Points')
        assert p_root is not None, 'Points xml node not found for triangle patch'
        assert rqet.node_type(p_root) == 'Point3dHdf5Array'
        h5_key_pair = self.model.h5_uuid_and_path_for_node(p_root,
                                                           tag='Coordinates')
        if h5_key_pair is None:
            return (None, None)
        try:
            self.model.h5_array_element(h5_key_pair,
                                        cache_array=True,
                                        object=self,
                                        array_attribute='points',
                                        dtype='float')
        except Exception:
            log.error('hdf5 points failure for triangle patch ' +
                      str(self.patch_index))
            raise
        triangles_node = rqet.find_tag(self.node, 'Triangles')
        h5_key_pair = self.model.h5_uuid_and_path_for_node(triangles_node)
        if h5_key_pair is None:
            log.warning('No Triangles found in xml for patch index: ' +
                        str(self.patch_index))
            return (None, None)
        try:
            self.model.h5_array_element(h5_key_pair,
                                        cache_array=True,
                                        object=self,
                                        array_attribute='triangles',
                                        dtype='int')
        except Exception:
            log.error('hdf5 triangles failure for triangle patch ' +
                      str(self.patch_index))
            raise
        return (self.triangles, self.points)
Example #23
0
    def __create_deviation_survey_reference_node(self, wbt_node):
        """ Create a reference node to a DeviationSurvey object and append it to the WellboreTrajectory

        object's root node.
        """

        if self.deviation_survey is not None:
            ds_root = self.deviation_survey.root_node
            self.model.create_ref_node(
                'DeviationSurvey',
                rqet.find_tag(rqet.find_tag(ds_root, 'Citation'),
                              'Title').text,
                bu.uuid_from_string(ds_root.attrib['uuid']),
                content_type='obj_DeviationSurveyRepresentation',
                root=wbt_node)
Example #24
0
def extract_extent_kji(grid):
    """Returns the grid extent; for IJK grids this is a 3 integer numpy array, order is Nk, Nj, Ni.

    returns:
       numpy int array of shape (3,) being number of cells in k, j & i axes respectively;
       the return value is cached in attribute extent_kji, which can alternatively be referenced
       directly by calling code as the value is set from xml on initialisation
    """

    if grid.extent_kji is not None:
        return grid.extent_kji
    grid.extent_kji = np.ones(3, dtype = 'int')  # todo: handle other varieties of grid
    grid.extent_kji[0] = int(rqet.find_tag(grid.root, 'Nk').text)
    grid.extent_kji[1] = int(rqet.find_tag(grid.root, 'Nj').text)
    grid.extent_kji[2] = int(rqet.find_tag(grid.root, 'Ni').text)
    return grid.extent_kji
Example #25
0
    def cases(self):
        """Returns a list of simulation case strings as found in the main xml file."""

        if self.case_list is not None:
            return self.case_list
        try:
            xml_file = os.path.join(self.path, 'main.xml')
            if self.zipped:
                with zf.ZipFile(self.zip_file) as zfp:
                    with zfp.open(xml_file) as fp:
                        tree = rqet.parse(fp)
                        root = tree.getroot()
            else:
                assert os.path.exists(
                    xml_file), 'could not find vdb main xml file: ' + xml_file
                with open(xml_file, 'r') as fp:
                    tree = rqet.parse(fp)
                    root = tree.getroot()
            caselist = rqet.list_of_tag(rqet.find_tag(root, 'CASELIST'),
                                        'CASE')
            self.case_list = []
            for case in caselist:
                self.case_list.append(str(case.attrib['Name']).strip())
            if self.use_case is None and len(self.case_list):
                self.use_case = self.case_list[0]
        except Exception:
            log.exception('failed to extract case list')
        return self.case_list
Example #26
0
    def __init__(self,
                 model,
                 uuid=None,
                 title=None,
                 originator=None,
                 extra_metadata=None):
        """Load an existing resqml object, or create new.

        Args:
            model (resqpy.model.Model): Parent model
            uuid (str, optional): Load from existing uuid (if given), else create new.
            title (str, optional): Citation title
            originator (str, optional): Creator of object. By default, uses user id.
        """
        self.model = model
        self.title = title  #: Citation title
        self.originator = originator  #: Creator of object. By default, user id.
        self.extra_metadata = {}
        if extra_metadata:
            self.extra_metadata = extra_metadata
            self._standardise_extra_metadata(
            )  # has side effect of making a copy

        if uuid is None:
            self.uuid = bu.new_uuid()  #: Unique identifier
        else:
            self.uuid = uuid
            root_node = self.root
            citation_node = rqet.find_tag(root_node, 'Citation')
            if citation_node is not None:
                self.title = rqet.find_tag_text(citation_node, 'Title')
                self.originator = rqet.find_tag_text(citation_node,
                                                     'Originator')
            self.extra_metadata = rqet.load_metadata_from_xml(root_node)
            self._load_from_xml()
 def _load_from_xml(self):
     """Loads class specific attributes from xml for an existing RESQML object; called from BaseResqpy."""
     super()._load_from_xml()
     root_node = self.root
     assert root_node is not None
     feature_uuid = bu.uuid_from_string(
         rqet.find_nested_tags_text(root_node,
                                    ['InterpretedFeature', 'UUID']))
     if feature_uuid is not None:
         self.geologic_unit_feature = StratigraphicUnitFeature(
             self.model,
             uuid=feature_uuid,
             title=self.model.title(uuid=feature_uuid))
     # load deposition mode and min & max thicknesses (& uom), if present
     self.deposition_mode = rqet.find_tag_text(root_node, 'DepositionMode')
     for min_max in ['Min', 'Max']:
         thick_node = rqet.find_tag(root_node, min_max + 'Thickness')
         if thick_node is not None:
             thick = float(thick_node.text)
             if min_max == 'Min':
                 self.min_thickness = thick
             else:
                 self.max_thickness = thick
             thick_uom = thick_node.attrib[
                 'uom']  # todo: check this is correct uom representation
             if self.thickness_uom is None:
                 self.thickness_uom = thick_uom
             else:
                 assert thick_uom == self.thickness_uom, 'inconsistent length units of measure for stratigraphic thicknesses'
Example #28
0
def grid_flavour(grid_root):
    """Returns a string indicating type of grid geometry, currently 'IjkGrid' or 'IjkBlockGrid'."""

    if grid_root is None:
        return None
    em = rqet.load_metadata_from_xml(grid_root)
    flavour = em.get('grid_flavour')
    if flavour is None:
        node_type = rqet.node_type(grid_root, strip_obj = True)
        if node_type == 'IjkGridRepresentation':
            if rqet.find_tag(grid_root, 'Geometry') is not None:
                flavour = 'IjkGrid'
            else:
                flavour = 'IjkBlockGrid'  # this might cause issues
        elif node_type == 'UnstructuredGridRepresentation':
            cell_shape = rqet.find_nested_tags_text(grid_root, ['Geometry', 'CellShape'])
            if cell_shape is None or cell_shape == 'polyhedral':
                flavour = 'UnstructuredGrid'
            elif cell_shape == 'tetrahedral':
                flavour = 'TetraGrid'
            elif cell_shape == 'hexahedral':
                flavour = 'HexaGrid'
            elif cell_shape == 'pyramidal':
                flavour = 'PyramidGrid'
            elif cell_shape == 'prism':
                flavour = 'PrismGrid'
    return flavour
Example #29
0
 def _load_from_xml(self):
     root_node = self.root
     self.domain = rqet.find_tag_text(root_node, 'Domain')
     interp_feature_ref_node = rqet.find_tag(root_node, 'InterpretedFeature')
     assert interp_feature_ref_node is not None
     self.feature_root = self.model.referenced_node(interp_feature_ref_node)
     if self.feature_root is not None:
         self.tectonic_boundary_feature = TectonicBoundaryFeature(self.model,
                                                                  uuid = self.feature_root.attrib['uuid'],
                                                                  feature_name = self.model.title_for_root(
                                                                      self.feature_root))
         self.main_has_occurred_during = extract_has_occurred_during(root_node)
         self.is_listric = rqet.find_tag_bool(root_node, 'IsListric')
         self.is_normal = (self.is_listric is None)
         self.maximum_throw = rqet.find_tag_float(root_node, 'MaximumThrow')
         # todo: check that type="eml:LengthMeasure" is simple float
         self.mean_azimuth = rqet.find_tag_float(root_node, 'MeanAzimuth')
         self.mean_dip = rqet.find_tag_float(root_node, 'MeanDip')
         throw_interpretation_nodes = rqet.list_of_tag(root_node, 'ThrowInterpretation')
         if throw_interpretation_nodes is not None and len(throw_interpretation_nodes):
             self.throw_interpretation_list = []
             for ti_node in throw_interpretation_nodes:
                 hod_pair = extract_has_occurred_during(ti_node)
                 throw_kind_list = rqet.list_of_tag(ti_node, 'Throw')
                 for tk_node in throw_kind_list:
                     self.throw_interpretation_list.append((tk_node.text, hod_pair))
Example #30
0
File: _mesh.py Project: bp/resqpy
 def __load_from_xml_refz(self, support_geom_node):
     self.flavour = 'ref&z'
     # assert rqet.node_type(support_geom_node) == 'Point3dFromRepresentationLatticeArray'  # only this supported for now
     self.ref_uuid = rqet.find_nested_tags_text(
         support_geom_node, ['SupportingRepresentation', 'UUID'])
     assert self.ref_uuid, 'missing supporting representation info in xml for z-value mesh'
     self.ref_mesh = Mesh(self.model, uuid=self.ref_uuid)
     assert self.nj == self.ref_mesh.nj and self.ni == self.ref_mesh.ni  # only this supported for now
     niosr_node = rqet.find_tag(support_geom_node,
                                'NodeIndicesOnSupportingRepresentation')
     start_value = rqet.find_tag_int(niosr_node, 'StartValue')
     assert start_value == 0, 'only full use of supporting mesh catered for at present'
     offset_nodes = rqet.list_of_tag(
         niosr_node,
         'Offset')  # first occurrence for FastestAxis, ie. I; 2nd for J
     assert len(
         offset_nodes
     ) == 2, 'missing (or too many) offset nodes in xml for regular mesh (lattice)'
     for j_or_i in range(2):  # 0 = J, 1 = I
         assert rqet.node_type(
             offset_nodes[j_or_i]
         ) == 'IntegerConstantArray', 'variable step not catered for'
         assert rqet.find_tag_int(
             offset_nodes[j_or_i],
             'Value') == 1, 'step other than 1 not catered for'
         count = rqet.find_tag_int(offset_nodes[j_or_i], 'Count')
         assert count == (self.nj, self.ni)[j_or_i] - 1, \
             'unexpected value for count in xml spacing info for regular mesh (lattice)'