Example #1
0
    def create_xml(self, add_as_part = True, originator = None, reuse = True):
        """Creates a genetic boundary feature organisational xml node from this genetic boundary feature object."""

        if reuse and self.try_reuse():
            return self.root  # check for reusable (equivalent) object
        # create node with citation block
        gbf = super().create_xml(add_as_part = False, originator = originator)

        assert self.kind in self.valid_kinds
        kind_node = rqet.SubElement(gbf, ns['resqml2'] + 'GeneticBoundaryKind')
        kind_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'GeneticBoundaryKind')
        kind_node.text = self.kind

        if self.absolute_age is not None:
            date_time, year_offset = self.absolute_age
            age_node = rqet.SubElement(gbf, ns['resqml2'] + 'AbsoluteAge')
            age_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Timestamp')
            age_node.text = rqet.null_xml_text
            dt_node = rqet.SubElement(age_node, ns['resqml2'] + 'DateTime')
            dt_node.set(ns['xsi'] + 'type', ns['xsd'] + 'dateTime')
            dt_node.text = str(date_time)
            if year_offset is not None:
                yo_node = rqet.SubElement(age_node, ns['resqml2'] + 'YearOffset')
                yo_node.set(ns['xsi'] + 'type', ns['xsd'] + 'long')
                yo_node.text = str(year_offset)

        if add_as_part:
            self.model.add_part('obj_GeneticBoundaryFeature', self.uuid, gbf)

        return gbf
Example #2
0
File: _xml.py Project: bp/resqpy
def _create_doc_props(model, add_as_part=True, root=None, originator=None):
    """Creates a document properties stub node and optionally adds as child of root and/or to parts forest."""

    dp = rqet.Element(ns['cp'] + 'coreProperties')
    dp.text = rqet.null_xml_text

    created = rqet.SubElement(dp, ns['dcterms'] + 'created')
    created.set(ns['xsi'] + 'type',
                ns['dcterms'] + 'W3CDTF')  # not sure of namespace here
    created.text = time.now()

    if originator is None:
        try:
            originator = str(os.getlogin())
        except Exception:
            originator = 'unknown'
    creator = rqet.SubElement(dp, ns['dc'] + 'creator')
    creator.text = originator

    ver = rqet.SubElement(dp, ns['cp'] + 'version')
    ver.text = '1.0'

    if root is not None:
        root.append(dp)
    if add_as_part:
        model.add_part('docProps', None, dp)
        if model.rels_present:
            (_, rel_tree) = model.rels_forest['_rels/.rels']
            core_rel = rqet.SubElement(rel_tree.getroot(),
                                       ns['rels'] + 'Relationship')
            core_rel.set('Id', 'CoreProperties')
            core_rel.set('Type', ns_url['rels_md'] + 'core-properties')
            core_rel.set('Target', 'docProps/core.xml')
    return dp
    def create_xml(self,
                   genetic_boundary_feature_root = None,
                   add_as_part = True,
                   add_relationships = True,
                   originator = None,
                   title_suffix = None,
                   reuse = True):
        """Create a organisational xml node from a geobody boundary interpretation object."""

        if not self.title:
            self.title = self.genetic_boundary_feature.feature_name
        if title_suffix:
            self.title += ' ' + title_suffix

        if reuse and self.try_reuse():
            return self.root
        gbi = super().create_xml(add_as_part = False, originator = originator)

        if self.genetic_boundary_feature is not None:
            gbf_root = self.genetic_boundary_feature.root
            if gbf_root is not None:
                if genetic_boundary_feature_root is None:
                    genetic_boundary_feature_root = gbf_root
                else:
                    assert gbf_root is genetic_boundary_feature_root, 'genetic boundary feature mismatch'
        else:
            if genetic_boundary_feature_root is None:
                genetic_boundary_feature_root = self.feature_root
            assert genetic_boundary_feature_root is not None
            self.genetic_boundary_feature = GeneticBoundaryFeature(self.model,
                                                                   uuid = genetic_boundary_feature_root.attrib['uuid'])
        self.feature_root = genetic_boundary_feature_root

        assert self.domain in self.valid_domains, 'illegal domain value for geobody boundary interpretation'
        dom_node = rqet.SubElement(gbi, ns['resqml2'] + 'Domain')
        dom_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Domain')
        dom_node.text = self.domain

        create_xml_has_occurred_during(self.model, gbi, self.has_occurred_during)

        if self.boundary_relation_list is not None:
            for boundary_relation in self.boundary_relation_list:
                assert boundary_relation in self.valid_boundary_relations
                br_node = rqet.SubElement(gbi, ns['resqml2'] + 'BoundaryRelation')
                br_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'BoundaryRelation')
                br_node.text = str(boundary_relation)

        self.model.create_ref_node('InterpretedFeature',
                                   self.model.title_for_root(genetic_boundary_feature_root),
                                   genetic_boundary_feature_root.attrib['uuid'],
                                   content_type = 'obj_GeneticBoundaryFeature',
                                   root = gbi)

        if add_as_part:
            self.model.add_part('obj_GeobodyBoundaryInterpretation', self.uuid, gbi)
            if add_relationships:
                self.model.create_reciprocal_relationship(gbi, 'destinationObject', genetic_boundary_feature_root,
                                                          'sourceObject')

        return gbi
