def _load_from_xml(self):
     """Loads class specific attributes from xml for an existing RESQML object; called from BaseResqpy."""
     root_node = self.root
     assert root_node is not None
     assert rqet.find_tag_text(root_node, 'OrderingCriteria') == 'age',  \
        'stratigraphic column rank interpretation ordering criterion must be age'
     self.domain = rqet.find_tag_text(root_node, 'Domain')
     self.feature_uuid = bu.uuid_from_string(
         rqet.find_nested_tags_text(root_node,
                                    ['InterpretedFeature', 'UUID']))
     self.has_occurred_during = rqo.extract_has_occurred_during(root_node)
     self.index = rqet.find_tag_int(root_node, 'Index')
     self.units = []
     for su_node in rqet.list_of_tag(root_node, 'StratigraphicUnits'):
         index = rqet.find_tag_int(su_node, 'Index')
         unit_uuid = bu.uuid_from_string(
             rqet.find_nested_tags_text(su_node, ['Unit', 'UUID']))
         assert index is not None and unit_uuid is not None
         assert self.model.type_of_uuid(
             unit_uuid, strip_obj=True) == 'StratigraphicUnitInterpretation'
         self.units.append(
             (index,
              StratigraphicUnitInterpretation(self.model, uuid=unit_uuid)))
     self._sort_units()
     self.contacts = []
     for contact_node in rqet.list_of_tag(root_node,
                                          'ContactInterpretation'):
         self.contacts.append(
             BinaryContactInterpretation(self.model,
                                         existing_xml_node=contact_node))
     self._sort_contacts()
Exemple #2
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))
Exemple #3
0
 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)
Exemple #4
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
Exemple #5
0
 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)'
Exemple #6
0
 def _load_from_xml(self):
     """Loads class specific attributes from xml for an existing RESQML object; called from BaseResqpy."""
     rank_node_list = rqet.list_of_tag(self.root, 'Ranks')
     assert rank_node_list is not None, 'no stratigraphic column ranks in xml for stratigraphic column'
     for rank_node in rank_node_list:
         rank = StratigraphicColumnRank(self.model,
                                        uuid=rqet.find_tag_text(
                                            rank_node, 'UUID'))
         self.add_rank(rank)
Exemple #7
0
 def _process_simple_types(schema, simple_types):
     for simpleton in rqet.list_of_tag(schema, 'simpleType'):
         name = simpleton.attrib['name']
         doc = rqet.find_nested_tags_text(simpleton,
                                          ['annotation', 'documentation'])
         restriction = rqet.find_tag(simpleton, 'restriction')
         restrict = None if restriction is None else rqet.stripped_of_prefix(
             restriction.attrib['base'])
         value_list = []
         enum_list = rqet.list_of_tag(restriction, 'enumeration')
         if enum_list is not None:
             for enumeration in enum_list:
                 value = enumeration.attrib['value']
                 v_doc = rqet.find_nested_tags_text(
                     enumeration, ['annotation', 'documentation'])
                 if v_doc is not None:
                     v_doc = str(v_doc).replace('\n', ' ')
                 value_list.append((value, v_doc))
         simple_types[name] = (restrict, value_list, doc)
Exemple #8
0
 def _load_from_xml(self):
     root_node = self.root
     for v_node in rqet.list_of_tag(root_node, 'Value'):
         key = rqet.find_tag_int(v_node, 'Key')
         value = rqet.find_tag_text(v_node, 'Value')
         assert key not in self.str_dict, 'key value ' + str(
             key) + ' occurs more than once in string lookup table xml'
         self.str_dict[key] = value
         if self.min_index is None or key < self.min_index:
             self.min_index = key
         if self.max_index is None or key > self.max_index:
             self.max_index = key
def _cached_part_array_ref_get_node_points(part_node, dtype):
    patch_list = rqet.list_of_tag(part_node, 'PatchOfPoints')
    assert len(patch_list) == 1  # todo: handle more than one patch of points
    first_values_node = rqet.find_tag(patch_list[0], 'Points')
    if first_values_node is None:
        return None  # could treat as fatal error
    if dtype is None:
        dtype = 'float'
    else:
        assert dtype in ['float', float, np.float32, np.float64]
    tag = 'Coordinates'
    return first_values_node, tag, dtype
