Source code for resqpy.strata._stratigraphic_column

"""_stratigraphic_column.py: RESQML StratigraphicColumn class."""

# NB: in this module, the term 'unit' refers to a geological stratigraphic unit, i.e. a layer of rock, not a unit of measure

import logging

log = logging.getLogger(__name__)

import resqpy.olio.uuid as bu
import resqpy.olio.xml_et as rqet
import resqpy.organize as rqo
import resqpy.strata
import resqpy.strata._strata_common as rqstc
import resqpy.strata._stratigraphic_column_rank as rqscr
from resqpy.olio.base import BaseResqpy


class StratigraphicColumn(BaseResqpy):
    """Class for RESQML stratigraphic column objects.

    RESQML documentation:

       A global interpretation of the stratigraphy, which can be made up of
       several ranks of stratigraphic unit interpretations.

       All stratigraphic column rank interpretations that make up a stratigraphic column
       must be ordered by age.
    """

    resqml_type = 'StratigraphicColumn'

    # todo: integrate with EarthModelInterpretation class which can optionally refer to a stratigraphic column

[docs] def __init__(self, parent_model, uuid = None, rank_uuid_list = None, title = None, extra_metadata = None): """Initialises a Stratigraphic Column object. arguments: parent_model (model.Model): the model with which the new stratigraphic column will be associated uuid (uuid.UUID, optional): the uuid of an existing RESQML stratigraphic column from which this object will be initialised rank_uuid_list (list of uuid, optional): if not initialising for an existing stratigraphic column, the ranks can be established from this list of uuids for existing stratigraphic column ranks; ranks should be ordered from geologically oldest to youngest with increasing index values title (str, optional): the citation title of the new stratigraphic column; ignored if uuid is not None extra_metadata (dict, optional): extra metadata items for the new feature """ self.ranks = [] # list of Stratigraphic Column Rank Interpretation objects, maintained in rank index order super().__init__(model = parent_model, uuid = uuid, title = title, extra_metadata = extra_metadata) if self.root is None and rank_uuid_list: for rank_uuid in rank_uuid_list: rank = rqscr.StratigraphicColumnRank(self.model, uuid = rank_uuid) self.add_rank(rank)
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 = rqscr.StratigraphicColumnRank(self.model, uuid = rqet.find_tag_text(rank_node, 'UUID')) self.add_rank(rank)
[docs] def iter_ranks(self): """Yields the stratigraphic column ranks which constitute this stratigraphic colunn.""" for rank in self.ranks: yield rank
[docs] def add_rank(self, rank): """Adds another stratigraphic column rank to this stratigraphic column. arguments: rank (StratigraphicColumnRank): an established rank to be added to this stratigraphic column note: ranks should be ordered from geologically oldest to youngest, with increasing index values """ assert rank is not None and rank.index is not None self.ranks.append(rank) self._sort_ranks()
def _sort_ranks(self): """Sort the list of ranks, in situ, by their index values.""" self.ranks.sort(key = rqstc._index_attr)
[docs] def is_equivalent(self, other, check_extra_metadata = True): """Returns True if this interpretation is essentially the same as the other; otherwise False. arguments: other (StratigraphicColumn): the other stratigraphic column to compare this one against check_extra_metadata (bool, default True): if True, then extra metadata items must match for the two columns to be deemed equivalent; if False, extra metadata is ignored in the comparison returns: bool: True if this stratigraphic column is essentially the same as the other; False otherwise """ if not isinstance(other, StratigraphicColumn): return False if self is other or bu.matching_uuids(self.uuid, other.uuid): return True if len(self.ranks) != len(other.ranks): return False for rank_a, rank_b in zip(self.ranks, other.ranks): if rank_a != rank_b: return False if check_extra_metadata and not rqo.equivalent_extra_metadata(self, other): return False return True
[docs] def create_xml(self, add_as_part = True, add_relationships = True, originator = None, reuse = True): """Creates xml tree for a stratigraphic column object. arguments: add_as_part (bool, default True): if True, the stratigraphic column 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 each of the referenced stratigraphic column rank interpretations 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 stratigraphic column and, if found, the uuid of this stratigraphic column is set to that of the equivalent part returns: lxml.etree._Element: the root node of the newly created xml tree for the stratigraphic column """ assert self.ranks, 'attempt to create xml for stratigraphic column without any contributing ranks' if reuse and self.try_reuse(): return self.root sci = super().create_xml(add_as_part = False, originator = originator) assert sci is not None for rank in self.ranks: self.model.create_ref_node('Ranks', rank.title, rank.uuid, content_type = 'obj_StratigraphicColumnRankInterpretation', root = sci) if add_as_part: self.model.add_part('obj_StratigraphicColumn', self.uuid, sci) if add_relationships: for rank in self.ranks: self.model.create_reciprocal_relationship(sci, 'destinationObject', rank.root, 'sourceObject') return sci