Example #4
0
    def create_xml(self,
                   wellbore_feature_root=None,
                   add_as_part=True,
                   add_relationships=True,
                   originator=None,
                   title_suffix=None,
                   reuse=True):
        """Creates a wellbore interpretation organisational xml node from a wellbore interpretation object."""

        # note: related wellbore feature node should be created first and referenced here

        if not self.title:
            self.title = self.wellbore_feature.feature_name
        if title_suffix:
            self.title += ' ' + title_suffix

        if reuse and self.try_reuse():
            return self.root
        wi = super().create_xml(add_as_part=False, originator=originator)

        if self.wellbore_feature is not None:
            wbf_root = self.wellbore_feature.root
            if wbf_root is not None:
                if wellbore_feature_root is None:
                    wellbore_feature_root = wbf_root
                else:
                    assert wbf_root is wellbore_feature_root, 'wellbore feature mismatch'

        if self.is_drilled is None:
            self.is_drilled = False

        id_node = rqet.SubElement(wi, ns['resqml2'] + 'IsDrilled')
        id_node.set(ns['xsi'] + 'type', ns['xsd'] + 'boolean')
        id_node.text = str(self.is_drilled).lower()

        assert self.domain in self.valid_domains, 'illegal domain value for wellbore interpretation'
        domain_node = rqet.SubElement(wi, ns['resqml2'] + 'Domain')
        domain_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Domain')
        domain_node.text = str(self.domain).lower()

        self.model.create_ref_node(
            'InterpretedFeature',
            self.model.title_for_root(wellbore_feature_root),
            wellbore_feature_root.attrib['uuid'],
            content_type='obj_WellboreFeature',
            root=wi)

        if add_as_part:
            self.model.add_part('obj_WellboreInterpretation', self.uuid, wi)
            if add_relationships:
                self.model.create_reciprocal_relationship(
                    wi, 'destinationObject', wellbore_feature_root,
                    'sourceObject')

        return wi
Example #5
0
def _create_xml_facet_node(facet_type, facet, p_node):
    if facet_type is not None and facet is not None:
        facet_node = rqet.SubElement(p_node, ns['resqml2'] + 'Facet')
        facet_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'PropertyKindFacet')
        facet_node.text = rqet.null_xml_text
        facet_type_node = rqet.SubElement(facet_node, ns['resqml2'] + 'Facet')
        facet_type_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Facet')
        facet_type_node.text = facet_type
        facet_value_node = rqet.SubElement(facet_node, ns['resqml2'] + 'Value')
        facet_value_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string')
        facet_value_node.text = facet
    def create_xml(self,
                   add_as_part=True,
                   add_relationships=True,
                   originator=None,
                   reuse=True):
        """Creates a stratigraphic unit interpretation xml tree.

        arguments:
           add_as_part (bool, default True): if True, the interpretation is added to the parent model as a high level part
           add_relationships (bool, default True): if True and add_as_part is True, a relationship is created with
              the referenced stratigraphic unit feature
           originator (str, optional): if present, is used as the originator field of the citation block
           reuse (bool, default True): if True, the parent model is inspected for any equivalent interpretation and, if found,
              the uuid of this interpretation is set to that of the equivalent part

        returns:
           lxml.etree._Element: the root node of the newly created xml tree for the interpretation
        """

        if reuse and self.try_reuse():
            return self.root

        sui = super().create_xml(add_as_part=add_as_part,
                                 add_relationships=add_relationships,
                                 originator=originator,
                                 reuse=False)
        assert sui is not None

        if self.deposition_mode is not None:
            assert self.deposition_mode in valid_deposition_modes,  \
               f'invalid deposition mode {self.deposition_mode} for stratigraphic unit interpretation'
            dm_node = rqet.SubElement(sui, ns['resqml2'] + 'DepositionMode')
            dm_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'DepositionMode')
            dm_node.text = self.deposition_mode

        if self.min_thickness is not None or self.max_thickness is not None:
            assert self.thickness_uom in wam.valid_uoms(quantity='length')

        if self.min_thickness is not None:
            min_thick_node = rqet.SubElement(sui,
                                             ns['resqml2'] + 'MinThickness')
            min_thick_node.set(ns['xsi'] + 'type', ns['eml'] + 'LengthMeasure')
            min_thick_node.set('uom', self.thickness_uom)  # todo: check this
            min_thick_node.text = str(self.min_thickness)

        if self.max_thickness is not None:
            max_thick_node = rqet.SubElement(sui,
                                             ns['resqml2'] + 'MaxThickness')
            max_thick_node.set(ns['xsi'] + 'type', ns['eml'] + 'LengthMeasure')
            max_thick_node.set('uom', self.thickness_uom)
            max_thick_node.text = str(self.max_thickness)

        return sui
Example #7
0
File: _xml.py Project: bp/resqpy
def _create_solitary_point3d(flavour, root, xyz):
    """Creates a subelement to root for a solitary point in 3D space."""

    # todo: check namespaces
    p3d = rqet.SubElement(root, ns['resqml2'] + flavour)
    p3d.set(ns['xsi'] + 'type', ns['resqml2'] + 'Point3d')
    p3d.text = rqet.null_xml_text

    for axis in range(3):
        coord_node = rqet.SubElement(
            p3d, ns['resqml2'] + 'Coordinate' + str(axis + 1))
        coord_node.set(ns['xsi'] + 'type', ns['xsd'] + 'double')
        coord_node.text = str(xyz[axis])

    return p3d