Exemple #10
0
 def _load_from_xml(self):
     time_series_root = self.root
     assert time_series_root is not None
     # for human timeframe series, timestamps is an ordered list of timestamp strings in resqml/iso format
     # for geological timeframe series, timestamps is an ordered list of ints being the year offsets from present
     self.timestamps = []
     for child in rqet.list_of_tag(time_series_root, 'Time'):
         dt_text = rqet.find_tag_text(child, 'DateTime')
         assert dt_text, 'missing DateTime field in xml for time series'
         year_offset = rqet.find_tag_int(child, 'YearOffset')
         if year_offset:
             assert self.timeframe == 'geologic'
             self.timestamps.append(year_offset)  # todo: trim and check timestamp
         else:
             assert self.timeframe == 'human'
             self.timestamps.append(dt_text)  # todo: trim and check timestamp
         self.timestamps.sort()
Exemple #11
0
    def _load_from_xml(self):

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

        self.rep_int_root = self.model.referenced_node(rqet.find_tag(root, 'RepresentedInterpretation'))

        for patch_node in rqet.list_of_tag(root, 'LinePatch'):  # Loop over all LinePatches - likely just the one
            assert patch_node is not None  # Required field

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

            crs_root = self.model.referenced_node(rqet.find_tag(geometry_node, 'LocalCrs'))
            assert crs_root is not None  # Required field
            self.crs_uuid = rqet.uuid_for_part_root(crs_root)
            assert self.crs_uuid is not None  # Required field

            closed_node = rqet.find_tag(patch_node, 'ClosedPolylines')
            assert closed_node is not None  # Required field
            # The ClosedPolylines could be a BooleanConstantArray, or a BooleanArrayFromIndexArray
            closed_array = self.get_bool_array(closed_node)

            count_node = rqet.find_tag(patch_node, 'NodeCountPerPolyline')
            load_hdf5_array(self, count_node, 'count_perpol', tag = 'Values')

            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')

            # Check that the number of bools aligns with the number of count_perpoly
            # Check that the total of the count_perpoly aligns with the number of coordinates
            assert len(self.count_perpol) == len(closed_array)
            assert np.sum(self.count_perpol) == len(self.coordinates)

            subpolys = self.convert_to_polylines(closed_array, self.count_perpol, self.coordinates, self.crs_uuid,
                                                 self.rep_int_root)
            # Check we have the right number of polygons
            assert len(subpolys) == len(self.count_perpol)

            # Remove duplicate coordinates and count arrays (exist in polylines now)
            # delattr(self,'coordinates')
            # delattr(self,'count_perpol')

            self.polys.extend(subpolys)
 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.genetic_boundary_feature = GeneticBoundaryFeature(self.model,
                                                                kind = 'geobody boundary',
                                                                uuid = self.feature_root.attrib['uuid'],
                                                                feature_name = self.model.title_for_root(
                                                                    self.feature_root))
     self.has_occurred_during = extract_has_occurred_during(root_node)
     br_node_list = rqet.list_of_tag(root_node, 'BoundaryRelation')
     if br_node_list is not None and len(br_node_list) > 0:
         self.boundary_relation_list = []
         for br_node in br_node_list:
             self.boundary_relation_list.append(br_node.text)
def _cached_part_array_ref_get_node_values(part_node, dtype):
    patch_list = rqet.list_of_tag(part_node, 'PatchOfValues')
    assert len(patch_list) == 1  # todo: handle more than one patch of values
    first_values_node = rqet.find_tag(patch_list[0], 'Values')
    if first_values_node is None:
        return None  # could treat as fatal error
    if dtype is None:
        array_type = rqet.node_type(first_values_node)
        assert array_type is not None
        if array_type == 'DoubleHdf5Array':
            dtype = 'float'
        elif array_type == 'IntegerHdf5Array':
            dtype = 'int'
        elif array_type == 'BooleanHdf5Array':
            dtype = 'bool'
        else:
            raise ValueError('array type not catered for: ' + str(array_type))
    tag = 'Values'
    return first_values_node, tag, dtype