Example #8
0
File: _mesh.py Project: bp/resqpy
    def __create_xml_refandz(self, p_node, ext_uuid):
        assert ext_uuid is not None
        assert self.ref_uuid is not None

        p_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Point3dZValueArray')

        sg_node = rqet.SubElement(p_node, ns['resqml2'] + 'SupportingGeometry')

        sg_node.set(ns['xsi'] + 'type',
                    ns['resqml2'] + 'Point3dFromRepresentationLatticeArray')
        sg_node.text = '\n'

        niosr_node = rqet.SubElement(
            sg_node, ns['resqml2'] + 'NodeIndicesOnSupportingRepresentation')
        niosr_node.set(ns['xsi'] + 'type',
                       ns['resqml2'] + 'IntegerLatticeArray')
        niosr_node.text = '\n'

        sv_node = rqet.SubElement(niosr_node, ns['resqml2'] + 'StartValue')
        sv_node.set(ns['xsi'] + 'type', ns['xsd'] + 'integer')
        sv_node.text = '0'  # no other possibility cater for at present

        for j_or_i in range(2):  # 0 = J, 1 = I
            o_node = rqet.SubElement(niosr_node, ns['resqml2'] + 'Offset')
            o_node.set(ns['xsi'] + 'type',
                       ns['resqml2'] + 'IntegerConstantArray'
                       )  # no other possibility cater for at present
            o_node.text = '\n'
            ov_node = rqet.SubElement(o_node, ns['resqml2'] + 'Value')
            ov_node.set(ns['xsi'] + 'type', ns['xsd'] + 'integer')
            ov_node.text = '1'  # no other possibility cater for at present
            oc_node = rqet.SubElement(o_node, ns['resqml2'] + 'Count')
            oc_node.set(ns['xsi'] + 'type', ns['xsd'] + 'positiveInteger')
            if j_or_i:
                oc_node.text = str(self.ni - 1)
            else:
                oc_node.text = str(self.nj - 1)

        ref_root = self.model.root_for_uuid(self.ref_uuid)
        self.model.create_ref_node('SupportingRepresentation',
                                   rqet.find_nested_tags_text(
                                       ref_root, ['Citation', 'Title']),
                                   self.ref_uuid,
                                   content_type='Grid2dRepresentation',
                                   root=sg_node)

        zv_node = rqet.SubElement(p_node, ns['resqml2'] + 'ZValues')
        zv_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'DoubleHdf5Array')
        zv_node.text = '\n'

        v_node = rqet.SubElement(zv_node, ns['resqml2'] + 'Values')
        v_node.set(ns['xsi'] + 'type', ns['eml'] + 'Hdf5Dataset')
        v_node.text = '\n'

        self.model.create_hdf5_dataset_ref(ext_uuid,
                                           self.uuid,
                                           'zvalues',
                                           root=v_node)
Example #9
0
def _create_xml_property_min_max(collection, property_array, const_value,
                                 discrete, add_min_max, p_node, min_value,
                                 max_value):
    if add_min_max:
        # todo: use active cell mask on numpy min and max operations; exclude null values on discrete min max
        min_value, max_value = pcga._get_property_array_min_max_value(
            collection, property_array, const_value, discrete, min_value,
            max_value)
        if min_value is not None:
            min_node = rqet.SubElement(p_node, ns['resqml2'] + 'MinimumValue')
            min_node.set(ns['xsi'] + 'type', ns['xsd'] + collection.xsd_type)
            min_node.text = str(min_value)
        if max_value is not None:
            max_node = rqet.SubElement(p_node, ns['resqml2'] + 'MaximumValue')
            max_node.set(ns['xsi'] + 'type', ns['xsd'] + collection.xsd_type)
            max_node.text = str(max_value)
Example #10
0
    def __add_sub_elements_to_root_node(self, wbm_node):
        """Appends sub-elements to the WellboreMarkerFrame object's root node."""

        nodeCount = rqet.SubElement(wbm_node, ns['resqml2'] + 'NodeCount')
        nodeCount.set(ns['xsi'] + 'type', ns['xsd'] + 'positiveInteger')
        nodeCount.text = str(self.node_count)

        nodeMd = rqet.SubElement(wbm_node, ns['resqml2'] + 'NodeMd')
        nodeMd.set(ns['xsi'] + 'type', ns['resqml2'] + 'DoubleHdf5Array')
        nodeMd.text = rqet.null_xml_text

        md_values_node = rqet.SubElement(nodeMd, ns['resqml2'] + 'Values')
        md_values_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Hdf5Dataset')
        md_values_node.text = rqet.null_xml_text

        return nodeCount, nodeMd, md_values_node
Example #11
0
File: _xml.py Project: bp/resqpy
def _create_hdf5_ext(model,
                     add_as_part=True,
                     root=None,
                     title='Hdf Proxy',
                     originator=None,
                     file_name=None,
                     uuid=None):
    """Creates an hdf5 external node and optionally adds as child of root and/or to parts forest."""

    ext = _new_obj_node('EpcExternalPartReference', name_space='eml')
    assert ext is not None
    if uuid is not None:  # preserve ext uuid if supplied
        ext.set('uuid', str(uuid))

    _create_citation(root=ext, title=title, originator=originator)

    mime_type = rqet.SubElement(ext, ns['eml'] + 'MimeType')
    mime_type.set(ns['xsi'] + 'type', ns['xsd'] + 'string')
    mime_type.text = 'application/x-hdf5'

    if root is not None:
        root.append(ext)
    if add_as_part:
        ext_uuid = bu.uuid_from_string(ext.attrib['uuid'])
        model.add_part('obj_EpcExternalPartReference', ext_uuid, ext)
        if not file_name:
            file_name = model.h5_file_name(override='full',
                                           file_must_exist=False)
        elif os.sep not in file_name:
            file_name = os.path.join(model.epc_directory, file_name)
        assert file_name
        log.debug(f'creating ext part for hdf5 file: {file_name}')
        model.h5_dict[ext_uuid.bytes] = file_name
        if model.main_h5_uuid is None:
            model.main_h5_uuid = ext_uuid
        if model.rels_present and file_name:
            (uuid, rel_tree) = model.rels_forest[rqet.rels_part_name_for_part(
                rqet.part_name_for_object('obj_EpcExternalPartReference',
                                          ext_uuid))]
            assert (bu.matching_uuids(uuid, ext_uuid))
            rel_node = rqet.SubElement(rel_tree.getroot(),
                                       ns['rels'] + 'Relationship')
            rel_node.set('Id', 'Hdf5File')
            rel_node.set('Type', ns_url['rels_ext'] + 'externalResource')
            rel_node.set('Target', file_name)
            rel_node.set('TargetMode', 'External')
    return ext
Example #12
0
    def __add_sub_elements_to_root_node(self, ds_node):
        """Appends sub-elements to the DeviationSurvey object's root node."""

        if_node = rqet.SubElement(ds_node, ns['resqml2'] + 'IsFinal')
        if_node.set(ns['xsi'] + 'type', ns['xsd'] + 'boolean')
        if_node.text = str(self.is_final).lower()

        sc_node = rqet.SubElement(ds_node, ns['resqml2'] + 'StationCount')
        sc_node.set(ns['xsi'] + 'type', ns['xsd'] + 'positiveInteger')
        sc_node.text = str(self.station_count)

        md_uom = rqet.SubElement(ds_node, ns['resqml2'] + 'MdUom')
        md_uom.set(ns['xsi'] + 'type', ns['eml'] + 'LengthUom')
        md_uom.text = bwam.rq_length_unit(self.md_uom)

        angle_uom = rqet.SubElement(ds_node, ns['resqml2'] + 'AngleUom')
        angle_uom.set(ns['xsi'] + 'type', ns['eml'] + 'PlaneAngleUom')
        if self.angles_in_degrees:
            angle_uom.text = 'dega'
        else:
            angle_uom.text = 'rad'

        mds = rqet.SubElement(ds_node, ns['resqml2'] + 'Mds')
        mds.set(ns['xsi'] + 'type', ns['resqml2'] + 'DoubleHdf5Array')
        mds.text = rqet.null_xml_text

        mds_values_node = rqet.SubElement(mds, ns['resqml2'] + 'Values')
        mds_values_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Hdf5Dataset')
        mds_values_node.text = rqet.null_xml_text

        azimuths = rqet.SubElement(ds_node, ns['resqml2'] + 'Azimuths')
        azimuths.set(ns['xsi'] + 'type', ns['resqml2'] + 'DoubleHdf5Array')
        azimuths.text = rqet.null_xml_text

        azimuths_values_node = rqet.SubElement(azimuths, ns['resqml2'] + 'Values')
        azimuths_values_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Hdf5Dataset')
        azimuths_values_node.text = rqet.null_xml_text

        inclinations = rqet.SubElement(ds_node, ns['resqml2'] + 'Inclinations')
        inclinations.set(ns['xsi'] + 'type', ns['resqml2'] + 'DoubleHdf5Array')
        inclinations.text = rqet.null_xml_text

        inclinations_values_node = rqet.SubElement(inclinations, ns['resqml2'] + 'Values')
        inclinations_values_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Hdf5Dataset')
        inclinations_values_node.text = rqet.null_xml_text

        return mds_values_node, azimuths_values_node, inclinations_values_node
Example #13
0
File: _xml.py Project: bp/resqpy
def _create_ref_node(flavour, title, uuid, content_type=None, root=None):
    """Create a reference node, optionally add to root."""

    assert uuid is not None

    if flavour.startswith('obj_'):
        flavour = flavour[4:]

    if not content_type:
        content_type = 'obj_' + flavour
    else:
        if content_type[0].isupper():
            content_type = 'obj_' + content_type

    prefix = ns['eml'] if flavour == 'HdfProxy' else ns['resqml2']
    ref_node = rqet.Element(prefix + flavour)
    ref_node.set(ns['xsi'] + 'type', ns['eml'] + 'DataObjectReference')
    ref_node.text = rqet.null_xml_text

    ct_node = rqet.SubElement(ref_node, ns['eml'] + 'ContentType')
    ct_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string')
    if 'EpcExternalPartReference' in content_type:
        ct_node.text = 'application/x-eml+xml;version=2.0;type=' + content_type
    else:
        ct_node.text = 'application/x-resqml+xml;version=2.0;type=' + content_type

    if not title:
        title = '(title unavailable)'
    title_node = rqet.SubElement(ref_node, ns['eml'] + 'Title')
    title_node.set(ns['xsi'] + 'type', ns['eml'] + 'DescriptionString')
    title_node.text = title

    uuid_node = rqet.SubElement(ref_node, ns['eml'] + 'UUID')
    uuid_node.set(ns['xsi'] + 'type', ns['eml'] + 'UuidString')
    uuid_node.text = str(uuid)

    if use_version_string:
        version_str = rqet.SubElement(
            ref_node, ns['eml'] + 'VersionString')  # I'm guessing what this is
        version_str.set(ns['xsi'] + 'type', ns['eml'] + 'NameString')
        version_str.text = bu.version_string(uuid)

    if root is not None:
        root.append(ref_node)

    return ref_node