Exemple #14
0
 def __load_from_xml_regz(self, support_geom_node):
     self.flavour = 'reg&z'
     orig_node = rqet.find_tag(support_geom_node, 'Origin')
     self.regular_origin = (rqet.find_tag_float(orig_node, 'Coordinate1'),
                            rqet.find_tag_float(orig_node, 'Coordinate2'),
                            rqet.find_tag_float(orig_node, 'Coordinate3'))
     assert self.regular_origin is not None, 'origin missing in xml for reg&z mesh (lattice)'
     offset_nodes = rqet.list_of_tag(
         support_geom_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 reg&z mesh (lattice)'
     self.regular_dxyz_dij = np.empty((2, 3))
     for j_or_i in range(2):  # 0 = J, 1 = I
         axial_offset_node = rqet.find_tag(offset_nodes[j_or_i], 'Offset')
         assert axial_offset_node is not None, 'missing offset offset node in xml'
         self.regular_dxyz_dij[1 - j_or_i] = (rqet.find_tag_float(
             axial_offset_node, 'Coordinate1'),
                                              rqet.find_tag_float(
                                                  axial_offset_node,
                                                  'Coordinate2'),
                                              rqet.find_tag_float(
                                                  axial_offset_node,
                                                  'Coordinate3'))
         if not maths.isclose(
                 vec.dot_product(self.regular_dxyz_dij[1 - j_or_i],
                                 self.regular_dxyz_dij[1 - j_or_i]), 1.0):
             log.warning(
                 'non-orthogonal axes and/or scaling in xml for regular mesh (lattice)'
             )
         spacing_node = rqet.find_tag(offset_nodes[j_or_i], 'Spacing')
         stride = rqet.find_tag_float(spacing_node, 'Value')
         count = rqet.find_tag_int(spacing_node, 'Count')
         assert stride is not None and count is not None, 'missing spacing info in xml'
         assert count == (self.nj, self.ni)[j_or_i] - 1, \
             'unexpected value for count in xml spacing info for regular mesh (lattice)'
         assert stride > 0.0, 'spacing distance is not positive in xml for regular mesh (lattice)'
         self.regular_dxyz_dij[1 - j_or_i] *= stride
Exemple #15
0
    def _load_from_xml(self):
        """Loads the wellbore marker frame object from an xml node (and associated hdf5 data).

        note:
           this method is not usually called directly
        """

        wellbore_marker_frame_root = self.root
        assert wellbore_marker_frame_root is not None

        self.trajectory_uuid = bu.uuid_from_string(
            rqet.find_nested_tags_text(wellbore_marker_frame_root,
                                       ['Trajectory', 'UUID']))
        self.trajectory = Trajectory(parent_model=self.model,
                                     uuid=self.trajectory_uuid)

        # list of Wellbore markers
        self.marker_list = []
        for i, tag in enumerate(
                rqet.list_of_tag(wellbore_marker_frame_root,
                                 'WellboreMarker')):
            marker_obj = WellboreMarker(parent_model=self.model,
                                        parent_frame=self,
                                        marker_index=i,
                                        marker_node=tag)
            self.marker_list.append(marker_obj)

        self.node_count = rqet.find_tag_int(wellbore_marker_frame_root,
                                            'NodeCount')
        load_hdf5_array(self,
                        rqet.find_tag(wellbore_marker_frame_root, 'NodeMd'),
                        "node_mds",
                        tag='Values')

        assert self.node_count == len(
            self.node_mds), 'node count does not match hdf5 array'
        assert len(
            self.marker_list
        ) == self.node_count, 'wellbore marker list does not contain correct node count'
Exemple #16
0
    def _load_from_xml(self):
        assert self.root is not None
        self.patch_count = rqet.count_tag(self.root, 'NodePatch')
        assert self.patch_count, 'no patches found in xml for point set'
        self.patch_array_list = [None for _ in range(self.patch_count)]
        patch_index = 0
        for child in rqet.list_of_tag(self.root, 'NodePatch'):
            point_count = rqet.find_tag_int(child, 'Count')
            geom_node = rqet.find_tag(child, 'Geometry')
            assert geom_node is not None, 'geometry missing in xml for point set patch'
            crs_uuid = rqet.find_nested_tags_text(geom_node, ['LocalCrs', 'UUID'])
            assert crs_uuid, 'crs uuid missing in geometry xml for point set patch'
            self.check_crs_match(crs_uuid)
            ext_uuid = rqet.find_nested_tags_text(geom_node, ['Points', 'Coordinates', 'HdfProxy', 'UUID'])
            assert ext_uuid, 'missing hdf5 uuid in geometry xml for point set patch'
            hdf5_path = rqet.find_nested_tags_text(geom_node, ['Points', 'Coordinates', 'PathInHdfFile'])
            assert hdf5_path, 'missing internal hdf5 path in geometry xml for point set patch'
            self.patch_ref_list.append((ext_uuid, hdf5_path, point_count))
            patch_index += 1

        ref_node = rqet.find_tag(self.root, 'RepresentedInterpretation')
        if ref_node is not None:
            interp_root = self.model.referenced_node(ref_node)
            self.set_represented_interpretation_root(interp_root)
Exemple #17
0
def _create_reciprocal_relationship(model,
                                    node_a,
                                    rel_type_a,
                                    node_b,
                                    rel_type_b,
                                    avoid_duplicates=True):
    """Adds a node to each of a pair of trees in the rels forest, to represent a two-way relationship."""
    def id_str(uuid):
        stringy = str(uuid)
        if not (rqet.pretend_to_be_fesapi
                or rqet.use_fesapi_quirks) or not stringy[0].isdigit():
            return stringy
        return '_' + stringy

    assert (model.rels_present)

    if node_a is None or node_b is None:
        log.error('attempt to create relationship with missing object')
        return

    uuid_a = node_a.attrib['uuid']
    obj_type_a = rqet.stripped_of_prefix(
        rqet.content_type(node_a.attrib[ns['xsi'] + 'type']))
    part_name_a = rqet.part_name_for_object(obj_type_a, uuid_a)
    rel_part_name_a = rqet.rels_part_name_for_part(part_name_a)
    (rel_uuid_a, rel_tree_a) = model.rels_forest[rel_part_name_a]
    rel_root_a = rel_tree_a.getroot()

    uuid_b = node_b.attrib['uuid']
    obj_type_b = rqet.stripped_of_prefix(
        rqet.content_type(node_b.attrib[ns['xsi'] + 'type']))
    part_name_b = rqet.part_name_for_object(obj_type_b, uuid_b)
    rel_part_name_b = rqet.rels_part_name_for_part(part_name_b)
    (rel_uuid_b, rel_tree_b) = model.rels_forest[rel_part_name_b]
    rel_root_b = rel_tree_b.getroot()

    create_a = True
    if avoid_duplicates:
        existing_rel_nodes = rqet.list_of_tag(rel_root_a, 'Relationship')
        for existing in existing_rel_nodes:
            if (rqet.stripped_of_prefix(existing.attrib['Type']) == rel_type_a
                    and existing.attrib['Target'] == part_name_b):
                create_a = False
                break
    if create_a:
        rel_a = rqet.SubElement(rel_root_a, ns['rels'] + 'Relationship')
        rel_a.set(
            'Id', id_str(uuid_b)
        )  # NB: fesapi prefixes uuid with _ for some rels only (where uuid starts with a digit)
        rel_a.set('Type', ns_url['rels_ext'] + rel_type_a)
        rel_a.set('Target', part_name_b)

    create_b = True
    if avoid_duplicates:
        existing_rel_nodes = rqet.list_of_tag(rel_root_b, 'Relationship')
        for existing in existing_rel_nodes:
            if (rqet.stripped_of_prefix(existing.attrib['Type']) == rel_type_b
                    and existing.attrib['Target'] == part_name_a):
                create_b = False
                break
    if create_b:
        rel_b = rqet.SubElement(rel_root_b, ns['rels'] + 'Relationship')
        rel_b.set(
            'Id', id_str(uuid_a)
        )  # NB: fesapi prefixes uuid with _ for some rels only (where uuid starts with a digit)
        rel_b.set('Type', ns_url['rels_ext'] + rel_type_b)
        rel_b.set('Target', part_name_a)