Example #14
0
    def __create_wbt_node_geometry_sub_elements(self, wbt_node):
        """ Append sub-elements to the Trajectory object's root node that are related to well geometry."""

        geom = rqet.SubElement(wbt_node, ns['resqml2'] + 'Geometry')
        geom.set(ns['xsi'] + 'type', ns['resqml2'] + 'ParametricLineGeometry')
        geom.text = '\n'

        # note: resqml standard allows trajectory to be in different crs to md datum
        #       however, this module often uses the md datum crs, if the trajectory has been imported

        kc_node = rqet.SubElement(geom, ns['resqml2'] + 'KnotCount')
        kc_node.set(ns['xsi'] + 'type', ns['xsd'] + 'positiveInteger')
        kc_node.text = str(self.knot_count)

        lki_node = rqet.SubElement(geom, ns['resqml2'] + 'LineKindIndex')
        lki_node.set(ns['xsi'] + 'type', ns['xsd'] + 'integer')
        lki_node.text = str(self.line_kind_index)

        cpp_node = rqet.SubElement(geom,
                                   ns['resqml2'] + 'ControlPointParameters')
        cpp_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'DoubleHdf5Array')
        cpp_node.text = rqet.null_xml_text

        cpp_values_node = rqet.SubElement(cpp_node, ns['resqml2'] + 'Values')
        cpp_values_node.set(ns['xsi'] + 'type', ns['eml'] + 'Hdf5Dataset')
        cpp_values_node.text = rqet.null_xml_text

        cp_node = rqet.SubElement(geom, ns['resqml2'] + 'ControlPoints')
        cp_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Point3dHdf5Array')
        cp_node.text = rqet.null_xml_text

        cp_coords_node = rqet.SubElement(cp_node,
                                         ns['resqml2'] + 'Coordinates')
        cp_coords_node.set(ns['xsi'] + 'type', ns['eml'] + 'Hdf5Dataset')
        cp_coords_node.text = rqet.null_xml_text

        if self.tangent_vectors is not None:
            tv_node = rqet.SubElement(geom, ns['resqml2'] + 'TangentVectors')
            tv_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Point3dHdf5Array')
            tv_node.text = rqet.null_xml_text

            tv_coords_node = rqet.SubElement(tv_node,
                                             ns['resqml2'] + 'Coordinates')
            tv_coords_node.set(ns['xsi'] + 'type', ns['eml'] + 'Hdf5Dataset')
            tv_coords_node.text = rqet.null_xml_text
        else:
            tv_node = None
            tv_coords_node = None

        return geom, kc_node, lki_node, cpp_node, cpp_values_node, cp_node, cp_coords_node, tv_node, tv_coords_node
Example #15
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 #16
0
def _create_xml_add_basics_to_p_node(collection, p_node, title, originator,
                                     extra_metadata, source, count,
                                     indexable_element):
    collection.model.create_citation(root=p_node,
                                     title=title,
                                     originator=originator)
    rqet.create_metadata_xml(node=p_node, extra_metadata=extra_metadata)

    if source is not None and len(source) > 0:
        collection.model.create_source(source=source, root=p_node)

    count_node = rqet.SubElement(p_node, ns['resqml2'] + 'Count')
    count_node.set(ns['xsi'] + 'type', ns['xsd'] + 'positiveInteger')
    count_node.text = str(count)

    ie_node = rqet.SubElement(p_node, ns['resqml2'] + 'IndexableElement')
    ie_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'IndexableElements')
    ie_node.text = indexable_element
Example #17
0
    def create_xml(self, add_as_part = True, title = None, originator = None, reuse = True):
        """Create a RESQML time series xml node from a TimeSeries or GeologicTimeSeries object, optionally add as part.

        arguments:
           add_as_part (boolean, default True): if True, the newly created xml node is added as a part
              in the model
           title (string): used as the citation Title text for the new time series node
           originator (string, optional): the name of the human being who created the time series object;
              default is to use the login name

        returns:
           the newly created time series xml node

        :meta common:
        """

        if reuse and self.try_reuse():
            return self.root  # check for reusable (equivalent) object

        if self.extra_metadata is None:
            self.extra_metadata = {}
        self.extra_metadata['timeframe'] = self.timeframe

        ts_node = super().create_xml(add_as_part = False, title = title, originator = originator)

        for index in range(self.number_of_timestamps()):
            time_node = rqet.SubElement(ts_node, ns['resqml2'] + 'Time')
            time_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Timestamp')
            time_node.text = rqet.null_xml_text
            dt_node = rqet.SubElement(time_node, ns['resqml2'] + 'DateTime')
            dt_node.set(ns['xsi'] + 'type', ns['xsd'] + 'dateTime')
            if self.timeframe == 'geologic':
                assert isinstance(self.timestamps[index], int)
                dt_node.text = '0000-01-01T00:00:00Z'
                yo_node = rqet.SubElement(time_node, ns['resqml2'] + 'YearOffset')
                yo_node.set(ns['xsi'] + 'type', ns['xsd'] + 'long')
                yo_node.text = str(self.timestamps[index])
            else:
                dt_node.text = self.timestamp(index)

        if add_as_part:
            self.model.add_part('obj_TimeSeries', self.uuid, ts_node)

        return ts_node
Example #18
0
File: _xml.py Project: bp/resqpy
def _create_source(source, root=None):
    """Create an extra meta data node holding information on the source of the data, optionally add to root."""

    emd_node = rqet.Element(ns['resqml2'] + 'ExtraMetadata')
    emd_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'NameValuePair')
    emd_node.text = rqet.null_xml_text

    name_node = rqet.SubElement(emd_node, ns['resqml2'] + 'Name')
    name_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string')
    name_node.text = 'source'

    value_node = rqet.SubElement(emd_node, ns['resqml2'] + 'Value')
    value_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string')
    value_node.text = source

    if root is not None:
        root.append(emd_node)

    return emd_node
Example #19
0
    def __create_wbt_node_non_geometry_sub_elements(self, wbt_node):
        """ Append sub-elements to the Trajectory object's root node that are unrelated to well geometry."""

        start_node = rqet.SubElement(wbt_node, ns['resqml2'] + 'StartMd')
        start_node.set(ns['xsi'] + 'type', ns['xsd'] + 'double')
        start_node.text = str(self.start_md)

        finish_node = rqet.SubElement(wbt_node, ns['resqml2'] + 'FinishMd')
        finish_node.set(ns['xsi'] + 'type', ns['xsd'] + 'double')
        finish_node.text = str(self.finish_md)

        md_uom = rqet.SubElement(wbt_node, ns['resqml2'] + 'MdUom')
        md_uom.set(ns['xsi'] + 'type', ns['eml'] + 'LengthUom')
        md_uom.text = bwam.rq_length_unit(self.md_uom)

        if self.md_domain:
            domain_node = rqet.SubElement(wbt_node, ns['resqml2'] + 'MdDomain')
            domain_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'MdDomain')
            domain_node.text = self.md_domain
Example #20
0
File: _mesh.py Project: bp/resqpy
    def __create_xml_regandz(self, p_node, ext_uuid):

        assert ext_uuid is not None

        p_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Point3dZValueArray')

        sg_node = rqet.SubElement(p_node, ns['resqml2'] + 'SupportingGeometry')

        sg_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Point3dLatticeArray')
        sg_node.text = '\n'

        assert self.regular_origin is not None and self.regular_dxyz_dij is not None

        self.model.create_solitary_point3d(
            'Origin', sg_node,
            self.regular_origin)  # todo: check xml namespace

        for j_or_i in range(
                2
        ):  # 0 = J, 1 = I; ie. J axis info first in xml, followed by I axis
            dxyz = self.regular_dxyz_dij[1 - j_or_i].copy()
            log.debug('dxyz: ' + str(dxyz))
            d_value = vec.dot_product(dxyz, dxyz)
            assert d_value > 0.0
            d_value = maths.sqrt(d_value)
            dxyz /= d_value
            o_node = rqet.SubElement(sg_node, ns['resqml2'] + 'Offset')
            o_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Point3dOffset')
            o_node.text = '\n'
            self.model.create_solitary_point3d('Offset', o_node, dxyz)
            space_node = rqet.SubElement(o_node, ns['resqml2'] + 'Spacing')
            space_node.set(
                ns['xsi'] + 'type', ns['resqml2'] +
                'DoubleConstantArray')  # nothing else catered for just now
            space_node.text = '\n'
            ov_node = rqet.SubElement(space_node, ns['resqml2'] + 'Value')
            ov_node.set(ns['xsi'] + 'type', ns['xsd'] + 'double')
            ov_node.text = str(d_value)
            oc_node = rqet.SubElement(space_node, ns['resqml2'] + 'Count')
            oc_node.set(ns['xsi'] + 'type', ns['xsd'] + 'positiveInteger')
            if j_or_i:
                oc_node.text = str(self.ni - 1)
            else:
                oc_node.text = str(self.nj - 1)

        zv_node = rqet.SubElement(p_node, ns['resqml2'] + 'ZValues')
        zv_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'DoubleHdf5Array')
        zv_node.text = '\n'

        v_node = rqet.SubElement(zv_node, ns['resqml2'] + 'Values')
        v_node.set(ns['xsi'] + 'type', ns['eml'] + 'Hdf5Dataset')
        v_node.text = '\n'

        self.model.create_hdf5_dataset_ref(ext_uuid,
                                           self.uuid,
                                           'zvalues',
                                           root=v_node)
Example #21
0
File: _xml.py Project: bp/resqpy
def _create_rels_part(model):
    """Adds a relationships reference node as a new part in the model's parts forest."""

    rels = rqet.SubElement(model.main_root, ns['content_types'] + 'Default')
    rels.set('Extension', 'rels')
    rels.set('ContentType',
             'application/vnd.openxmlformats-package.relationships+xml')
    model.rels_present = True
    model.set_modified()

    return rels
Example #22
0
File: _xml.py Project: bp/resqpy
def _uom_node(root, uom):
    """Add a generic unit of measure sub element to root."""

    assert root is not None and uom is not None and len(uom)
    # todo: could assert that uom is a valid unit of measure

    node = rqet.SubElement(root, ns['resqml2'] + 'UOM')
    node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ResqmlUom')
    node.text = uom

    return node
Example #23
0
    def create_xml(self,
                   title=None,
                   originator=None,
                   add_as_part=True,
                   reuse=True):
        """Creates an xml node for the string table lookup.

        arguments:
           title (string, optional): if present, overrides the object's title attribute to be used as citation title
           originator (string, optional): if present, used as the citation creator (otherwise login name is used)
           add_as_part (boolean, default True): if True, the property set is added to the model as a part

        :meta common:
        """

        if title:
            self.title = title

        if reuse and self.try_reuse():
            return self.root  # check for reusable (equivalent) object

        sl_node = super().create_xml(add_as_part=False, originator=originator)

        for k, v in self.str_dict.items():

            pair_node = rqet.SubElement(sl_node, ns['resqml2'] + 'Value')
            pair_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'StringLookup')
            pair_node.text = rqet.null_xml_text

            key_node = rqet.SubElement(pair_node, ns['resqml2'] + 'Key')
            key_node.set(ns['xsi'] + 'type', ns['xsd'] + 'integer')
            key_node.text = str(k)

            value_node = rqet.SubElement(pair_node, ns['resqml2'] + 'Value')
            value_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string')
            value_node.text = str(v)

        if add_as_part:
            self.model.add_part('obj_StringTableLookup', self.uuid, sl_node)

        return sl_node
Example #24
0
File: _xml.py Project: bp/resqpy
def _create_citation(root=None, title='', originator=None):
    """Creates a citation xml node and optionally appends as a child of root."""

    if not title:
        title = '(no title)'

    citation = rqet.Element(ns['eml'] + 'Citation')
    citation.set(ns['xsi'] + 'type', ns['eml'] + 'Citation')
    citation.text = rqet.null_xml_text

    title_node = rqet.SubElement(citation, ns['eml'] + 'Title')
    title_node.set(ns['xsi'] + 'type', ns['eml'] + 'DescriptionString')
    title_node.text = str(title)

    originator_node = rqet.SubElement(citation, ns['eml'] + 'Originator')
    if originator is None:
        try:
            originator = str(getpass.getuser())
        except Exception:
            originator = 'unknown'
    originator_node.set(ns['xsi'] + 'type', ns['eml'] + 'NameString')
    originator_node.text = originator

    creation_node = rqet.SubElement(citation, ns['eml'] + 'Creation')
    creation_node.set(ns['xsi'] + 'type', ns['xsd'] + 'dateTime')
    creation_node.text = time.now()

    format_node = rqet.SubElement(citation, ns['eml'] + 'Format')
    format_node.set(ns['xsi'] + 'type', ns['eml'] + 'DescriptionString')
    if rqet.pretend_to_be_fesapi:
        format_node.text = '[F2I-CONSULTING:fesapi]'
    else:
        format_node.text = citation_format

    # todo: add optional description field

    if root is not None:
        root.append(citation)

    return citation
Example #25
0
    def create_xml(self, add_as_part=True, originator=None, reuse=True):
        """Create xml for this bespoke property kind."""

        if reuse and self.try_reuse():
            return self.root  # check for reusable (equivalent) object

        pk = super().create_xml(add_as_part=False, originator=originator)

        ns_node = rqet.SubElement(pk, ns['resqml2'] + 'NamingSystem')
        ns_node.set(ns['xsi'] + 'type', ns['xsd'] + 'anyURI')
        ns_node.text = str(self.naming_system)

        ia_node = rqet.SubElement(pk, ns['resqml2'] + 'IsAbstract')
        ia_node.set(ns['xsi'] + 'type', ns['xsd'] + 'boolean')
        ia_node.text = str(self.is_abstract).lower()

        # note: schema definition requires this field, even for discrete property kinds
        uom = self.example_uom
        if uom is None:
            uom = 'Euc'
        ru_node = rqet.SubElement(pk, ns['resqml2'] + 'RepresentativeUom')
        ru_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ResqmlUom')
        ru_node.text = str(uom)

        ppk_node = rqet.SubElement(pk, ns['resqml2'] + 'ParentPropertyKind')
        ppk_node.set(ns['xsi'] + 'type',
                     ns['resqml2'] + 'StandardPropertyKind')
        ppk_node.text = rqet.null_xml_text

        ppk_kind_node = rqet.SubElement(ppk_node, ns['resqml2'] + 'Kind')
        ppk_kind_node.set(ns['xsi'] + 'type',
                          ns['resqml2'] + 'ResqmlPropertyKind')
        ppk_kind_node.text = str(self.parent_kind)

        if add_as_part:
            self.model.add_part('obj_PropertyKind', self.uuid, pk)
            # no relationships at present, if local parent property kinds were to be supported then a rel. is needed there

        return pk
Example #26
0
    def create_xml(self,
                   organization_feature_root = None,
                   add_as_part = True,
                   add_relationships = True,
                   originator = None,
                   title_suffix = None,
                   reuse = True):
        """Creates an earth model interpretation organisational xml node from an earth model interpretation object."""

        # note: related organization feature node should be created first and referenced here

        if not self.title:
            self.title = self.organization_feature.feature_name
        if title_suffix:
            self.title += ' ' + title_suffix

        if reuse and self.try_reuse():
            return self.root
        emi = super().create_xml(add_as_part = False, originator = originator)

        if self.organization_feature is not None:
            of_root = self.organization_feature.root
            if of_root is not None:
                if organization_feature_root is None:
                    organization_feature_root = of_root
                else:
                    assert of_root is organization_feature_root, 'organization feature mismatch'

        assert organization_feature_root is not None, 'interpreted feature not established for model interpretation'

        assert self.domain in self.valid_domains, 'illegal domain value for earth model interpretation'
        dom_node = rqet.SubElement(emi, ns['resqml2'] + 'Domain')
        dom_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Domain')
        dom_node.text = self.domain

        self.model.create_ref_node('InterpretedFeature',
                                   self.model.title_for_root(organization_feature_root),
                                   organization_feature_root.attrib['uuid'],
                                   content_type = 'obj_OrganizationFeature',
                                   root = emi)

        create_xml_has_occurred_during(self.model, emi, self.has_occurred_during)

        if add_as_part:
            self.model.add_part('obj_EarthModelInterpretation', self.uuid, emi)
            if add_relationships:
                self.model.create_reciprocal_relationship(emi, 'destinationObject', organization_feature_root,
                                                          'sourceObject')

        return emi
Example #27
0
File: _utils.py Project: bp/resqpy
def create_xml_has_occurred_during(model, parent_node, hod_pair, tag = 'HasOccuredDuring'):
    """Creates XML sub-tree 'HasOccuredDuring' node"""
    if hod_pair is None:
        return
    base_chrono_uuid, top_chrono_uuid = hod_pair
    if base_chrono_uuid is None or top_chrono_uuid is None:
        return
    hod_node = rqet.SubElement(parent_node, tag)
    hod_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'TimeInterval')
    hod_node.text = rqet.null_xml_text
    chrono_base_root = model.root_for_uuid(base_chrono_uuid)
    chrono_top_root = model.root_for_uuid(top_chrono_uuid)
    model.create_ref_node('ChronoBottom', model.title_for_root(chrono_base_root), base_chrono_uuid, root = hod_node)
    model.create_ref_node('ChronoTop', model.title_for_root(chrono_top_root), top_chrono_uuid, root = hod_node)
Example #28
0
def _create_xml_property_kind(collection, p_node, find_local_property_kinds,
                              property_kind, uom, discrete,
                              property_kind_uuid):
    p_kind_node = rqet.SubElement(p_node, ns['resqml2'] + 'PropertyKind')
    p_kind_node.text = rqet.null_xml_text
    if find_local_property_kinds and property_kind not in supported_property_kind_list:
        property_kind_uuid = pcga._get_property_kind_uuid(
            collection, property_kind_uuid, property_kind, uom, discrete)

    if property_kind_uuid is None:
        p_kind_node.set(ns['xsi'] + 'type', ns['resqml2'] +
                        'StandardPropertyKind')  # todo: local prop kind ref
        kind_node = rqet.SubElement(p_kind_node, ns['resqml2'] + 'Kind')
        kind_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ResqmlPropertyKind')
        kind_node.text = property_kind
    else:
        p_kind_node.set(ns['xsi'] + 'type', ns['resqml2'] +
                        'LocalPropertyKind')  # todo: local prop kind ref
        collection.model.create_ref_node('LocalPropertyKind',
                                         property_kind,
                                         property_kind_uuid,
                                         content_type='obj_PropertyKind',
                                         root=p_kind_node)
Example #29
0
    def create_xml(self,
                   add_as_part=True,
                   add_relationships=True,
                   title=None,
                   originator=None):
        """Creates xml for a measured depth datum element; crs node must already exist; optionally adds as part.

        arguments:
           add_as_part (boolean, default True): if True, the newly created xml node is added as a part
              in the model
           add_relationships (boolean, default True): if True, a relationship xml part is created relating the
              new md datum part to the crs
           title (string): used as the citation Title text for the new md datum node
           originator (string, optional): the name of the human being who created the md datum part;
              default is to use the login name

        returns:
           the newly created measured depth datum xml node
        """

        md_reference = self.md_reference.lower()
        assert md_reference in valid_md_reference_list, 'invalid measured depth reference: ' + md_reference

        if title:
            self.title = title
        if not self.title:
            self.title = 'measured depth datum'

        crs_uuid = self.crs_uuid
        assert crs_uuid is not None

        datum = super().create_xml(add_as_part=False, originator=originator)

        self.model.create_solitary_point3d('Location', datum, self.location)

        md_ref = rqet.SubElement(datum, ns['resqml2'] + 'MdReference')
        md_ref.set(ns['xsi'] + 'type', ns['resqml2'] + 'MdReference')
        md_ref.text = md_reference

        self.model.create_crs_reference(crs_uuid=crs_uuid, root=datum)

        if add_as_part:
            self.model.add_part('obj_MdDatum', self.uuid, datum)
            if add_relationships:
                crs_root = self.model.root_for_uuid(self.crs_uuid)
                self.model.create_reciprocal_relationship(
                    datum, 'destinationObject', crs_root, 'sourceObject')

        return datum
Example #30
0
    def create_xml(self,
                   add_as_part=True,
                   add_relationships=True,
                   originator=None,
                   reuse=True):
        """Creates a rock fluid unit feature organisational xml node from this rock fluid unit feature object."""

        assert self.feature_name and self.phase and self.top_boundary_feature and self.base_boundary_feature
        if self.phase not in self.valid_phases:
            raise ValueError(f"Phase '{self.phase}' not recognized")

        if reuse and self.try_reuse():
            return self.root  # check for reusable (equivalent) object
        # create node with citation block
        rfuf = super().create_xml(add_as_part=False, originator=originator)

        phase_node = rqet.SubElement(rfuf, ns['resqml2'] + 'Phase')
        phase_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'Phase')
        phase_node.text = self.phase

        top_boundary_root = self.top_boundary_feature.root
        assert top_boundary_root is not None
        self.model.create_ref_node(
            'FluidBoundaryTop',
            self.model.title_for_root(top_boundary_root),
            top_boundary_root.attrib['uuid'],
            content_type='obj_BoundaryFeature',
            root=rfuf)

        base_boundary_root = self.base_boundary_feature.root
        assert base_boundary_root is not None
        self.model.create_ref_node(
            'FluidBoundaryBottom',
            self.model.title_for_root(base_boundary_root),
            base_boundary_root.attrib['uuid'],
            content_type='obj_BoundaryFeature',
            root=rfuf)

        if add_as_part:
            self.model.add_part('obj_RockFluidUnitFeature', self.uuid, rfuf)
            if add_relationships:
                self.model.create_reciprocal_relationship(
                    rfuf, 'destinationObject', top_boundary_root,
                    'sourceObject')
                self.model.create_reciprocal_relationship(
                    rfuf, 'destinationObject', base_boundary_root,
                    'sourceObject')

        return rfuf