Skip to content

AF

momapy.sbgn.af

SBGN Activity Flow (AF) subpackage facade.

Layout-model mapping catalogue

This section lists, for each model-element category in SBGN-AF, the shape of the corresponding key in LayoutModelMapping. See LayoutModelMapping for the general concepts (singleton keys, frozenset keys, representatives).

Singleton keys (one layout element represents the model element):

Model element Layout element used as the key
Compartment CompartmentLayout
BiologicalActivity BiologicalActivityLayout
Phenotype PhenotypeLayout
UnitOfInformation and subclasses (e.g. MacromoleculeUnitOfInformation, NucleicAcidFeatureUnitOfInformation, SimpleChemicalUnitOfInformation, ComplexUnitOfInformation, UnspecifiedEntityUnitOfInformation, PerturbationUnitOfInformation) The corresponding *UnitOfInformationLayout (e.g. MacromoleculeUnitOfInformationLayout, PerturbationUnitOfInformationLayout)
Submap SubmapLayout
LogicalOperatorInput LogicArcLayout
TagReference, TerminalReference EquivalenceArcLayout

Frozenset keys (a cluster of layout elements jointly represents the model element; the representative is the layout that stands for the cluster on its own and must be passed as representative= when calling add_mapping):

Model element Members of the frozenset key Representative
LogicalOperator and subclasses (e.g. AndOperator, OrOperator, NotOperator, DelayOperator) The operator *Layout (e.g. AndOperatorLayout, DelayOperatorLayout) + every LogicArcLayout input + every target layout those logic arcs point to The operator *Layout
Influence and subclasses (e.g. UnknownInfluence, PositiveInfluence, NegativeInfluence, NecessaryStimulation) The influence arc layout (e.g. UnknownInfluenceLayout, PositiveInfluenceLayout, NecessaryStimulationLayout) + all layouts in the source cluster (resolved via the source's own frozenset key if it has one, else the source layout itself) + all layouts in the target cluster (resolved the same way) The influence arc layout
Tag or Terminal carrying TagReference or TerminalReference arcs The TagLayout or TerminalLayout + every EquivalenceArcLayout reference arc + every referenced activity layout The TagLayout or TerminalLayout

Standalone Tag and Terminal instances (with no reference arcs) use a singleton key: TagLayout or TerminalLayout.

Modules:

Name Description
layout

Layout classes for SBGN Activity Flow (AF) maps.

map

Map classes for SBGN Activity Flow (AF) maps.

model

Model classes for SBGN Activity Flow (AF) maps.

Classes:

Name Description
Activity

Abstract base class for activities.

AndOperator

AND operator.

AndOperatorLayout

AND operator layout.

BiologicalActivity

Biological activity.

BiologicalActivityLayout

Biological activity layout.

Compartment

Compartment.

CompartmentLayout

Compartment layout.

ComplexUnitOfInformation

Complex unit of information.

ComplexUnitOfInformationLayout

Complex unit of information layout.

DelayOperator

Delay operator.

DelayOperatorLayout

Delay operator layout.

EquivalenceArcLayout

Equivalence arc layout.

Influence

Abstract base class for influences.

LogicArcLayout

Logic arc layout.

LogicalOperator

Abstract base class for logical operators.

LogicalOperatorInput

Logical operator input.

MacromoleculeUnitOfInformation

Macromolecule unit of information.

MacromoleculeUnitOfInformationLayout

Macromolecule unit of information layout.

NecessaryStimulation

Necessary stimulation.

NecessaryStimulationLayout

Necessary stimulation layout.

NegativeInfluence

Negative influence.

NegativeInfluenceLayout

Negative influence layout.

NotOperator

NOT operator.

NotOperatorLayout

NOT operator layout.

NucleicAcidFeatureUnitOfInformation

Nucleic acid feature unit of information.

NucleicAcidFeatureUnitOfInformationLayout

Nucleic acid feature unit of information layout.

OrOperator

OR operator.

OrOperatorLayout

OR operator layout.

PerturbationUnitOfInformation

Perturbation unit of information.

PerturbationUnitOfInformationLayout

Perturbation unit of information layout.

Phenotype

Phenotype.

PhenotypeLayout

Phenotype layout.

PositiveInfluence

Positive influence.

PositiveInfluenceLayout

Positive influence layout.

SBGNAFLayout

SBGN AF layout.

SBGNAFMap

Class for SBGN-AF maps.

SBGNAFModel

SBGN AF model.

SimpleChemicalUnitOfInformation

Simple chemical unit of information.

SimpleChemicalUnitOfInformationLayout

Simple chemical unit of information layout.

Submap

Submap.

SubmapLayout

Submap layout.

Tag

Tag.

TagLayout

Tag layout.

TagReference

Tag reference.

Terminal

Terminal.

TerminalLayout

Terminal layout.

TerminalReference

Terminal reference.

UnitOfInformation

Abstract base class for units of information.

UnitOfInformationLayout

Unit of information layout.

UnknownInfluence

Unknown influence.

UnknownInfluenceLayout

Unknown influence layout.

UnspecifiedEntityUnitOfInformation

Unspecified entity unit of information.

UnspecifiedEntityUnitOfInformationLayout

Unspecified entity unit of information layout.

Activity dataclass

Activity(*, id_: str = make_uuid4_as_str(), label: str | None = None, compartment: Compartment | None = None)

Bases: SBGNModelElement

Abstract base class for activities.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'affcf585-ab9d-4578-a1a5-f8838e3135d7'
label str | None

The label of the activity.

None
compartment Compartment | None

The compartment containing this activity.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

AndOperator dataclass

AndOperator(*, id_: str = make_uuid4_as_str(), inputs: frozenset[LogicalOperatorInput] = frozenset())

Bases: LogicalOperator

AND operator.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'70608251-0384-49d5-a6e4-2015dbd5c475'
inputs frozenset[LogicalOperatorInput]

Input connections to the logical operator.

<dynamic>

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

AndOperatorLayout dataclass

AndOperatorLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 30.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 30.0, text: str = 'AND', font_family: str = DEFAULT_FONT_FAMILY, font_fill: Color | NoneValueType = black, font_stroke: Color | NoneValueType = NoneValue, font_style: FontStyle = NORMAL, font_weight: FontWeight | float = NORMAL, orientation: Orientation = HORIZONTAL, left_to_right: bool = True, left_connector_length: float = 10.0, right_connector_length: float = 10.0, left_connector_stroke: NoneValueType | Color | None = None, left_connector_stroke_width: float | None = None, left_connector_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, left_connector_stroke_dashoffset: float | None = None, left_connector_fill: NoneValueType | Color | None = None, left_connector_transform: NoneValueType | tuple[Transformation, ...] | None = None, left_connector_filter: NoneValueType | Filter | None = None, right_connector_stroke: NoneValueType | Color | None = None, right_connector_stroke_width: float | None = None, right_connector_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, right_connector_stroke_dashoffset: float | None = None, right_connector_fill: NoneValueType | Color | None = None, right_connector_transform: NoneValueType | tuple[Transformation, ...] | None = None, right_connector_filter: NoneValueType | Filter | None = None)

Bases: _ConnectorsMixin, _SimpleMixin, _TextMixin, SBGNNode

AND operator layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'a772eaa9-a46b-4be6-80ab-b7997f26c2cb'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

30.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

30.0
text str

The text displayed inside the node.

'AND'
font_family str

Font family for the text.

'DejaVu Sans'
font_fill Color | NoneValueType

Fill color for the text.

Color(red=0, green=0, blue=0, alpha=1.0)
font_stroke Color | NoneValueType

Stroke color for the text outline.

<momapy.drawing.NoneValueType object at 0x7fb1b7eb96a0>
font_style FontStyle

Font style (normal, italic, etc.).

<FontStyle.NORMAL: 0>
font_weight FontWeight | float

Font weight (normal, bold, etc.).

<FontWeight.NORMAL: 0>
orientation Orientation

Orientation of connectors (HORIZONTAL or VERTICAL).

<Orientation.HORIZONTAL: 1>
left_to_right bool

Whether connectors flow left to right.

True
left_connector_length float

Length of the left connector.

10.0
right_connector_length float

Length of the right connector.

10.0
left_connector_stroke NoneValueType | Color | None

Stroke color for the left connector line.

None
left_connector_stroke_width float | None

Stroke width for the left connector line.

None
left_connector_stroke_dasharray NoneValueType | tuple[float, ...] | None

Dash pattern for the left connector line.

None
left_connector_stroke_dashoffset float | None

Dash offset for the left connector line.

None
left_connector_fill NoneValueType | Color | None

Fill color for the left connector.

None
left_connector_transform NoneValueType | tuple[Transformation, ...] | None

Transformations applied to the left connector.

None
left_connector_filter NoneValueType | Filter | None

Filter applied to the left connector.

None
right_connector_stroke NoneValueType | Color | None

Stroke color for the right connector line.

None
right_connector_stroke_width float | None

Stroke width for the right connector line.

None
right_connector_stroke_dasharray NoneValueType | tuple[float, ...] | None

Dash pattern for the right connector line.

None
right_connector_stroke_dashoffset float | None

Dash offset for the right connector line.

None
right_connector_fill NoneValueType | Color | None

Fill color for the right connector.

None
right_connector_transform NoneValueType | tuple[Transformation, ...] | None

Transformations applied to the right connector.

None
right_connector_filter NoneValueType | Filter | None

Filter applied to the right connector.

None

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Get the east (right) anchor point.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

left_connector_base

Get the base point of the left connector.

left_connector_tip

Get the tip point of the left connector.

north

Get the north (top) anchor point.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

right_connector_base

Get the base point of the right connector.

right_connector_tip

Get the tip point of the right connector.

size

Return the size of the node.

south

Get the south (bottom) anchor point.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Get the west (left) anchor point.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Get the east (right) anchor point.

Returns:

Type Description
Point

Point on the east side of the element.

Source code in src/momapy/sbgn/elements.py
def east(self) -> Point:
    """Get the east (right) anchor point.

    Returns:
        Point on the east side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x + self.width / 2, self.y)
    else:
        return Point(self.x + self.width / 2 + self.right_connector_length, self.y)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

left_connector_base

left_connector_base() -> Point

Get the base point of the left connector.

Returns:

Type Description
Point

Point where the left connector attaches to the shape.

Source code in src/momapy/sbgn/elements.py
def left_connector_base(self) -> Point:
    """Get the base point of the left connector.

    Returns:
        Point where the left connector attaches to the shape.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2)
    else:
        return Point(self.x - self.width / 2, self.y)

left_connector_tip

left_connector_tip() -> Point

Get the tip point of the left connector.

Returns:

Type Description
Point

Point at the end of the left connector line.

Source code in src/momapy/sbgn/elements.py
def left_connector_tip(self) -> Point:
    """Get the tip point of the left connector.

    Returns:
        Point at the end of the left connector line.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2 - self.left_connector_length)
    else:
        return Point(self.x - self.width / 2 - self.left_connector_length, self.y)

north

north() -> Point

Get the north (top) anchor point.

Returns:

Type Description
Point

Point on the north side of the element.

Source code in src/momapy/sbgn/elements.py
def north(self) -> Point:
    """Get the north (top) anchor point.

    Returns:
        Point on the north side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2 - self.left_connector_length)
    else:
        return Point(self.x, self.y - self.height / 2)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

right_connector_base

right_connector_base() -> Point

Get the base point of the right connector.

Returns:

Type Description
Point

Point where the right connector attaches to the shape.

Source code in src/momapy/sbgn/elements.py
def right_connector_base(self) -> Point:
    """Get the base point of the right connector.

    Returns:
        Point where the right connector attaches to the shape.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2)
    else:
        return Point(self.x + self.width / 2, self.y)

right_connector_tip

right_connector_tip() -> Point

Get the tip point of the right connector.

Returns:

Type Description
Point

Point at the end of the right connector line.

Source code in src/momapy/sbgn/elements.py
def right_connector_tip(self) -> Point:
    """Get the tip point of the right connector.

    Returns:
        Point at the end of the right connector line.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2 + self.right_connector_length)
    else:
        return Point(self.x + self.width / 2 + self.right_connector_length, self.y)

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Get the south (bottom) anchor point.

Returns:

Type Description
Point

Point on the south side of the element.

Source code in src/momapy/sbgn/elements.py
def south(self) -> Point:
    """Get the south (bottom) anchor point.

    Returns:
        Point on the south side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2 + self.right_connector_length)
    else:
        return Point(self.x, self.y + self.height / 2)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Get the west (left) anchor point.

Returns:

Type Description
Point

Point on the west side of the element.

Source code in src/momapy/sbgn/elements.py
def west(self) -> Point:
    """Get the west (left) anchor point.

    Returns:
        Point on the west side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x - self.width / 2, self.y)
    else:
        return Point(self.x - self.width / 2 - self.left_connector_length, self.y)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

BiologicalActivity dataclass

BiologicalActivity(*, id_: str = make_uuid4_as_str(), label: str | None = None, compartment: Compartment | None = None, units_of_information: frozenset[UnitOfInformation] = frozenset())

Bases: Activity

Biological activity.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'6f5511ab-659e-4d87-b5ff-c2fe52a86aa9'
label str | None

The label of the activity.

None
compartment Compartment | None

The compartment containing this activity.

None
units_of_information frozenset[UnitOfInformation]

Units of information for the activity.

<dynamic>

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

BiologicalActivityLayout dataclass

BiologicalActivityLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 30.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 60.0)

Bases: _SimpleMixin, SBGNNode

Biological activity layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'851fe1bf-0af6-47bf-a347-55d5391cc243'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

30.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

60.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

Compartment dataclass

Compartment(*, id_: str = make_uuid4_as_str(), label: str | None = None, units_of_information: frozenset[UnitOfInformation] = frozenset())

Bases: SBGNModelElement

Compartment.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'17098f40-ea41-4882-b09b-2acb9bd990d7'
label str | None

The label of the compartment.

None
units_of_information frozenset[UnitOfInformation]

The units of information of the compartment.

<dynamic>

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

CompartmentLayout dataclass

CompartmentLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 80.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float = 3.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 80.0, rounded_corners: float = 5.0)

Bases: _SimpleMixin, SBGNNode

Compartment layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'5d5294d1-9a67-4fb6-b5f6-0918f22fa61f'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

80.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float

The stroke width of the node

3.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

80.0
rounded_corners float

The radius of the rounded corners.

5.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

ComplexUnitOfInformation dataclass

ComplexUnitOfInformation(*, id_: str = make_uuid4_as_str(), label: str | None = None)

Bases: UnitOfInformation

Complex unit of information.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'165f0bad-01c0-4b50-bec1-0bd0fe20eac6'
label str | None

The label of the unit of information.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

ComplexUnitOfInformationLayout dataclass

ComplexUnitOfInformationLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 12.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 18.0, cut_corners: float = 3.0)

Bases: _SimpleMixin, SBGNNode

Complex unit of information layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'23d8ea7c-a46a-4be1-9449-13533196d47c'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

12.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

18.0
cut_corners float

The size of the cut corners.

3.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

DelayOperator dataclass

DelayOperator(*, id_: str = make_uuid4_as_str(), inputs: frozenset[LogicalOperatorInput] = frozenset())

Bases: LogicalOperator

Delay operator.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'c4611012-9ad7-4822-b57e-75dffda9a232'
inputs frozenset[LogicalOperatorInput]

Input connections to the logical operator.

<dynamic>

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

DelayOperatorLayout dataclass

DelayOperatorLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 30.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 30.0, text: str = 'τ', font_family: str = DEFAULT_FONT_FAMILY, font_fill: Color | NoneValueType = black, font_stroke: Color | NoneValueType = NoneValue, font_style: FontStyle = NORMAL, font_weight: FontWeight | float = NORMAL, orientation: Orientation = HORIZONTAL, left_to_right: bool = True, left_connector_length: float = 10.0, right_connector_length: float = 10.0, left_connector_stroke: NoneValueType | Color | None = None, left_connector_stroke_width: float | None = None, left_connector_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, left_connector_stroke_dashoffset: float | None = None, left_connector_fill: NoneValueType | Color | None = None, left_connector_transform: NoneValueType | tuple[Transformation, ...] | None = None, left_connector_filter: NoneValueType | Filter | None = None, right_connector_stroke: NoneValueType | Color | None = None, right_connector_stroke_width: float | None = None, right_connector_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, right_connector_stroke_dashoffset: float | None = None, right_connector_fill: NoneValueType | Color | None = None, right_connector_transform: NoneValueType | tuple[Transformation, ...] | None = None, right_connector_filter: NoneValueType | Filter | None = None)

Bases: _ConnectorsMixin, _SimpleMixin, _TextMixin, SBGNNode

Delay operator layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'c8ccad63-098c-41e3-96d7-e85a87d7195d'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

30.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

30.0
text str

The text displayed inside the node.

'τ'
font_family str

Font family for the text.

'DejaVu Sans'
font_fill Color | NoneValueType

Fill color for the text.

Color(red=0, green=0, blue=0, alpha=1.0)
font_stroke Color | NoneValueType

Stroke color for the text outline.

<momapy.drawing.NoneValueType object at 0x7fb1b7eb96a0>
font_style FontStyle

Font style (normal, italic, etc.).

<FontStyle.NORMAL: 0>
font_weight FontWeight | float

Font weight (normal, bold, etc.).

<FontWeight.NORMAL: 0>
orientation Orientation

Orientation of connectors (HORIZONTAL or VERTICAL).

<Orientation.HORIZONTAL: 1>
left_to_right bool

Whether connectors flow left to right.

True
left_connector_length float

Length of the left connector.

10.0
right_connector_length float

Length of the right connector.

10.0
left_connector_stroke NoneValueType | Color | None

Stroke color for the left connector line.

None
left_connector_stroke_width float | None

Stroke width for the left connector line.

None
left_connector_stroke_dasharray NoneValueType | tuple[float, ...] | None

Dash pattern for the left connector line.

None
left_connector_stroke_dashoffset float | None

Dash offset for the left connector line.

None
left_connector_fill NoneValueType | Color | None

Fill color for the left connector.

None
left_connector_transform NoneValueType | tuple[Transformation, ...] | None

Transformations applied to the left connector.

None
left_connector_filter NoneValueType | Filter | None

Filter applied to the left connector.

None
right_connector_stroke NoneValueType | Color | None

Stroke color for the right connector line.

None
right_connector_stroke_width float | None

Stroke width for the right connector line.

None
right_connector_stroke_dasharray NoneValueType | tuple[float, ...] | None

Dash pattern for the right connector line.

None
right_connector_stroke_dashoffset float | None

Dash offset for the right connector line.

None
right_connector_fill NoneValueType | Color | None

Fill color for the right connector.

None
right_connector_transform NoneValueType | tuple[Transformation, ...] | None

Transformations applied to the right connector.

None
right_connector_filter NoneValueType | Filter | None

Filter applied to the right connector.

None

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Get the east (right) anchor point.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

left_connector_base

Get the base point of the left connector.

left_connector_tip

Get the tip point of the left connector.

north

Get the north (top) anchor point.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

right_connector_base

Get the base point of the right connector.

right_connector_tip

Get the tip point of the right connector.

size

Return the size of the node.

south

Get the south (bottom) anchor point.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Get the west (left) anchor point.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Get the east (right) anchor point.

Returns:

Type Description
Point

Point on the east side of the element.

Source code in src/momapy/sbgn/elements.py
def east(self) -> Point:
    """Get the east (right) anchor point.

    Returns:
        Point on the east side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x + self.width / 2, self.y)
    else:
        return Point(self.x + self.width / 2 + self.right_connector_length, self.y)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

left_connector_base

left_connector_base() -> Point

Get the base point of the left connector.

Returns:

Type Description
Point

Point where the left connector attaches to the shape.

Source code in src/momapy/sbgn/elements.py
def left_connector_base(self) -> Point:
    """Get the base point of the left connector.

    Returns:
        Point where the left connector attaches to the shape.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2)
    else:
        return Point(self.x - self.width / 2, self.y)

left_connector_tip

left_connector_tip() -> Point

Get the tip point of the left connector.

Returns:

Type Description
Point

Point at the end of the left connector line.

Source code in src/momapy/sbgn/elements.py
def left_connector_tip(self) -> Point:
    """Get the tip point of the left connector.

    Returns:
        Point at the end of the left connector line.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2 - self.left_connector_length)
    else:
        return Point(self.x - self.width / 2 - self.left_connector_length, self.y)

north

north() -> Point

Get the north (top) anchor point.

Returns:

Type Description
Point

Point on the north side of the element.

Source code in src/momapy/sbgn/elements.py
def north(self) -> Point:
    """Get the north (top) anchor point.

    Returns:
        Point on the north side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2 - self.left_connector_length)
    else:
        return Point(self.x, self.y - self.height / 2)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

right_connector_base

right_connector_base() -> Point

Get the base point of the right connector.

Returns:

Type Description
Point

Point where the right connector attaches to the shape.

Source code in src/momapy/sbgn/elements.py
def right_connector_base(self) -> Point:
    """Get the base point of the right connector.

    Returns:
        Point where the right connector attaches to the shape.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2)
    else:
        return Point(self.x + self.width / 2, self.y)

right_connector_tip

right_connector_tip() -> Point

Get the tip point of the right connector.

Returns:

Type Description
Point

Point at the end of the right connector line.

Source code in src/momapy/sbgn/elements.py
def right_connector_tip(self) -> Point:
    """Get the tip point of the right connector.

    Returns:
        Point at the end of the right connector line.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2 + self.right_connector_length)
    else:
        return Point(self.x + self.width / 2 + self.right_connector_length, self.y)

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Get the south (bottom) anchor point.

Returns:

Type Description
Point

Point on the south side of the element.

Source code in src/momapy/sbgn/elements.py
def south(self) -> Point:
    """Get the south (bottom) anchor point.

    Returns:
        Point on the south side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2 + self.right_connector_length)
    else:
        return Point(self.x, self.y + self.height / 2)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Get the west (left) anchor point.

Returns:

Type Description
Point

Point on the west side of the element.

Source code in src/momapy/sbgn/elements.py
def west(self) -> Point:
    """Get the west (left) anchor point.

    Returns:
        Point on the west side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x - self.width / 2, self.y)
    else:
        return Point(self.x - self.width / 2 - self.left_connector_length, self.y)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

EquivalenceArcLayout dataclass

EquivalenceArcLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, end_shorten: float = 0.0, fill: NoneValueType | Color | None = None, filter_: NoneValueType | Filter | None = None, path_fill: NoneValueType | Color | None = NoneValue, path_filter: NoneValueType | Filter | None = None, path_stroke: NoneValueType | Color | None = black, path_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, path_stroke_dashoffset: NoneValueType | float | None = None, path_stroke_width: float | None = 1.25, path_transform: NoneValueType | tuple[Transformation, ...] | None = None, stroke: NoneValueType | Color | None = None, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: NoneValueType | float | None = None, segments: tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...] = tuple(), source: LayoutElement | None = None, start_shorten: float = 0.0, target: LayoutElement | None = None, transform: NoneValueType | tuple[Transformation, ...] | None = None, arrowhead_fill: NoneValueType | Color | None = white, arrowhead_filter: NoneValueType | Filter | None = None, arrowhead_stroke: NoneValueType | Color | None = black, arrowhead_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, arrowhead_stroke_dashoffset: NoneValueType | float | None = None, arrowhead_stroke_width: float | None = 1.25, arrowhead_transform: NoneValueType | tuple[Transformation, ...] | None = None)

Bases: SBGNSingleHeadedArc

Equivalence arc layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'3685e9f1-c551-4104-bfa3-0bdb082dec32'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
end_shorten float

The length the end of the arc will be shorten by

0.0
fill NoneValueType | Color | None

The fill color of the arc

None
filter_ NoneValueType | Filter | None

The filter of the arc

None
path_fill NoneValueType | Color | None

The path fill color of the arc

<momapy.drawing.NoneValueType object at 0x7fb1b7eb96a0>
path_filter NoneValueType | Filter | None

The path filter of the arc

None
path_stroke NoneValueType | Color | None

The path stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
path_stroke_dasharray NoneValueType | tuple[float, ...] | None

The path stroke dasharray of the arc

None
path_stroke_dashoffset NoneValueType | float | None

The path stroke dashoffset of the arc

None
path_stroke_width float | None

The path stroke width of the arc

1.25
path_transform NoneValueType | tuple[Transformation, ...] | None

The path transform of the arc

None
stroke NoneValueType | Color | None

The stroke color of the arc

None
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the arc

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the arc

None
stroke_width NoneValueType | float | None

The stroke width of the arc

None
segments tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...]

The path segments of the arc

<dynamic>
source LayoutElement | None

The source of the arc

None
start_shorten float

The length the start of the arc will be shorten by

0.0
target LayoutElement | None

The target of the arc

None
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the arc

None
arrowhead_fill NoneValueType | Color | None

The arrowhead fill color of the arc

Color(red=255, green=255, blue=255, alpha=1.0)
arrowhead_filter NoneValueType | Filter | None

The arrowhead filter of the arc

None
arrowhead_stroke NoneValueType | Color | None

The arrowhead stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
arrowhead_stroke_dasharray NoneValueType | tuple[float, ...] | None

The arrowhead stroke dasharray of the arc

None
arrowhead_stroke_dashoffset NoneValueType | float | None

The arrowhead stroke dashoffset of the arc

None
arrowhead_stroke_width float | None

The arrowhead stroke width of the arc

1.25
arrowhead_transform NoneValueType | tuple[Transformation, ...] | None

The arrowhead transform of the arc

None

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

arrowhead_base

Return the arrowhead base anchor point of the single-headed arc.

arrowhead_bbox

Return the bounding box of the single-headed arc arrowhead.

arrowhead_border

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

arrowhead_drawing_elements

Return the drawing elements of the single-headed arc arrowhead.

arrowhead_length

Return the length of the single-headed arc arrowhead.

arrowhead_tip

Return the arrowhead tip anchor point of the single-headed arc.

bbox

Compute and return the bounding box of the group layout element.

childless

Return a copy of the arc with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

end_point

Return the ending point of the arc.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

fraction

Return the position and angle on the arc at a given fraction (of the total arc length).

length

Return the total length of the arc path.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_children

Return the self children of the arc.

own_drawing_elements

Return the self drawing elements of the single-headed arc.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

path_drawing_elements

Return the drawing elements of the single-headed arc path.

points

Return the points of the arc path.

start_point

Return the starting point of the arc.

to_geometry

Return a list of geometry primitives from the drawing elements.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

arrowhead_base

arrowhead_base() -> Point

Return the arrowhead base anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_base(self) -> Point:
    """Return the arrowhead base anchor point of the single-headed arc."""
    arrowhead_length = self.arrowhead_length()
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return self.arrowhead_tip() - (arrowhead_length, 0)
    fraction = 1 - (arrowhead_length + self.end_shorten) / segment_length
    return segment.get_position_at_fraction(fraction)

arrowhead_bbox

arrowhead_bbox() -> Bbox

Return the bounding box of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_bbox(self) -> Bbox:
    """Return the bounding box of the single-headed arc arrowhead."""
    return get_drawing_elements_bbox(self.arrowhead_drawing_elements())

arrowhead_border

arrowhead_border(point: Point) -> Point

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def arrowhead_border(self, point: Point) -> Point:
    """Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    point = get_drawing_elements_border(self.arrowhead_drawing_elements(), point)
    if point is None:
        return self.arrowhead_tip()
    return point

arrowhead_drawing_elements

arrowhead_drawing_elements() -> list[DrawingElement]

Return the drawing elements of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_drawing_elements(
    self,
) -> list[DrawingElement]:
    """Return the drawing elements of the single-headed arc arrowhead."""
    drawing_elements = self._arrowhead_border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_arrowhead",
        elements=tuple(drawing_elements),
        fill=self.arrowhead_fill,
        filter_=self.arrowhead_filter,
        id_=f"{self.id_}_arrowhead",
        stroke=self.arrowhead_stroke,
        stroke_dasharray=self.arrowhead_stroke_dasharray,
        stroke_dashoffset=self.arrowhead_stroke_dashoffset,
        stroke_width=self.arrowhead_stroke_width,
        transform=self.arrowhead_transform,
    )
    transformation = self._get_arrowhead_transformation()
    group = group.transformed(transformation)
    return [group]

arrowhead_length

arrowhead_length() -> float

Return the length of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_length(self) -> float:
    """Return the length of the single-headed arc arrowhead."""
    bbox = get_drawing_elements_bbox(self._arrowhead_border_drawing_elements())
    if math.isnan(bbox.width):
        return 0.0
    return bbox.east().x

arrowhead_tip

arrowhead_tip() -> Point

Return the arrowhead tip anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_tip(self) -> Point:
    """Return the arrowhead tip anchor point of the single-headed arc."""
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return segment.p2
    fraction = 1 - self.end_shorten / segment_length
    return segment.get_position_at_fraction(fraction)

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

childless

childless() -> Self

Return a copy of the arc with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the arc with no children."""
    return dataclasses.replace(self, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

end_point

end_point() -> Point

Return the ending point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def end_point(self) -> Point:
    """Return the ending point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[-1]

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

fraction

fraction(fraction: float) -> tuple[Point, float]

Return the position and angle on the arc at a given fraction (of the total arc length).

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def fraction(self, fraction: float) -> tuple[Point, float]:
    """Return the position and angle on the arc at a given fraction (of the total arc length).

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    current_length = 0
    length_to_reach = fraction * self.length()
    for segment in self.segments:
        current_length += segment.length()
        if current_length >= length_to_reach:
            break
    segment_start_length = current_length - segment.length()
    segment_fraction = (length_to_reach - segment_start_length) / segment.length()
    position, angle = segment.get_position_and_angle_at_fraction(segment_fraction)
    return position, angle

length

length() -> float

Return the total length of the arc path.

Source code in src/momapy/core/layout.py
def length(self) -> float:
    """Return the total length of the arc path."""
    return sum([segment.length() for segment in self.segments])

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_children

own_children() -> list[LayoutElement]

Return the self children of the arc.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the arc."""
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the self drawing elements of the single-headed arc.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the self drawing elements of the single-headed arc."""
    drawing_elements = (
        self.path_drawing_elements() + self.arrowhead_drawing_elements()
    )
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

path_drawing_elements

path_drawing_elements() -> list[Path]

Return the drawing elements of the single-headed arc path.

Source code in src/momapy/core/layout.py
def path_drawing_elements(self) -> list[Path]:
    """Return the drawing elements of the single-headed arc path."""
    arrowhead_length = self.arrowhead_length()
    if len(self.segments) == 1:
        segment = (
            self.segments[0]
            .shortened(self.start_shorten, "start")
            .shortened(self.end_shorten + arrowhead_length, "end")
        )
        actions = [
            MoveTo(segment.p1),
            self._make_path_action_from_segment(segment),
        ]
    else:
        first_segment = self.segments[0].shortened(self.start_shorten, "start")
        last_segment = self.segments[-1].shortened(
            self.end_shorten + arrowhead_length, "end"
        )
        actions = [
            MoveTo(first_segment.p1),
            self._make_path_action_from_segment(first_segment),
        ]
        for segment in self.segments[1:-1]:
            action = self._make_path_action_from_segment(segment)
            actions.append(action)
        actions.append(self._make_path_action_from_segment(last_segment))
    path = Path(
        actions=tuple(actions),
        class_=f"{type(self).__name__}_path",
        fill=self.path_fill,
        filter_=self.path_filter,
        id_=f"{self.id_}_path",
        stroke=self.path_stroke,
        stroke_dasharray=self.path_stroke_dasharray,
        stroke_dashoffset=self.path_stroke_dashoffset,
        stroke_width=self.path_stroke_width,
        transform=self.path_transform,
    )
    return [path]

points

points() -> list[Point]

Return the points of the arc path.

An arc with no segments has no points and returns an empty list.

Source code in src/momapy/core/layout.py
def points(self) -> list[Point]:
    """Return the points of the arc path.

    An arc with no segments has no points and returns an empty list.
    """
    if not self.segments:
        return []
    points = []
    for segment in self.segments:
        points.append(segment.p1)
    points.append(segment.p2)
    return points

start_point

start_point() -> Point

Return the starting point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def start_point(self) -> Point:
    """Return the starting point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[0]

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

Influence dataclass

Influence(*, id_: str = make_uuid4_as_str(), source: BiologicalActivity | LogicalOperator, target: Activity)

Bases: SBGNModelElement

Abstract base class for influences.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'ae492ebb-e29c-4d14-b414-d1aa9389d173'
source BiologicalActivity | LogicalOperator

The source activity or logical operator.

required
target Activity

The target activity being influenced.

required

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

LogicArcLayout dataclass

LogicArcLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, end_shorten: float = 0.0, fill: NoneValueType | Color | None = None, filter_: NoneValueType | Filter | None = None, path_fill: NoneValueType | Color | None = NoneValue, path_filter: NoneValueType | Filter | None = None, path_stroke: NoneValueType | Color | None = black, path_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, path_stroke_dashoffset: NoneValueType | float | None = None, path_stroke_width: float | None = 1.25, path_transform: NoneValueType | tuple[Transformation, ...] | None = None, stroke: NoneValueType | Color | None = None, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: NoneValueType | float | None = None, segments: tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...] = tuple(), source: LayoutElement | None = None, start_shorten: float = 0.0, target: LayoutElement | None = None, transform: NoneValueType | tuple[Transformation, ...] | None = None, arrowhead_fill: NoneValueType | Color | None = white, arrowhead_filter: NoneValueType | Filter | None = None, arrowhead_stroke: NoneValueType | Color | None = black, arrowhead_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, arrowhead_stroke_dashoffset: NoneValueType | float | None = None, arrowhead_stroke_width: float | None = 1.25, arrowhead_transform: NoneValueType | tuple[Transformation, ...] | None = None)

Bases: SBGNSingleHeadedArc

Logic arc layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'76c2c073-4d72-45ab-b71a-aa56673c9700'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
end_shorten float

The length the end of the arc will be shorten by

0.0
fill NoneValueType | Color | None

The fill color of the arc

None
filter_ NoneValueType | Filter | None

The filter of the arc

None
path_fill NoneValueType | Color | None

The path fill color of the arc

<momapy.drawing.NoneValueType object at 0x7fb1b7eb96a0>
path_filter NoneValueType | Filter | None

The path filter of the arc

None
path_stroke NoneValueType | Color | None

The path stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
path_stroke_dasharray NoneValueType | tuple[float, ...] | None

The path stroke dasharray of the arc

None
path_stroke_dashoffset NoneValueType | float | None

The path stroke dashoffset of the arc

None
path_stroke_width float | None

The path stroke width of the arc

1.25
path_transform NoneValueType | tuple[Transformation, ...] | None

The path transform of the arc

None
stroke NoneValueType | Color | None

The stroke color of the arc

None
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the arc

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the arc

None
stroke_width NoneValueType | float | None

The stroke width of the arc

None
segments tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...]

The path segments of the arc

<dynamic>
source LayoutElement | None

The source of the arc

None
start_shorten float

The length the start of the arc will be shorten by

0.0
target LayoutElement | None

The target of the arc

None
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the arc

None
arrowhead_fill NoneValueType | Color | None

The arrowhead fill color of the arc

Color(red=255, green=255, blue=255, alpha=1.0)
arrowhead_filter NoneValueType | Filter | None

The arrowhead filter of the arc

None
arrowhead_stroke NoneValueType | Color | None

The arrowhead stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
arrowhead_stroke_dasharray NoneValueType | tuple[float, ...] | None

The arrowhead stroke dasharray of the arc

None
arrowhead_stroke_dashoffset NoneValueType | float | None

The arrowhead stroke dashoffset of the arc

None
arrowhead_stroke_width float | None

The arrowhead stroke width of the arc

1.25
arrowhead_transform NoneValueType | tuple[Transformation, ...] | None

The arrowhead transform of the arc

None

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

arrowhead_base

Return the arrowhead base anchor point of the single-headed arc.

arrowhead_bbox

Return the bounding box of the single-headed arc arrowhead.

arrowhead_border

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

arrowhead_drawing_elements

Return the drawing elements of the single-headed arc arrowhead.

arrowhead_length

Return the length of the single-headed arc arrowhead.

arrowhead_tip

Return the arrowhead tip anchor point of the single-headed arc.

bbox

Compute and return the bounding box of the group layout element.

childless

Return a copy of the arc with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

end_point

Return the ending point of the arc.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

fraction

Return the position and angle on the arc at a given fraction (of the total arc length).

length

Return the total length of the arc path.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_children

Return the self children of the arc.

own_drawing_elements

Return the self drawing elements of the single-headed arc.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

path_drawing_elements

Return the drawing elements of the single-headed arc path.

points

Return the points of the arc path.

start_point

Return the starting point of the arc.

to_geometry

Return a list of geometry primitives from the drawing elements.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

arrowhead_base

arrowhead_base() -> Point

Return the arrowhead base anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_base(self) -> Point:
    """Return the arrowhead base anchor point of the single-headed arc."""
    arrowhead_length = self.arrowhead_length()
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return self.arrowhead_tip() - (arrowhead_length, 0)
    fraction = 1 - (arrowhead_length + self.end_shorten) / segment_length
    return segment.get_position_at_fraction(fraction)

arrowhead_bbox

arrowhead_bbox() -> Bbox

Return the bounding box of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_bbox(self) -> Bbox:
    """Return the bounding box of the single-headed arc arrowhead."""
    return get_drawing_elements_bbox(self.arrowhead_drawing_elements())

arrowhead_border

arrowhead_border(point: Point) -> Point

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def arrowhead_border(self, point: Point) -> Point:
    """Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    point = get_drawing_elements_border(self.arrowhead_drawing_elements(), point)
    if point is None:
        return self.arrowhead_tip()
    return point

arrowhead_drawing_elements

arrowhead_drawing_elements() -> list[DrawingElement]

Return the drawing elements of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_drawing_elements(
    self,
) -> list[DrawingElement]:
    """Return the drawing elements of the single-headed arc arrowhead."""
    drawing_elements = self._arrowhead_border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_arrowhead",
        elements=tuple(drawing_elements),
        fill=self.arrowhead_fill,
        filter_=self.arrowhead_filter,
        id_=f"{self.id_}_arrowhead",
        stroke=self.arrowhead_stroke,
        stroke_dasharray=self.arrowhead_stroke_dasharray,
        stroke_dashoffset=self.arrowhead_stroke_dashoffset,
        stroke_width=self.arrowhead_stroke_width,
        transform=self.arrowhead_transform,
    )
    transformation = self._get_arrowhead_transformation()
    group = group.transformed(transformation)
    return [group]

arrowhead_length

arrowhead_length() -> float

Return the length of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_length(self) -> float:
    """Return the length of the single-headed arc arrowhead."""
    bbox = get_drawing_elements_bbox(self._arrowhead_border_drawing_elements())
    if math.isnan(bbox.width):
        return 0.0
    return bbox.east().x

arrowhead_tip

arrowhead_tip() -> Point

Return the arrowhead tip anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_tip(self) -> Point:
    """Return the arrowhead tip anchor point of the single-headed arc."""
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return segment.p2
    fraction = 1 - self.end_shorten / segment_length
    return segment.get_position_at_fraction(fraction)

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

childless

childless() -> Self

Return a copy of the arc with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the arc with no children."""
    return dataclasses.replace(self, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

end_point

end_point() -> Point

Return the ending point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def end_point(self) -> Point:
    """Return the ending point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[-1]

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

fraction

fraction(fraction: float) -> tuple[Point, float]

Return the position and angle on the arc at a given fraction (of the total arc length).

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def fraction(self, fraction: float) -> tuple[Point, float]:
    """Return the position and angle on the arc at a given fraction (of the total arc length).

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    current_length = 0
    length_to_reach = fraction * self.length()
    for segment in self.segments:
        current_length += segment.length()
        if current_length >= length_to_reach:
            break
    segment_start_length = current_length - segment.length()
    segment_fraction = (length_to_reach - segment_start_length) / segment.length()
    position, angle = segment.get_position_and_angle_at_fraction(segment_fraction)
    return position, angle

length

length() -> float

Return the total length of the arc path.

Source code in src/momapy/core/layout.py
def length(self) -> float:
    """Return the total length of the arc path."""
    return sum([segment.length() for segment in self.segments])

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_children

own_children() -> list[LayoutElement]

Return the self children of the arc.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the arc."""
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the self drawing elements of the single-headed arc.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the self drawing elements of the single-headed arc."""
    drawing_elements = (
        self.path_drawing_elements() + self.arrowhead_drawing_elements()
    )
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

path_drawing_elements

path_drawing_elements() -> list[Path]

Return the drawing elements of the single-headed arc path.

Source code in src/momapy/core/layout.py
def path_drawing_elements(self) -> list[Path]:
    """Return the drawing elements of the single-headed arc path."""
    arrowhead_length = self.arrowhead_length()
    if len(self.segments) == 1:
        segment = (
            self.segments[0]
            .shortened(self.start_shorten, "start")
            .shortened(self.end_shorten + arrowhead_length, "end")
        )
        actions = [
            MoveTo(segment.p1),
            self._make_path_action_from_segment(segment),
        ]
    else:
        first_segment = self.segments[0].shortened(self.start_shorten, "start")
        last_segment = self.segments[-1].shortened(
            self.end_shorten + arrowhead_length, "end"
        )
        actions = [
            MoveTo(first_segment.p1),
            self._make_path_action_from_segment(first_segment),
        ]
        for segment in self.segments[1:-1]:
            action = self._make_path_action_from_segment(segment)
            actions.append(action)
        actions.append(self._make_path_action_from_segment(last_segment))
    path = Path(
        actions=tuple(actions),
        class_=f"{type(self).__name__}_path",
        fill=self.path_fill,
        filter_=self.path_filter,
        id_=f"{self.id_}_path",
        stroke=self.path_stroke,
        stroke_dasharray=self.path_stroke_dasharray,
        stroke_dashoffset=self.path_stroke_dashoffset,
        stroke_width=self.path_stroke_width,
        transform=self.path_transform,
    )
    return [path]

points

points() -> list[Point]

Return the points of the arc path.

An arc with no segments has no points and returns an empty list.

Source code in src/momapy/core/layout.py
def points(self) -> list[Point]:
    """Return the points of the arc path.

    An arc with no segments has no points and returns an empty list.
    """
    if not self.segments:
        return []
    points = []
    for segment in self.segments:
        points.append(segment.p1)
    points.append(segment.p2)
    return points

start_point

start_point() -> Point

Return the starting point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def start_point(self) -> Point:
    """Return the starting point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[0]

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

LogicalOperator dataclass

LogicalOperator(*, id_: str = make_uuid4_as_str(), inputs: frozenset[LogicalOperatorInput] = frozenset())

Bases: SBGNModelElement

Abstract base class for logical operators.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'a2e1b477-ce51-414d-8882-4e560bd7e3fd'
inputs frozenset[LogicalOperatorInput]

Input connections to the logical operator.

<dynamic>

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

LogicalOperatorInput dataclass

LogicalOperatorInput(*, id_: str = make_uuid4_as_str(), referred_element: Union[BiologicalActivity, ForwardRef(LogicalOperator, module=__name__)])

Bases: SBGNRole

Logical operator input.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'7d7a37b2-f267-4c63-bdb4-d887e502ce4c'
referred_element BiologicalActivity | ForwardRef

The biological activity or logical operator providing the input.

required

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

MacromoleculeUnitOfInformation dataclass

MacromoleculeUnitOfInformation(*, id_: str = make_uuid4_as_str(), label: str | None = None)

Bases: UnitOfInformation

Macromolecule unit of information.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'68bd62b2-c4d6-4a22-81cd-68a8c105be19'
label str | None

The label of the unit of information.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

MacromoleculeUnitOfInformationLayout dataclass

MacromoleculeUnitOfInformationLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 12.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 18.0, rounded_corners: float = 3.0)

Bases: _SimpleMixin, SBGNNode

Macromolecule unit of information layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'b6d75e0b-9e1e-4716-9a04-3637c6ba4c50'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

12.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

18.0
rounded_corners float

The radius of the rounded corners.

3.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

NecessaryStimulation dataclass

NecessaryStimulation(*, id_: str = make_uuid4_as_str(), source: BiologicalActivity | LogicalOperator, target: Activity)

Bases: Influence

Necessary stimulation.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'c6b9f318-1dc1-452e-8a73-209110b92681'
source BiologicalActivity | LogicalOperator

The source activity or logical operator.

required
target Activity

The target activity being influenced.

required

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

NecessaryStimulationLayout dataclass

NecessaryStimulationLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, end_shorten: float = 0.0, fill: NoneValueType | Color | None = None, filter_: NoneValueType | Filter | None = None, path_fill: NoneValueType | Color | None = NoneValue, path_filter: NoneValueType | Filter | None = None, path_stroke: NoneValueType | Color | None = black, path_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, path_stroke_dashoffset: NoneValueType | float | None = None, path_stroke_width: float | None = 1.25, path_transform: NoneValueType | tuple[Transformation, ...] | None = None, stroke: NoneValueType | Color | None = None, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: NoneValueType | float | None = None, segments: tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...] = tuple(), source: LayoutElement | None = None, start_shorten: float = 0.0, target: LayoutElement | None = None, transform: NoneValueType | tuple[Transformation, ...] | None = None, arrowhead_fill: NoneValueType | Color | None = white, arrowhead_filter: NoneValueType | Filter | None = None, arrowhead_stroke: NoneValueType | Color | None = black, arrowhead_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, arrowhead_stroke_dashoffset: NoneValueType | float | None = None, arrowhead_stroke_width: float | None = 1.25, arrowhead_transform: NoneValueType | tuple[Transformation, ...] | None = None, arrowhead_bar_height: float = 12.0, arrowhead_sep: float = 3.0, arrowhead_triangle_height: float = 10.0, arrowhead_triangle_width: float = 10.0)

Bases: SBGNSingleHeadedArc

Necessary stimulation layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'c35c1fe5-925e-40c5-a146-d72e2cf557af'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
end_shorten float

The length the end of the arc will be shorten by

0.0
fill NoneValueType | Color | None

The fill color of the arc

None
filter_ NoneValueType | Filter | None

The filter of the arc

None
path_fill NoneValueType | Color | None

The path fill color of the arc

<momapy.drawing.NoneValueType object at 0x7fb1b7eb96a0>
path_filter NoneValueType | Filter | None

The path filter of the arc

None
path_stroke NoneValueType | Color | None

The path stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
path_stroke_dasharray NoneValueType | tuple[float, ...] | None

The path stroke dasharray of the arc

None
path_stroke_dashoffset NoneValueType | float | None

The path stroke dashoffset of the arc

None
path_stroke_width float | None

The path stroke width of the arc

1.25
path_transform NoneValueType | tuple[Transformation, ...] | None

The path transform of the arc

None
stroke NoneValueType | Color | None

The stroke color of the arc

None
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the arc

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the arc

None
stroke_width NoneValueType | float | None

The stroke width of the arc

None
segments tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...]

The path segments of the arc

<dynamic>
source LayoutElement | None

The source of the arc

None
start_shorten float

The length the start of the arc will be shorten by

0.0
target LayoutElement | None

The target of the arc

None
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the arc

None
arrowhead_fill NoneValueType | Color | None

The arrowhead fill color of the arc

Color(red=255, green=255, blue=255, alpha=1.0)
arrowhead_filter NoneValueType | Filter | None

The arrowhead filter of the arc

None
arrowhead_stroke NoneValueType | Color | None

The arrowhead stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
arrowhead_stroke_dasharray NoneValueType | tuple[float, ...] | None

The arrowhead stroke dasharray of the arc

None
arrowhead_stroke_dashoffset NoneValueType | float | None

The arrowhead stroke dashoffset of the arc

None
arrowhead_stroke_width float | None

The arrowhead stroke width of the arc

1.25
arrowhead_transform NoneValueType | tuple[Transformation, ...] | None

The arrowhead transform of the arc

None
arrowhead_bar_height float

The height of the arrowhead bar.

12.0
arrowhead_sep float

The separation between the bar and the triangle.

3.0
arrowhead_triangle_height float

The height of the arrowhead triangle.

10.0
arrowhead_triangle_width float

The width of the arrowhead triangle.

10.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

arrowhead_base

Return the arrowhead base anchor point of the single-headed arc.

arrowhead_bbox

Return the bounding box of the single-headed arc arrowhead.

arrowhead_border

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

arrowhead_drawing_elements

Return the drawing elements of the single-headed arc arrowhead.

arrowhead_length

Return the length of the single-headed arc arrowhead.

arrowhead_tip

Return the arrowhead tip anchor point of the single-headed arc.

bbox

Compute and return the bounding box of the group layout element.

childless

Return a copy of the arc with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

end_point

Return the ending point of the arc.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

fraction

Return the position and angle on the arc at a given fraction (of the total arc length).

length

Return the total length of the arc path.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_children

Return the self children of the arc.

own_drawing_elements

Return the self drawing elements of the single-headed arc.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

path_drawing_elements

Return the drawing elements of the single-headed arc path.

points

Return the points of the arc path.

start_point

Return the starting point of the arc.

to_geometry

Return a list of geometry primitives from the drawing elements.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

arrowhead_base

arrowhead_base() -> Point

Return the arrowhead base anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_base(self) -> Point:
    """Return the arrowhead base anchor point of the single-headed arc."""
    arrowhead_length = self.arrowhead_length()
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return self.arrowhead_tip() - (arrowhead_length, 0)
    fraction = 1 - (arrowhead_length + self.end_shorten) / segment_length
    return segment.get_position_at_fraction(fraction)

arrowhead_bbox

arrowhead_bbox() -> Bbox

Return the bounding box of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_bbox(self) -> Bbox:
    """Return the bounding box of the single-headed arc arrowhead."""
    return get_drawing_elements_bbox(self.arrowhead_drawing_elements())

arrowhead_border

arrowhead_border(point: Point) -> Point

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def arrowhead_border(self, point: Point) -> Point:
    """Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    point = get_drawing_elements_border(self.arrowhead_drawing_elements(), point)
    if point is None:
        return self.arrowhead_tip()
    return point

arrowhead_drawing_elements

arrowhead_drawing_elements() -> list[DrawingElement]

Return the drawing elements of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_drawing_elements(
    self,
) -> list[DrawingElement]:
    """Return the drawing elements of the single-headed arc arrowhead."""
    drawing_elements = self._arrowhead_border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_arrowhead",
        elements=tuple(drawing_elements),
        fill=self.arrowhead_fill,
        filter_=self.arrowhead_filter,
        id_=f"{self.id_}_arrowhead",
        stroke=self.arrowhead_stroke,
        stroke_dasharray=self.arrowhead_stroke_dasharray,
        stroke_dashoffset=self.arrowhead_stroke_dashoffset,
        stroke_width=self.arrowhead_stroke_width,
        transform=self.arrowhead_transform,
    )
    transformation = self._get_arrowhead_transformation()
    group = group.transformed(transformation)
    return [group]

arrowhead_length

arrowhead_length() -> float

Return the length of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_length(self) -> float:
    """Return the length of the single-headed arc arrowhead."""
    bbox = get_drawing_elements_bbox(self._arrowhead_border_drawing_elements())
    if math.isnan(bbox.width):
        return 0.0
    return bbox.east().x

arrowhead_tip

arrowhead_tip() -> Point

Return the arrowhead tip anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_tip(self) -> Point:
    """Return the arrowhead tip anchor point of the single-headed arc."""
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return segment.p2
    fraction = 1 - self.end_shorten / segment_length
    return segment.get_position_at_fraction(fraction)

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

childless

childless() -> Self

Return a copy of the arc with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the arc with no children."""
    return dataclasses.replace(self, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

end_point

end_point() -> Point

Return the ending point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def end_point(self) -> Point:
    """Return the ending point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[-1]

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

fraction

fraction(fraction: float) -> tuple[Point, float]

Return the position and angle on the arc at a given fraction (of the total arc length).

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def fraction(self, fraction: float) -> tuple[Point, float]:
    """Return the position and angle on the arc at a given fraction (of the total arc length).

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    current_length = 0
    length_to_reach = fraction * self.length()
    for segment in self.segments:
        current_length += segment.length()
        if current_length >= length_to_reach:
            break
    segment_start_length = current_length - segment.length()
    segment_fraction = (length_to_reach - segment_start_length) / segment.length()
    position, angle = segment.get_position_and_angle_at_fraction(segment_fraction)
    return position, angle

length

length() -> float

Return the total length of the arc path.

Source code in src/momapy/core/layout.py
def length(self) -> float:
    """Return the total length of the arc path."""
    return sum([segment.length() for segment in self.segments])

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_children

own_children() -> list[LayoutElement]

Return the self children of the arc.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the arc."""
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the self drawing elements of the single-headed arc.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the self drawing elements of the single-headed arc."""
    drawing_elements = (
        self.path_drawing_elements() + self.arrowhead_drawing_elements()
    )
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

path_drawing_elements

path_drawing_elements() -> list[Path]

Return the drawing elements of the single-headed arc path.

Source code in src/momapy/core/layout.py
def path_drawing_elements(self) -> list[Path]:
    """Return the drawing elements of the single-headed arc path."""
    arrowhead_length = self.arrowhead_length()
    if len(self.segments) == 1:
        segment = (
            self.segments[0]
            .shortened(self.start_shorten, "start")
            .shortened(self.end_shorten + arrowhead_length, "end")
        )
        actions = [
            MoveTo(segment.p1),
            self._make_path_action_from_segment(segment),
        ]
    else:
        first_segment = self.segments[0].shortened(self.start_shorten, "start")
        last_segment = self.segments[-1].shortened(
            self.end_shorten + arrowhead_length, "end"
        )
        actions = [
            MoveTo(first_segment.p1),
            self._make_path_action_from_segment(first_segment),
        ]
        for segment in self.segments[1:-1]:
            action = self._make_path_action_from_segment(segment)
            actions.append(action)
        actions.append(self._make_path_action_from_segment(last_segment))
    path = Path(
        actions=tuple(actions),
        class_=f"{type(self).__name__}_path",
        fill=self.path_fill,
        filter_=self.path_filter,
        id_=f"{self.id_}_path",
        stroke=self.path_stroke,
        stroke_dasharray=self.path_stroke_dasharray,
        stroke_dashoffset=self.path_stroke_dashoffset,
        stroke_width=self.path_stroke_width,
        transform=self.path_transform,
    )
    return [path]

points

points() -> list[Point]

Return the points of the arc path.

An arc with no segments has no points and returns an empty list.

Source code in src/momapy/core/layout.py
def points(self) -> list[Point]:
    """Return the points of the arc path.

    An arc with no segments has no points and returns an empty list.
    """
    if not self.segments:
        return []
    points = []
    for segment in self.segments:
        points.append(segment.p1)
    points.append(segment.p2)
    return points

start_point

start_point() -> Point

Return the starting point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def start_point(self) -> Point:
    """Return the starting point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[0]

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

NegativeInfluence dataclass

NegativeInfluence(*, id_: str = make_uuid4_as_str(), source: BiologicalActivity | LogicalOperator, target: Activity)

Bases: Influence

Negative influence.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'374870f4-0b5c-46c4-80cf-7c56e26304cd'
source BiologicalActivity | LogicalOperator

The source activity or logical operator.

required
target Activity

The target activity being influenced.

required

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

NegativeInfluenceLayout dataclass

NegativeInfluenceLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, end_shorten: float = 0.0, fill: NoneValueType | Color | None = None, filter_: NoneValueType | Filter | None = None, path_fill: NoneValueType | Color | None = NoneValue, path_filter: NoneValueType | Filter | None = None, path_stroke: NoneValueType | Color | None = black, path_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, path_stroke_dashoffset: NoneValueType | float | None = None, path_stroke_width: float | None = 1.25, path_transform: NoneValueType | tuple[Transformation, ...] | None = None, stroke: NoneValueType | Color | None = None, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: NoneValueType | float | None = None, segments: tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...] = tuple(), source: LayoutElement | None = None, start_shorten: float = 0.0, target: LayoutElement | None = None, transform: NoneValueType | tuple[Transformation, ...] | None = None, arrowhead_fill: NoneValueType | Color | None = white, arrowhead_filter: NoneValueType | Filter | None = None, arrowhead_stroke: NoneValueType | Color | None = black, arrowhead_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, arrowhead_stroke_dashoffset: NoneValueType | float | None = None, arrowhead_stroke_width: float | None = 1.25, arrowhead_transform: NoneValueType | tuple[Transformation, ...] | None = None, arrowhead_height: float = 10.0)

Bases: SBGNSingleHeadedArc

Negative influence layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'483709c0-0033-47fe-88fc-130a6c5fd721'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
end_shorten float

The length the end of the arc will be shorten by

0.0
fill NoneValueType | Color | None

The fill color of the arc

None
filter_ NoneValueType | Filter | None

The filter of the arc

None
path_fill NoneValueType | Color | None

The path fill color of the arc

<momapy.drawing.NoneValueType object at 0x7fb1b7eb96a0>
path_filter NoneValueType | Filter | None

The path filter of the arc

None
path_stroke NoneValueType | Color | None

The path stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
path_stroke_dasharray NoneValueType | tuple[float, ...] | None

The path stroke dasharray of the arc

None
path_stroke_dashoffset NoneValueType | float | None

The path stroke dashoffset of the arc

None
path_stroke_width float | None

The path stroke width of the arc

1.25
path_transform NoneValueType | tuple[Transformation, ...] | None

The path transform of the arc

None
stroke NoneValueType | Color | None

The stroke color of the arc

None
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the arc

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the arc

None
stroke_width NoneValueType | float | None

The stroke width of the arc

None
segments tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...]

The path segments of the arc

<dynamic>
source LayoutElement | None

The source of the arc

None
start_shorten float

The length the start of the arc will be shorten by

0.0
target LayoutElement | None

The target of the arc

None
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the arc

None
arrowhead_fill NoneValueType | Color | None

The arrowhead fill color of the arc

Color(red=255, green=255, blue=255, alpha=1.0)
arrowhead_filter NoneValueType | Filter | None

The arrowhead filter of the arc

None
arrowhead_stroke NoneValueType | Color | None

The arrowhead stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
arrowhead_stroke_dasharray NoneValueType | tuple[float, ...] | None

The arrowhead stroke dasharray of the arc

None
arrowhead_stroke_dashoffset NoneValueType | float | None

The arrowhead stroke dashoffset of the arc

None
arrowhead_stroke_width float | None

The arrowhead stroke width of the arc

1.25
arrowhead_transform NoneValueType | tuple[Transformation, ...] | None

The arrowhead transform of the arc

None
arrowhead_height float

The height of the arrowhead.

10.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

arrowhead_base

Return the arrowhead base anchor point of the single-headed arc.

arrowhead_bbox

Return the bounding box of the single-headed arc arrowhead.

arrowhead_border

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

arrowhead_drawing_elements

Return the drawing elements of the single-headed arc arrowhead.

arrowhead_length

Return the length of the single-headed arc arrowhead.

arrowhead_tip

Return the arrowhead tip anchor point of the single-headed arc.

bbox

Compute and return the bounding box of the group layout element.

childless

Return a copy of the arc with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

end_point

Return the ending point of the arc.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

fraction

Return the position and angle on the arc at a given fraction (of the total arc length).

length

Return the total length of the arc path.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_children

Return the self children of the arc.

own_drawing_elements

Return the self drawing elements of the single-headed arc.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

path_drawing_elements

Return the drawing elements of the single-headed arc path.

points

Return the points of the arc path.

start_point

Return the starting point of the arc.

to_geometry

Return a list of geometry primitives from the drawing elements.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

arrowhead_base

arrowhead_base() -> Point

Return the arrowhead base anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_base(self) -> Point:
    """Return the arrowhead base anchor point of the single-headed arc."""
    arrowhead_length = self.arrowhead_length()
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return self.arrowhead_tip() - (arrowhead_length, 0)
    fraction = 1 - (arrowhead_length + self.end_shorten) / segment_length
    return segment.get_position_at_fraction(fraction)

arrowhead_bbox

arrowhead_bbox() -> Bbox

Return the bounding box of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_bbox(self) -> Bbox:
    """Return the bounding box of the single-headed arc arrowhead."""
    return get_drawing_elements_bbox(self.arrowhead_drawing_elements())

arrowhead_border

arrowhead_border(point: Point) -> Point

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def arrowhead_border(self, point: Point) -> Point:
    """Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    point = get_drawing_elements_border(self.arrowhead_drawing_elements(), point)
    if point is None:
        return self.arrowhead_tip()
    return point

arrowhead_drawing_elements

arrowhead_drawing_elements() -> list[DrawingElement]

Return the drawing elements of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_drawing_elements(
    self,
) -> list[DrawingElement]:
    """Return the drawing elements of the single-headed arc arrowhead."""
    drawing_elements = self._arrowhead_border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_arrowhead",
        elements=tuple(drawing_elements),
        fill=self.arrowhead_fill,
        filter_=self.arrowhead_filter,
        id_=f"{self.id_}_arrowhead",
        stroke=self.arrowhead_stroke,
        stroke_dasharray=self.arrowhead_stroke_dasharray,
        stroke_dashoffset=self.arrowhead_stroke_dashoffset,
        stroke_width=self.arrowhead_stroke_width,
        transform=self.arrowhead_transform,
    )
    transformation = self._get_arrowhead_transformation()
    group = group.transformed(transformation)
    return [group]

arrowhead_length

arrowhead_length() -> float

Return the length of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_length(self) -> float:
    """Return the length of the single-headed arc arrowhead."""
    bbox = get_drawing_elements_bbox(self._arrowhead_border_drawing_elements())
    if math.isnan(bbox.width):
        return 0.0
    return bbox.east().x

arrowhead_tip

arrowhead_tip() -> Point

Return the arrowhead tip anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_tip(self) -> Point:
    """Return the arrowhead tip anchor point of the single-headed arc."""
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return segment.p2
    fraction = 1 - self.end_shorten / segment_length
    return segment.get_position_at_fraction(fraction)

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

childless

childless() -> Self

Return a copy of the arc with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the arc with no children."""
    return dataclasses.replace(self, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

end_point

end_point() -> Point

Return the ending point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def end_point(self) -> Point:
    """Return the ending point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[-1]

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

fraction

fraction(fraction: float) -> tuple[Point, float]

Return the position and angle on the arc at a given fraction (of the total arc length).

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def fraction(self, fraction: float) -> tuple[Point, float]:
    """Return the position and angle on the arc at a given fraction (of the total arc length).

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    current_length = 0
    length_to_reach = fraction * self.length()
    for segment in self.segments:
        current_length += segment.length()
        if current_length >= length_to_reach:
            break
    segment_start_length = current_length - segment.length()
    segment_fraction = (length_to_reach - segment_start_length) / segment.length()
    position, angle = segment.get_position_and_angle_at_fraction(segment_fraction)
    return position, angle

length

length() -> float

Return the total length of the arc path.

Source code in src/momapy/core/layout.py
def length(self) -> float:
    """Return the total length of the arc path."""
    return sum([segment.length() for segment in self.segments])

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_children

own_children() -> list[LayoutElement]

Return the self children of the arc.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the arc."""
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the self drawing elements of the single-headed arc.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the self drawing elements of the single-headed arc."""
    drawing_elements = (
        self.path_drawing_elements() + self.arrowhead_drawing_elements()
    )
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

path_drawing_elements

path_drawing_elements() -> list[Path]

Return the drawing elements of the single-headed arc path.

Source code in src/momapy/core/layout.py
def path_drawing_elements(self) -> list[Path]:
    """Return the drawing elements of the single-headed arc path."""
    arrowhead_length = self.arrowhead_length()
    if len(self.segments) == 1:
        segment = (
            self.segments[0]
            .shortened(self.start_shorten, "start")
            .shortened(self.end_shorten + arrowhead_length, "end")
        )
        actions = [
            MoveTo(segment.p1),
            self._make_path_action_from_segment(segment),
        ]
    else:
        first_segment = self.segments[0].shortened(self.start_shorten, "start")
        last_segment = self.segments[-1].shortened(
            self.end_shorten + arrowhead_length, "end"
        )
        actions = [
            MoveTo(first_segment.p1),
            self._make_path_action_from_segment(first_segment),
        ]
        for segment in self.segments[1:-1]:
            action = self._make_path_action_from_segment(segment)
            actions.append(action)
        actions.append(self._make_path_action_from_segment(last_segment))
    path = Path(
        actions=tuple(actions),
        class_=f"{type(self).__name__}_path",
        fill=self.path_fill,
        filter_=self.path_filter,
        id_=f"{self.id_}_path",
        stroke=self.path_stroke,
        stroke_dasharray=self.path_stroke_dasharray,
        stroke_dashoffset=self.path_stroke_dashoffset,
        stroke_width=self.path_stroke_width,
        transform=self.path_transform,
    )
    return [path]

points

points() -> list[Point]

Return the points of the arc path.

An arc with no segments has no points and returns an empty list.

Source code in src/momapy/core/layout.py
def points(self) -> list[Point]:
    """Return the points of the arc path.

    An arc with no segments has no points and returns an empty list.
    """
    if not self.segments:
        return []
    points = []
    for segment in self.segments:
        points.append(segment.p1)
    points.append(segment.p2)
    return points

start_point

start_point() -> Point

Return the starting point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def start_point(self) -> Point:
    """Return the starting point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[0]

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

NotOperator dataclass

NotOperator(*, id_: str = make_uuid4_as_str(), inputs: frozenset[LogicalOperatorInput] = frozenset())

Bases: LogicalOperator

NOT operator.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'd3721e51-055f-4ba1-8bc6-c674d1582a45'
inputs frozenset[LogicalOperatorInput]

Input connections to the logical operator.

<dynamic>

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

NotOperatorLayout dataclass

NotOperatorLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 30.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 30.0, text: str = 'NOT', font_family: str = DEFAULT_FONT_FAMILY, font_fill: Color | NoneValueType = black, font_stroke: Color | NoneValueType = NoneValue, font_style: FontStyle = NORMAL, font_weight: FontWeight | float = NORMAL, orientation: Orientation = HORIZONTAL, left_to_right: bool = True, left_connector_length: float = 10.0, right_connector_length: float = 10.0, left_connector_stroke: NoneValueType | Color | None = None, left_connector_stroke_width: float | None = None, left_connector_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, left_connector_stroke_dashoffset: float | None = None, left_connector_fill: NoneValueType | Color | None = None, left_connector_transform: NoneValueType | tuple[Transformation, ...] | None = None, left_connector_filter: NoneValueType | Filter | None = None, right_connector_stroke: NoneValueType | Color | None = None, right_connector_stroke_width: float | None = None, right_connector_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, right_connector_stroke_dashoffset: float | None = None, right_connector_fill: NoneValueType | Color | None = None, right_connector_transform: NoneValueType | tuple[Transformation, ...] | None = None, right_connector_filter: NoneValueType | Filter | None = None)

Bases: _ConnectorsMixin, _SimpleMixin, _TextMixin, SBGNNode

NOT operator layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'84f8c672-bc66-492a-be20-82cb4b639438'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

30.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

30.0
text str

The text displayed inside the node.

'NOT'
font_family str

Font family for the text.

'DejaVu Sans'
font_fill Color | NoneValueType

Fill color for the text.

Color(red=0, green=0, blue=0, alpha=1.0)
font_stroke Color | NoneValueType

Stroke color for the text outline.

<momapy.drawing.NoneValueType object at 0x7fb1b7eb96a0>
font_style FontStyle

Font style (normal, italic, etc.).

<FontStyle.NORMAL: 0>
font_weight FontWeight | float

Font weight (normal, bold, etc.).

<FontWeight.NORMAL: 0>
orientation Orientation

Orientation of connectors (HORIZONTAL or VERTICAL).

<Orientation.HORIZONTAL: 1>
left_to_right bool

Whether connectors flow left to right.

True
left_connector_length float

Length of the left connector.

10.0
right_connector_length float

Length of the right connector.

10.0
left_connector_stroke NoneValueType | Color | None

Stroke color for the left connector line.

None
left_connector_stroke_width float | None

Stroke width for the left connector line.

None
left_connector_stroke_dasharray NoneValueType | tuple[float, ...] | None

Dash pattern for the left connector line.

None
left_connector_stroke_dashoffset float | None

Dash offset for the left connector line.

None
left_connector_fill NoneValueType | Color | None

Fill color for the left connector.

None
left_connector_transform NoneValueType | tuple[Transformation, ...] | None

Transformations applied to the left connector.

None
left_connector_filter NoneValueType | Filter | None

Filter applied to the left connector.

None
right_connector_stroke NoneValueType | Color | None

Stroke color for the right connector line.

None
right_connector_stroke_width float | None

Stroke width for the right connector line.

None
right_connector_stroke_dasharray NoneValueType | tuple[float, ...] | None

Dash pattern for the right connector line.

None
right_connector_stroke_dashoffset float | None

Dash offset for the right connector line.

None
right_connector_fill NoneValueType | Color | None

Fill color for the right connector.

None
right_connector_transform NoneValueType | tuple[Transformation, ...] | None

Transformations applied to the right connector.

None
right_connector_filter NoneValueType | Filter | None

Filter applied to the right connector.

None

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Get the east (right) anchor point.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

left_connector_base

Get the base point of the left connector.

left_connector_tip

Get the tip point of the left connector.

north

Get the north (top) anchor point.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

right_connector_base

Get the base point of the right connector.

right_connector_tip

Get the tip point of the right connector.

size

Return the size of the node.

south

Get the south (bottom) anchor point.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Get the west (left) anchor point.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Get the east (right) anchor point.

Returns:

Type Description
Point

Point on the east side of the element.

Source code in src/momapy/sbgn/elements.py
def east(self) -> Point:
    """Get the east (right) anchor point.

    Returns:
        Point on the east side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x + self.width / 2, self.y)
    else:
        return Point(self.x + self.width / 2 + self.right_connector_length, self.y)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

left_connector_base

left_connector_base() -> Point

Get the base point of the left connector.

Returns:

Type Description
Point

Point where the left connector attaches to the shape.

Source code in src/momapy/sbgn/elements.py
def left_connector_base(self) -> Point:
    """Get the base point of the left connector.

    Returns:
        Point where the left connector attaches to the shape.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2)
    else:
        return Point(self.x - self.width / 2, self.y)

left_connector_tip

left_connector_tip() -> Point

Get the tip point of the left connector.

Returns:

Type Description
Point

Point at the end of the left connector line.

Source code in src/momapy/sbgn/elements.py
def left_connector_tip(self) -> Point:
    """Get the tip point of the left connector.

    Returns:
        Point at the end of the left connector line.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2 - self.left_connector_length)
    else:
        return Point(self.x - self.width / 2 - self.left_connector_length, self.y)

north

north() -> Point

Get the north (top) anchor point.

Returns:

Type Description
Point

Point on the north side of the element.

Source code in src/momapy/sbgn/elements.py
def north(self) -> Point:
    """Get the north (top) anchor point.

    Returns:
        Point on the north side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2 - self.left_connector_length)
    else:
        return Point(self.x, self.y - self.height / 2)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

right_connector_base

right_connector_base() -> Point

Get the base point of the right connector.

Returns:

Type Description
Point

Point where the right connector attaches to the shape.

Source code in src/momapy/sbgn/elements.py
def right_connector_base(self) -> Point:
    """Get the base point of the right connector.

    Returns:
        Point where the right connector attaches to the shape.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2)
    else:
        return Point(self.x + self.width / 2, self.y)

right_connector_tip

right_connector_tip() -> Point

Get the tip point of the right connector.

Returns:

Type Description
Point

Point at the end of the right connector line.

Source code in src/momapy/sbgn/elements.py
def right_connector_tip(self) -> Point:
    """Get the tip point of the right connector.

    Returns:
        Point at the end of the right connector line.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2 + self.right_connector_length)
    else:
        return Point(self.x + self.width / 2 + self.right_connector_length, self.y)

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Get the south (bottom) anchor point.

Returns:

Type Description
Point

Point on the south side of the element.

Source code in src/momapy/sbgn/elements.py
def south(self) -> Point:
    """Get the south (bottom) anchor point.

    Returns:
        Point on the south side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2 + self.right_connector_length)
    else:
        return Point(self.x, self.y + self.height / 2)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Get the west (left) anchor point.

Returns:

Type Description
Point

Point on the west side of the element.

Source code in src/momapy/sbgn/elements.py
def west(self) -> Point:
    """Get the west (left) anchor point.

    Returns:
        Point on the west side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x - self.width / 2, self.y)
    else:
        return Point(self.x - self.width / 2 - self.left_connector_length, self.y)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

NucleicAcidFeatureUnitOfInformation dataclass

NucleicAcidFeatureUnitOfInformation(*, id_: str = make_uuid4_as_str(), label: str | None = None)

Bases: UnitOfInformation

Nucleic acid feature unit of information.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'46eca30a-7eda-4d93-bcd9-3d5219766078'
label str | None

The label of the unit of information.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

NucleicAcidFeatureUnitOfInformationLayout dataclass

NucleicAcidFeatureUnitOfInformationLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 12.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 18.0, rounded_corners: float = 3.0)

Bases: _SimpleMixin, SBGNNode

Nucleic acid feature unit of information layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'aad3a223-3fc0-43cb-b6c3-a3fc9eb594d3'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

12.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

18.0
rounded_corners float

The radius of the rounded corners.

3.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

OrOperator dataclass

OrOperator(*, id_: str = make_uuid4_as_str(), inputs: frozenset[LogicalOperatorInput] = frozenset())

Bases: LogicalOperator

OR operator.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'6f6f95c4-c360-4b59-a42f-47be48e9e675'
inputs frozenset[LogicalOperatorInput]

Input connections to the logical operator.

<dynamic>

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

OrOperatorLayout dataclass

OrOperatorLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 30.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 30.0, text: str = 'OR', font_family: str = DEFAULT_FONT_FAMILY, font_fill: Color | NoneValueType = black, font_stroke: Color | NoneValueType = NoneValue, font_style: FontStyle = NORMAL, font_weight: FontWeight | float = NORMAL, orientation: Orientation = HORIZONTAL, left_to_right: bool = True, left_connector_length: float = 10.0, right_connector_length: float = 10.0, left_connector_stroke: NoneValueType | Color | None = None, left_connector_stroke_width: float | None = None, left_connector_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, left_connector_stroke_dashoffset: float | None = None, left_connector_fill: NoneValueType | Color | None = None, left_connector_transform: NoneValueType | tuple[Transformation, ...] | None = None, left_connector_filter: NoneValueType | Filter | None = None, right_connector_stroke: NoneValueType | Color | None = None, right_connector_stroke_width: float | None = None, right_connector_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, right_connector_stroke_dashoffset: float | None = None, right_connector_fill: NoneValueType | Color | None = None, right_connector_transform: NoneValueType | tuple[Transformation, ...] | None = None, right_connector_filter: NoneValueType | Filter | None = None)

Bases: _ConnectorsMixin, _SimpleMixin, _TextMixin, SBGNNode

OR operator layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'3f658771-2905-4199-ab73-2f4afcde4271'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

30.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

30.0
text str

The text displayed inside the node.

'OR'
font_family str

Font family for the text.

'DejaVu Sans'
font_fill Color | NoneValueType

Fill color for the text.

Color(red=0, green=0, blue=0, alpha=1.0)
font_stroke Color | NoneValueType

Stroke color for the text outline.

<momapy.drawing.NoneValueType object at 0x7fb1b7eb96a0>
font_style FontStyle

Font style (normal, italic, etc.).

<FontStyle.NORMAL: 0>
font_weight FontWeight | float

Font weight (normal, bold, etc.).

<FontWeight.NORMAL: 0>
orientation Orientation

Orientation of connectors (HORIZONTAL or VERTICAL).

<Orientation.HORIZONTAL: 1>
left_to_right bool

Whether connectors flow left to right.

True
left_connector_length float

Length of the left connector.

10.0
right_connector_length float

Length of the right connector.

10.0
left_connector_stroke NoneValueType | Color | None

Stroke color for the left connector line.

None
left_connector_stroke_width float | None

Stroke width for the left connector line.

None
left_connector_stroke_dasharray NoneValueType | tuple[float, ...] | None

Dash pattern for the left connector line.

None
left_connector_stroke_dashoffset float | None

Dash offset for the left connector line.

None
left_connector_fill NoneValueType | Color | None

Fill color for the left connector.

None
left_connector_transform NoneValueType | tuple[Transformation, ...] | None

Transformations applied to the left connector.

None
left_connector_filter NoneValueType | Filter | None

Filter applied to the left connector.

None
right_connector_stroke NoneValueType | Color | None

Stroke color for the right connector line.

None
right_connector_stroke_width float | None

Stroke width for the right connector line.

None
right_connector_stroke_dasharray NoneValueType | tuple[float, ...] | None

Dash pattern for the right connector line.

None
right_connector_stroke_dashoffset float | None

Dash offset for the right connector line.

None
right_connector_fill NoneValueType | Color | None

Fill color for the right connector.

None
right_connector_transform NoneValueType | tuple[Transformation, ...] | None

Transformations applied to the right connector.

None
right_connector_filter NoneValueType | Filter | None

Filter applied to the right connector.

None

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Get the east (right) anchor point.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

left_connector_base

Get the base point of the left connector.

left_connector_tip

Get the tip point of the left connector.

north

Get the north (top) anchor point.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

right_connector_base

Get the base point of the right connector.

right_connector_tip

Get the tip point of the right connector.

size

Return the size of the node.

south

Get the south (bottom) anchor point.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Get the west (left) anchor point.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Get the east (right) anchor point.

Returns:

Type Description
Point

Point on the east side of the element.

Source code in src/momapy/sbgn/elements.py
def east(self) -> Point:
    """Get the east (right) anchor point.

    Returns:
        Point on the east side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x + self.width / 2, self.y)
    else:
        return Point(self.x + self.width / 2 + self.right_connector_length, self.y)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

left_connector_base

left_connector_base() -> Point

Get the base point of the left connector.

Returns:

Type Description
Point

Point where the left connector attaches to the shape.

Source code in src/momapy/sbgn/elements.py
def left_connector_base(self) -> Point:
    """Get the base point of the left connector.

    Returns:
        Point where the left connector attaches to the shape.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2)
    else:
        return Point(self.x - self.width / 2, self.y)

left_connector_tip

left_connector_tip() -> Point

Get the tip point of the left connector.

Returns:

Type Description
Point

Point at the end of the left connector line.

Source code in src/momapy/sbgn/elements.py
def left_connector_tip(self) -> Point:
    """Get the tip point of the left connector.

    Returns:
        Point at the end of the left connector line.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2 - self.left_connector_length)
    else:
        return Point(self.x - self.width / 2 - self.left_connector_length, self.y)

north

north() -> Point

Get the north (top) anchor point.

Returns:

Type Description
Point

Point on the north side of the element.

Source code in src/momapy/sbgn/elements.py
def north(self) -> Point:
    """Get the north (top) anchor point.

    Returns:
        Point on the north side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y - self.height / 2 - self.left_connector_length)
    else:
        return Point(self.x, self.y - self.height / 2)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

right_connector_base

right_connector_base() -> Point

Get the base point of the right connector.

Returns:

Type Description
Point

Point where the right connector attaches to the shape.

Source code in src/momapy/sbgn/elements.py
def right_connector_base(self) -> Point:
    """Get the base point of the right connector.

    Returns:
        Point where the right connector attaches to the shape.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2)
    else:
        return Point(self.x + self.width / 2, self.y)

right_connector_tip

right_connector_tip() -> Point

Get the tip point of the right connector.

Returns:

Type Description
Point

Point at the end of the right connector line.

Source code in src/momapy/sbgn/elements.py
def right_connector_tip(self) -> Point:
    """Get the tip point of the right connector.

    Returns:
        Point at the end of the right connector line.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2 + self.right_connector_length)
    else:
        return Point(self.x + self.width / 2 + self.right_connector_length, self.y)

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Get the south (bottom) anchor point.

Returns:

Type Description
Point

Point on the south side of the element.

Source code in src/momapy/sbgn/elements.py
def south(self) -> Point:
    """Get the south (bottom) anchor point.

    Returns:
        Point on the south side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x, self.y + self.height / 2 + self.right_connector_length)
    else:
        return Point(self.x, self.y + self.height / 2)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Get the west (left) anchor point.

Returns:

Type Description
Point

Point on the west side of the element.

Source code in src/momapy/sbgn/elements.py
def west(self) -> Point:
    """Get the west (left) anchor point.

    Returns:
        Point on the west side of the element.
    """
    if self.orientation == Orientation.VERTICAL:
        return Point(self.x - self.width / 2, self.y)
    else:
        return Point(self.x - self.width / 2 - self.left_connector_length, self.y)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

PerturbationUnitOfInformation dataclass

PerturbationUnitOfInformation(*, id_: str = make_uuid4_as_str(), label: str | None = None)

Bases: UnitOfInformation

Perturbation unit of information.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'90b96ead-9e57-4da1-8b2f-3a920c649af4'
label str | None

The label of the unit of information.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

PerturbationUnitOfInformationLayout dataclass

PerturbationUnitOfInformationLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 12.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 18.0, angle: float = 70.0)

Bases: _SimpleMixin, SBGNNode

Perturbation unit of information layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'6e57884b-a5e8-427b-8ff8-719613744eb8'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

12.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

18.0
angle float

The angle of the notched sides.

70.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
angle float

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle class-attribute instance-attribute

angle: float = dataclasses.field(default=70.0, metadata={'description': 'The angle of the notched sides.'})

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

Phenotype dataclass

Phenotype(*, id_: str = make_uuid4_as_str(), label: str | None = None, compartment: Compartment | None = None)

Bases: Activity

Phenotype.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'39e26014-6f8d-4c3d-a694-3fc0418a2dc8'
label str | None

The label of the activity.

None
compartment Compartment | None

The compartment containing this activity.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

PhenotypeLayout dataclass

PhenotypeLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 30.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 60.0, angle: float = 70.0)

Bases: _SimpleMixin, SBGNNode

Phenotype layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'8fa81939-f74f-4137-92e0-f7d1cf3681bf'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

30.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

60.0
angle float

The angle of the slanted sides.

70.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
angle float

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle class-attribute instance-attribute

angle: float = dataclasses.field(default=70.0, metadata={'description': 'The angle of the slanted sides.'})

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

PositiveInfluence dataclass

PositiveInfluence(*, id_: str = make_uuid4_as_str(), source: BiologicalActivity | LogicalOperator, target: Activity)

Bases: Influence

Positive influence.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'e77292d3-cd5f-42f3-a1ea-8e62e6f830ef'
source BiologicalActivity | LogicalOperator

The source activity or logical operator.

required
target Activity

The target activity being influenced.

required

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

PositiveInfluenceLayout dataclass

PositiveInfluenceLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, end_shorten: float = 0.0, fill: NoneValueType | Color | None = None, filter_: NoneValueType | Filter | None = None, path_fill: NoneValueType | Color | None = NoneValue, path_filter: NoneValueType | Filter | None = None, path_stroke: NoneValueType | Color | None = black, path_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, path_stroke_dashoffset: NoneValueType | float | None = None, path_stroke_width: float | None = 1.25, path_transform: NoneValueType | tuple[Transformation, ...] | None = None, stroke: NoneValueType | Color | None = None, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: NoneValueType | float | None = None, segments: tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...] = tuple(), source: LayoutElement | None = None, start_shorten: float = 0.0, target: LayoutElement | None = None, transform: NoneValueType | tuple[Transformation, ...] | None = None, arrowhead_fill: NoneValueType | Color | None = white, arrowhead_filter: NoneValueType | Filter | None = None, arrowhead_stroke: NoneValueType | Color | None = black, arrowhead_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, arrowhead_stroke_dashoffset: NoneValueType | float | None = None, arrowhead_stroke_width: float | None = 1.25, arrowhead_transform: NoneValueType | tuple[Transformation, ...] | None = None, arrowhead_height: float = 10.0, arrowhead_width: float = 10.0)

Bases: SBGNSingleHeadedArc

Positive influence layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'22e82c6f-3cdc-497c-9331-7b43dcad948f'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
end_shorten float

The length the end of the arc will be shorten by

0.0
fill NoneValueType | Color | None

The fill color of the arc

None
filter_ NoneValueType | Filter | None

The filter of the arc

None
path_fill NoneValueType | Color | None

The path fill color of the arc

<momapy.drawing.NoneValueType object at 0x7fb1b7eb96a0>
path_filter NoneValueType | Filter | None

The path filter of the arc

None
path_stroke NoneValueType | Color | None

The path stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
path_stroke_dasharray NoneValueType | tuple[float, ...] | None

The path stroke dasharray of the arc

None
path_stroke_dashoffset NoneValueType | float | None

The path stroke dashoffset of the arc

None
path_stroke_width float | None

The path stroke width of the arc

1.25
path_transform NoneValueType | tuple[Transformation, ...] | None

The path transform of the arc

None
stroke NoneValueType | Color | None

The stroke color of the arc

None
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the arc

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the arc

None
stroke_width NoneValueType | float | None

The stroke width of the arc

None
segments tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...]

The path segments of the arc

<dynamic>
source LayoutElement | None

The source of the arc

None
start_shorten float

The length the start of the arc will be shorten by

0.0
target LayoutElement | None

The target of the arc

None
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the arc

None
arrowhead_fill NoneValueType | Color | None

The arrowhead fill color of the arc

Color(red=255, green=255, blue=255, alpha=1.0)
arrowhead_filter NoneValueType | Filter | None

The arrowhead filter of the arc

None
arrowhead_stroke NoneValueType | Color | None

The arrowhead stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
arrowhead_stroke_dasharray NoneValueType | tuple[float, ...] | None

The arrowhead stroke dasharray of the arc

None
arrowhead_stroke_dashoffset NoneValueType | float | None

The arrowhead stroke dashoffset of the arc

None
arrowhead_stroke_width float | None

The arrowhead stroke width of the arc

1.25
arrowhead_transform NoneValueType | tuple[Transformation, ...] | None

The arrowhead transform of the arc

None
arrowhead_height float

The height of the arrowhead.

10.0
arrowhead_width float

The width of the arrowhead.

10.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

arrowhead_base

Return the arrowhead base anchor point of the single-headed arc.

arrowhead_bbox

Return the bounding box of the single-headed arc arrowhead.

arrowhead_border

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

arrowhead_drawing_elements

Return the drawing elements of the single-headed arc arrowhead.

arrowhead_length

Return the length of the single-headed arc arrowhead.

arrowhead_tip

Return the arrowhead tip anchor point of the single-headed arc.

bbox

Compute and return the bounding box of the group layout element.

childless

Return a copy of the arc with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

end_point

Return the ending point of the arc.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

fraction

Return the position and angle on the arc at a given fraction (of the total arc length).

length

Return the total length of the arc path.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_children

Return the self children of the arc.

own_drawing_elements

Return the self drawing elements of the single-headed arc.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

path_drawing_elements

Return the drawing elements of the single-headed arc path.

points

Return the points of the arc path.

start_point

Return the starting point of the arc.

to_geometry

Return a list of geometry primitives from the drawing elements.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

arrowhead_base

arrowhead_base() -> Point

Return the arrowhead base anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_base(self) -> Point:
    """Return the arrowhead base anchor point of the single-headed arc."""
    arrowhead_length = self.arrowhead_length()
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return self.arrowhead_tip() - (arrowhead_length, 0)
    fraction = 1 - (arrowhead_length + self.end_shorten) / segment_length
    return segment.get_position_at_fraction(fraction)

arrowhead_bbox

arrowhead_bbox() -> Bbox

Return the bounding box of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_bbox(self) -> Bbox:
    """Return the bounding box of the single-headed arc arrowhead."""
    return get_drawing_elements_bbox(self.arrowhead_drawing_elements())

arrowhead_border

arrowhead_border(point: Point) -> Point

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def arrowhead_border(self, point: Point) -> Point:
    """Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    point = get_drawing_elements_border(self.arrowhead_drawing_elements(), point)
    if point is None:
        return self.arrowhead_tip()
    return point

arrowhead_drawing_elements

arrowhead_drawing_elements() -> list[DrawingElement]

Return the drawing elements of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_drawing_elements(
    self,
) -> list[DrawingElement]:
    """Return the drawing elements of the single-headed arc arrowhead."""
    drawing_elements = self._arrowhead_border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_arrowhead",
        elements=tuple(drawing_elements),
        fill=self.arrowhead_fill,
        filter_=self.arrowhead_filter,
        id_=f"{self.id_}_arrowhead",
        stroke=self.arrowhead_stroke,
        stroke_dasharray=self.arrowhead_stroke_dasharray,
        stroke_dashoffset=self.arrowhead_stroke_dashoffset,
        stroke_width=self.arrowhead_stroke_width,
        transform=self.arrowhead_transform,
    )
    transformation = self._get_arrowhead_transformation()
    group = group.transformed(transformation)
    return [group]

arrowhead_length

arrowhead_length() -> float

Return the length of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_length(self) -> float:
    """Return the length of the single-headed arc arrowhead."""
    bbox = get_drawing_elements_bbox(self._arrowhead_border_drawing_elements())
    if math.isnan(bbox.width):
        return 0.0
    return bbox.east().x

arrowhead_tip

arrowhead_tip() -> Point

Return the arrowhead tip anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_tip(self) -> Point:
    """Return the arrowhead tip anchor point of the single-headed arc."""
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return segment.p2
    fraction = 1 - self.end_shorten / segment_length
    return segment.get_position_at_fraction(fraction)

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

childless

childless() -> Self

Return a copy of the arc with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the arc with no children."""
    return dataclasses.replace(self, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

end_point

end_point() -> Point

Return the ending point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def end_point(self) -> Point:
    """Return the ending point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[-1]

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

fraction

fraction(fraction: float) -> tuple[Point, float]

Return the position and angle on the arc at a given fraction (of the total arc length).

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def fraction(self, fraction: float) -> tuple[Point, float]:
    """Return the position and angle on the arc at a given fraction (of the total arc length).

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    current_length = 0
    length_to_reach = fraction * self.length()
    for segment in self.segments:
        current_length += segment.length()
        if current_length >= length_to_reach:
            break
    segment_start_length = current_length - segment.length()
    segment_fraction = (length_to_reach - segment_start_length) / segment.length()
    position, angle = segment.get_position_and_angle_at_fraction(segment_fraction)
    return position, angle

length

length() -> float

Return the total length of the arc path.

Source code in src/momapy/core/layout.py
def length(self) -> float:
    """Return the total length of the arc path."""
    return sum([segment.length() for segment in self.segments])

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_children

own_children() -> list[LayoutElement]

Return the self children of the arc.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the arc."""
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the self drawing elements of the single-headed arc.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the self drawing elements of the single-headed arc."""
    drawing_elements = (
        self.path_drawing_elements() + self.arrowhead_drawing_elements()
    )
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

path_drawing_elements

path_drawing_elements() -> list[Path]

Return the drawing elements of the single-headed arc path.

Source code in src/momapy/core/layout.py
def path_drawing_elements(self) -> list[Path]:
    """Return the drawing elements of the single-headed arc path."""
    arrowhead_length = self.arrowhead_length()
    if len(self.segments) == 1:
        segment = (
            self.segments[0]
            .shortened(self.start_shorten, "start")
            .shortened(self.end_shorten + arrowhead_length, "end")
        )
        actions = [
            MoveTo(segment.p1),
            self._make_path_action_from_segment(segment),
        ]
    else:
        first_segment = self.segments[0].shortened(self.start_shorten, "start")
        last_segment = self.segments[-1].shortened(
            self.end_shorten + arrowhead_length, "end"
        )
        actions = [
            MoveTo(first_segment.p1),
            self._make_path_action_from_segment(first_segment),
        ]
        for segment in self.segments[1:-1]:
            action = self._make_path_action_from_segment(segment)
            actions.append(action)
        actions.append(self._make_path_action_from_segment(last_segment))
    path = Path(
        actions=tuple(actions),
        class_=f"{type(self).__name__}_path",
        fill=self.path_fill,
        filter_=self.path_filter,
        id_=f"{self.id_}_path",
        stroke=self.path_stroke,
        stroke_dasharray=self.path_stroke_dasharray,
        stroke_dashoffset=self.path_stroke_dashoffset,
        stroke_width=self.path_stroke_width,
        transform=self.path_transform,
    )
    return [path]

points

points() -> list[Point]

Return the points of the arc path.

An arc with no segments has no points and returns an empty list.

Source code in src/momapy/core/layout.py
def points(self) -> list[Point]:
    """Return the points of the arc path.

    An arc with no segments has no points and returns an empty list.
    """
    if not self.segments:
        return []
    points = []
    for segment in self.segments:
        points.append(segment.p1)
    points.append(segment.p2)
    return points

start_point

start_point() -> Point

Return the starting point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def start_point(self) -> Point:
    """Return the starting point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[0]

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

SBGNAFLayout dataclass

SBGNAFLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = None, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: NoneValueType | float | None = None, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float)

Bases: SBGNLayout

SBGN AF layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'0e97eaf8-6999-4d44-8ccf-67f9081defe5'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

required
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

None
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width NoneValueType | float | None

The stroke width of the node

None
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

required

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

is_sublayout

Return True if the layout is a sublayout of another given layout, False otherwise.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

is_sublayout

is_sublayout(other: Layout, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout is a sublayout of another given layout, False otherwise.

Source code in src/momapy/core/layout.py
def is_sublayout(
    self, other: "Layout", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout is a sublayout of another given layout, `False` otherwise."""

    def _is_sublist(
        list1: list[LayoutElement],
        list2: list[LayoutElement],
        unordered: bool = False,
    ) -> bool:
        if not unordered:
            i = 0
            for elem1 in list1:
                elem2 = list2[i]
                while elem2 != elem1 and i < len(list2) - 1:
                    i += 1
                    elem2 = list2[i]
                if not elem2 == elem1:
                    return False
                i += 1
        else:
            dlist1 = collections.defaultdict(int)
            dlist2 = collections.defaultdict(int)
            for elem1 in list1:
                dlist1[elem1] += 1
            for elem2 in list2:
                dlist2[elem2] += 1
            for elem in dlist1:
                if dlist1[elem] > dlist2[elem]:
                    return False
        return True

    if self.childless() != other.childless():
        return False
    if flattened:
        return _is_sublist(
            self.flattened()[1:],
            other.flattened()[1:],
            unordered=unordered,
        )
    return _is_sublist(self.children(), other.children(), unordered=unordered)

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

SBGNAFMap dataclass

SBGNAFMap(*, id_: str = make_uuid4_as_str(), model: SBGNAFModel | None = None, layout: SBGNAFLayout | None = None, layout_model_mapping: LayoutModelMapping | None = None)

Bases: SBGNMap

Class for SBGN-AF maps.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'317dd984-5c2b-460f-aa48-4839535f9345'
model SBGNAFModel | None

The model of the map

None
layout SBGNAFLayout | None

The layout of the map

None
layout_model_mapping LayoutModelMapping | None

The layout model mapping of the map

None

Methods:

Name Description
get_mapping

Return the model element or layout elements mapped to map_element.

is_submap

Return True if the Map is a submap of another given map, False otherwise.

get_mapping

get_mapping(map_element: MapElement) -> ModelElement | list[LayoutElement | frozenset[LayoutElement]] | None

Return the model element or layout elements mapped to map_element.

The lookup is bidirectional: a layout key (a singleton or frozenset) resolves to its model element, and a model element resolves to the list of layout keys mapped to it. Forwards to layout_model_mapping.get_mapping.

Returns None when the map has no layout_model_mapping (for example a layout-less map such as one read from SBML).

Source code in src/momapy/core/map.py
def get_mapping(
    self,
    map_element: "MapElement",
) -> "ModelElement | list[LayoutElement | frozenset[LayoutElement]] | None":
    """Return the model element or layout elements mapped to `map_element`.

    The lookup is bidirectional: a layout key (a singleton or frozenset)
    resolves to its model element, and a model element resolves to the
    list of layout keys mapped to it. Forwards to
    `layout_model_mapping.get_mapping`.

    Returns `None` when the map has no `layout_model_mapping` (for
    example a layout-less map such as one read from SBML).
    """
    if self.layout_model_mapping is None:
        return None
    return self.layout_model_mapping.get_mapping(map_element)

is_submap

is_submap(other: Map) -> bool

Return True if the Map is a submap of another given map, False otherwise.

A complete map is never a submap of an incomplete one: if either self or other has a None model, layout, or layout-model mapping, this returns False.

Source code in src/momapy/core/map.py
def is_submap(self, other: "Map") -> bool:
    """Return `True` if the `Map` is a submap of another given map, `False` otherwise.

    A complete map is never a submap of an incomplete one: if either `self`
    or `other` has a `None` model, layout, or layout-model mapping, this
    returns `False`.
    """
    if (
        self.model is None
        or self.layout is None
        or self.layout_model_mapping is None
        or other.model is None
        or other.layout is None
        or other.layout_model_mapping is None
    ):
        return False
    return (
        self.model.is_submodel(other.model)
        and self.layout.is_sublayout(other.layout)
        and self.layout_model_mapping.is_submapping(other.layout_model_mapping)
    )

SBGNAFModel dataclass

SBGNAFModel(*, id_: str = make_uuid4_as_str(), activities: frozenset[Activity] = frozenset(), compartments: frozenset[Compartment] = frozenset(), influences: frozenset[Influence] = frozenset(), logical_operators: frozenset[LogicalOperator] = frozenset(), submaps: frozenset[Submap] = frozenset(), tags: frozenset[Tag] = frozenset())

Bases: SBGNModel

SBGN AF model.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'c4d25e9d-45c7-48cd-8868-d172e5546f4f'
activities frozenset[Activity]

The activities of the SBGN-AF model.

<dynamic>
compartments frozenset[Compartment]

The compartments of the SBGN-AF model.

<dynamic>
influences frozenset[Influence]

The influences of the SBGN-AF model.

<dynamic>
logical_operators frozenset[LogicalOperator]

The logical operators of the SBGN-AF model.

<dynamic>
submaps frozenset[Submap]

The submaps of the SBGN-AF model.

<dynamic>
tags frozenset[Tag]

The tags of the SBGN-AF model.

<dynamic>

Methods:

Name Description
descendants

Return every ModelElement reachable from this Model.

is_submodel

Check if this model is a submodel of another model.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from this Model.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers of the Model, deduplicating by object identity. The Model itself is not a ModelElement and is not included.

This mirrors ModelElement.descendants and contrasts with LayoutElement.descendants, which walks the explicit children() tree (visual containment) rather than reference reachability.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order.

Source code in src/momapy/core/model.py
def descendants(self) -> list[ModelElement]:
    """Return every `ModelElement` reachable from this `Model`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers of the `Model`, deduplicating by
    object identity. The `Model` itself is not a `ModelElement` and is
    not included.

    This mirrors
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and contrasts with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which walks the explicit `children()` tree (visual *containment*)
    rather than reference reachability.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order.
    """
    seen: set[int] = set()
    result: list[ModelElement] = []
    for field in dataclasses.fields(type(self)):
        _walk_model_graph(getattr(self, field.name), seen, result)
    return result

is_submodel

is_submodel(other: SBGNAFModel) -> bool

Check if this model is a submodel of another model.

Parameters:

Name Type Description Default
other SBGNAFModel

Another SBGN-AF model to compare against.

required

Returns:

Type Description
bool

True if this model is a submodel of other, False otherwise.

Source code in src/momapy/sbgn/af/model.py
def is_submodel(self, other: "SBGNAFModel") -> bool:
    """Check if this model is a submodel of another model.

    Args:
        other: Another SBGN-AF model to compare against.

    Returns:
        True if this model is a submodel of `other`, False otherwise.
    """
    return (
        self.activities.issubset(other.activities)
        and self.compartments.issubset(other.compartments)
        and self.influences.issubset(other.influences)
        and self.logical_operators.issubset(other.logical_operators)
        and self.submaps.issubset(other.submaps)
        and self.tags.issubset(other.tags)
    )

SimpleChemicalUnitOfInformation dataclass

SimpleChemicalUnitOfInformation(*, id_: str = make_uuid4_as_str(), label: str | None = None)

Bases: UnitOfInformation

Simple chemical unit of information.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'3dded47c-635d-45cf-abae-5b83e48cd779'
label str | None

The label of the unit of information.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

SimpleChemicalUnitOfInformationLayout dataclass

SimpleChemicalUnitOfInformationLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 12.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 12.0)

Bases: _SimpleMixin, SBGNNode

Simple chemical unit of information layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'2f2857cc-2541-4e42-be4d-4a4056990ebc'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

12.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

12.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

Submap dataclass

Submap(*, id_: str = make_uuid4_as_str(), label: str | None = None, terminals: frozenset[Terminal] = frozenset())

Bases: SBGNModelElement

Submap.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'9e507ba6-b128-4d72-85a9-9ed83dcb4c50'
label str | None

The label of the submap.

None
terminals frozenset[Terminal]

The terminals of the submap.

<dynamic>

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

SubmapLayout dataclass

SubmapLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 80.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float = 2.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 80.0)

Bases: _SimpleMixin, SBGNNode

Submap layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'958ba947-95a9-4197-b093-221fb93d7ee6'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

80.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float

The stroke width of the node

2.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

80.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

Tag dataclass

Tag(*, id_: str = make_uuid4_as_str(), label: str | None = None, referred_element: TagReference | None = None)

Bases: SBGNModelElement

Tag.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'5377d23a-ff23-4f00-846e-d64515b0c512'
label str | None

The label of the tag.

None
referred_element TagReference | None

The element referred to by the tag.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

TagLayout dataclass

TagLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 35.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 35.0, direction: Direction = RIGHT, angle: float = 70.0)

Bases: _SimpleMixin, SBGNNode

Tag layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'a03b8c58-dfb9-4921-8e67-d1aa16ba9b0e'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

35.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

35.0
direction Direction

The direction the tag points to.

<Direction.RIGHT: 2>
angle float

The angle of the pointed side.

70.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
angle float

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle class-attribute instance-attribute

angle: float = dataclasses.field(default=70.0, metadata={'description': 'The angle of the pointed side.'})

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

TagReference dataclass

TagReference(*, id_: str = make_uuid4_as_str(), referred_element: Activity | Compartment)

Bases: SBGNRole

Tag reference.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'6516c662-5d23-4eeb-b537-dacf9cdddb0a'
referred_element Activity | Compartment

The activity or compartment being referenced.

required

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

Terminal dataclass

Terminal(*, id_: str = make_uuid4_as_str(), label: str | None = None, referred_element: TerminalReference | None = None)

Bases: SBGNAuxiliaryUnit

Terminal.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'9f3c054b-0ef4-47b7-b142-a332b92671f8'
label str | None

The label of the terminal.

None
referred_element TerminalReference | None

The element referred to by the terminal.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

TerminalLayout dataclass

TerminalLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 35.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 35.0, direction: Direction = RIGHT, angle: float = 70.0)

Bases: _SimpleMixin, SBGNNode

Terminal layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'8a5188f9-bcbe-44af-bd03-89a31ca740cd'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

35.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

35.0
direction Direction

The direction the terminal points to.

<Direction.RIGHT: 2>
angle float

The angle of the notched side.

70.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
angle float

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle class-attribute instance-attribute

angle: float = dataclasses.field(default=70.0, metadata={'description': 'The angle of the notched side.'})

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

TerminalReference dataclass

TerminalReference(*, id_: str = make_uuid4_as_str(), referred_element: Activity | Compartment)

Bases: SBGNRole

Terminal reference.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'8c85e800-cc14-44d4-85fb-99843ba9f197'
referred_element Activity | Compartment

The activity or compartment being referenced.

required

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

UnitOfInformation dataclass

UnitOfInformation(*, id_: str = make_uuid4_as_str(), label: str | None = None)

Bases: SBGNAuxiliaryUnit

Abstract base class for units of information.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'd9e74d66-99c4-4044-9637-02dba86f21cb'
label str | None

The label of the unit of information.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

UnitOfInformationLayout dataclass

UnitOfInformationLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 12.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 18.0)

Bases: _SimpleMixin, SBGNNode

Unit of information layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'81eebb20-a689-473a-b51c-c6e0ea1621fa'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

12.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

18.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.

UnknownInfluence dataclass

UnknownInfluence(*, id_: str = make_uuid4_as_str(), source: BiologicalActivity | LogicalOperator, target: Activity)

Bases: Influence

Unknown influence.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'792cc74c-b759-4fdc-ae4a-0ce541abd67c'
source BiologicalActivity | LogicalOperator

The source activity or logical operator.

required
target Activity

The target activity being influenced.

required

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

UnknownInfluenceLayout dataclass

UnknownInfluenceLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, end_shorten: float = 0.0, fill: NoneValueType | Color | None = None, filter_: NoneValueType | Filter | None = None, path_fill: NoneValueType | Color | None = NoneValue, path_filter: NoneValueType | Filter | None = None, path_stroke: NoneValueType | Color | None = black, path_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, path_stroke_dashoffset: NoneValueType | float | None = None, path_stroke_width: float | None = 1.25, path_transform: NoneValueType | tuple[Transformation, ...] | None = None, stroke: NoneValueType | Color | None = None, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: NoneValueType | float | None = None, segments: tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...] = tuple(), source: LayoutElement | None = None, start_shorten: float = 0.0, target: LayoutElement | None = None, transform: NoneValueType | tuple[Transformation, ...] | None = None, arrowhead_fill: NoneValueType | Color | None = white, arrowhead_filter: NoneValueType | Filter | None = None, arrowhead_stroke: NoneValueType | Color | None = black, arrowhead_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, arrowhead_stroke_dashoffset: NoneValueType | float | None = None, arrowhead_stroke_width: float | None = 1.25, arrowhead_transform: NoneValueType | tuple[Transformation, ...] | None = None, arrowhead_height: float = 10.0, arrowhead_width: float = 10.0)

Bases: SBGNSingleHeadedArc

Unknown influence layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'c065db0c-adfe-4e1a-b081-08fb5040ad7a'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
end_shorten float

The length the end of the arc will be shorten by

0.0
fill NoneValueType | Color | None

The fill color of the arc

None
filter_ NoneValueType | Filter | None

The filter of the arc

None
path_fill NoneValueType | Color | None

The path fill color of the arc

<momapy.drawing.NoneValueType object at 0x7fb1b7eb96a0>
path_filter NoneValueType | Filter | None

The path filter of the arc

None
path_stroke NoneValueType | Color | None

The path stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
path_stroke_dasharray NoneValueType | tuple[float, ...] | None

The path stroke dasharray of the arc

None
path_stroke_dashoffset NoneValueType | float | None

The path stroke dashoffset of the arc

None
path_stroke_width float | None

The path stroke width of the arc

1.25
path_transform NoneValueType | tuple[Transformation, ...] | None

The path transform of the arc

None
stroke NoneValueType | Color | None

The stroke color of the arc

None
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the arc

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the arc

None
stroke_width NoneValueType | float | None

The stroke width of the arc

None
segments tuple[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc, ...]

The path segments of the arc

<dynamic>
source LayoutElement | None

The source of the arc

None
start_shorten float

The length the start of the arc will be shorten by

0.0
target LayoutElement | None

The target of the arc

None
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the arc

None
arrowhead_fill NoneValueType | Color | None

The arrowhead fill color of the arc

Color(red=255, green=255, blue=255, alpha=1.0)
arrowhead_filter NoneValueType | Filter | None

The arrowhead filter of the arc

None
arrowhead_stroke NoneValueType | Color | None

The arrowhead stroke color of the arc

Color(red=0, green=0, blue=0, alpha=1.0)
arrowhead_stroke_dasharray NoneValueType | tuple[float, ...] | None

The arrowhead stroke dasharray of the arc

None
arrowhead_stroke_dashoffset NoneValueType | float | None

The arrowhead stroke dashoffset of the arc

None
arrowhead_stroke_width float | None

The arrowhead stroke width of the arc

1.25
arrowhead_transform NoneValueType | tuple[Transformation, ...] | None

The arrowhead transform of the arc

None
arrowhead_height float

The height of the arrowhead.

10.0
arrowhead_width float

The width of the arrowhead.

10.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

arrowhead_base

Return the arrowhead base anchor point of the single-headed arc.

arrowhead_bbox

Return the bounding box of the single-headed arc arrowhead.

arrowhead_border

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

arrowhead_drawing_elements

Return the drawing elements of the single-headed arc arrowhead.

arrowhead_length

Return the length of the single-headed arc arrowhead.

arrowhead_tip

Return the arrowhead tip anchor point of the single-headed arc.

bbox

Compute and return the bounding box of the group layout element.

childless

Return a copy of the arc with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

end_point

Return the ending point of the arc.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

fraction

Return the position and angle on the arc at a given fraction (of the total arc length).

length

Return the total length of the arc path.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_children

Return the self children of the arc.

own_drawing_elements

Return the self drawing elements of the single-headed arc.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

path_drawing_elements

Return the drawing elements of the single-headed arc path.

points

Return the points of the arc path.

start_point

Return the starting point of the arc.

to_geometry

Return a list of geometry primitives from the drawing elements.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

arrowhead_base

arrowhead_base() -> Point

Return the arrowhead base anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_base(self) -> Point:
    """Return the arrowhead base anchor point of the single-headed arc."""
    arrowhead_length = self.arrowhead_length()
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return self.arrowhead_tip() - (arrowhead_length, 0)
    fraction = 1 - (arrowhead_length + self.end_shorten) / segment_length
    return segment.get_position_at_fraction(fraction)

arrowhead_bbox

arrowhead_bbox() -> Bbox

Return the bounding box of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_bbox(self) -> Bbox:
    """Return the bounding box of the single-headed arc arrowhead."""
    return get_drawing_elements_bbox(self.arrowhead_drawing_elements())

arrowhead_border

arrowhead_border(point: Point) -> Point

Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def arrowhead_border(self, point: Point) -> Point:
    """Return the point at the intersection of the drawing elements of the single-headed arc arrowhead and the line going through the center of these drawing elements and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    point = get_drawing_elements_border(self.arrowhead_drawing_elements(), point)
    if point is None:
        return self.arrowhead_tip()
    return point

arrowhead_drawing_elements

arrowhead_drawing_elements() -> list[DrawingElement]

Return the drawing elements of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_drawing_elements(
    self,
) -> list[DrawingElement]:
    """Return the drawing elements of the single-headed arc arrowhead."""
    drawing_elements = self._arrowhead_border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_arrowhead",
        elements=tuple(drawing_elements),
        fill=self.arrowhead_fill,
        filter_=self.arrowhead_filter,
        id_=f"{self.id_}_arrowhead",
        stroke=self.arrowhead_stroke,
        stroke_dasharray=self.arrowhead_stroke_dasharray,
        stroke_dashoffset=self.arrowhead_stroke_dashoffset,
        stroke_width=self.arrowhead_stroke_width,
        transform=self.arrowhead_transform,
    )
    transformation = self._get_arrowhead_transformation()
    group = group.transformed(transformation)
    return [group]

arrowhead_length

arrowhead_length() -> float

Return the length of the single-headed arc arrowhead.

Source code in src/momapy/core/layout.py
def arrowhead_length(self) -> float:
    """Return the length of the single-headed arc arrowhead."""
    bbox = get_drawing_elements_bbox(self._arrowhead_border_drawing_elements())
    if math.isnan(bbox.width):
        return 0.0
    return bbox.east().x

arrowhead_tip

arrowhead_tip() -> Point

Return the arrowhead tip anchor point of the single-headed arc.

Source code in src/momapy/core/layout.py
def arrowhead_tip(self) -> Point:
    """Return the arrowhead tip anchor point of the single-headed arc."""
    segment = self.segments[-1]
    segment_length = segment.length()
    if segment_length == 0:
        return segment.p2
    fraction = 1 - self.end_shorten / segment_length
    return segment.get_position_at_fraction(fraction)

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

childless

childless() -> Self

Return a copy of the arc with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the arc with no children."""
    return dataclasses.replace(self, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

end_point

end_point() -> Point

Return the ending point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def end_point(self) -> Point:
    """Return the ending point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[-1]

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

fraction

fraction(fraction: float) -> tuple[Point, float]

Return the position and angle on the arc at a given fraction (of the total arc length).

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def fraction(self, fraction: float) -> tuple[Point, float]:
    """Return the position and angle on the arc at a given fraction (of the total arc length).

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    current_length = 0
    length_to_reach = fraction * self.length()
    for segment in self.segments:
        current_length += segment.length()
        if current_length >= length_to_reach:
            break
    segment_start_length = current_length - segment.length()
    segment_fraction = (length_to_reach - segment_start_length) / segment.length()
    position, angle = segment.get_position_and_angle_at_fraction(segment_fraction)
    return position, angle

length

length() -> float

Return the total length of the arc path.

Source code in src/momapy/core/layout.py
def length(self) -> float:
    """Return the total length of the arc path."""
    return sum([segment.length() for segment in self.segments])

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_children

own_children() -> list[LayoutElement]

Return the self children of the arc.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the arc."""
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the self drawing elements of the single-headed arc.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the self drawing elements of the single-headed arc."""
    drawing_elements = (
        self.path_drawing_elements() + self.arrowhead_drawing_elements()
    )
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

path_drawing_elements

path_drawing_elements() -> list[Path]

Return the drawing elements of the single-headed arc path.

Source code in src/momapy/core/layout.py
def path_drawing_elements(self) -> list[Path]:
    """Return the drawing elements of the single-headed arc path."""
    arrowhead_length = self.arrowhead_length()
    if len(self.segments) == 1:
        segment = (
            self.segments[0]
            .shortened(self.start_shorten, "start")
            .shortened(self.end_shorten + arrowhead_length, "end")
        )
        actions = [
            MoveTo(segment.p1),
            self._make_path_action_from_segment(segment),
        ]
    else:
        first_segment = self.segments[0].shortened(self.start_shorten, "start")
        last_segment = self.segments[-1].shortened(
            self.end_shorten + arrowhead_length, "end"
        )
        actions = [
            MoveTo(first_segment.p1),
            self._make_path_action_from_segment(first_segment),
        ]
        for segment in self.segments[1:-1]:
            action = self._make_path_action_from_segment(segment)
            actions.append(action)
        actions.append(self._make_path_action_from_segment(last_segment))
    path = Path(
        actions=tuple(actions),
        class_=f"{type(self).__name__}_path",
        fill=self.path_fill,
        filter_=self.path_filter,
        id_=f"{self.id_}_path",
        stroke=self.path_stroke,
        stroke_dasharray=self.path_stroke_dasharray,
        stroke_dashoffset=self.path_stroke_dashoffset,
        stroke_width=self.path_stroke_width,
        transform=self.path_transform,
    )
    return [path]

points

points() -> list[Point]

Return the points of the arc path.

An arc with no segments has no points and returns an empty list.

Source code in src/momapy/core/layout.py
def points(self) -> list[Point]:
    """Return the points of the arc path.

    An arc with no segments has no points and returns an empty list.
    """
    if not self.segments:
        return []
    points = []
    for segment in self.segments:
        points.append(segment.p1)
    points.append(segment.p2)
    return points

start_point

start_point() -> Point

Return the starting point of the arc.

Raises:

Type Description
ValueError

If the arc has no segments.

Source code in src/momapy/core/layout.py
def start_point(self) -> Point:
    """Return the starting point of the arc.

    Raises:
        ValueError: If the arc has no segments.
    """
    if not self.segments:
        raise ValueError("arc has no segments")
    return self.points()[0]

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

UnspecifiedEntityUnitOfInformation dataclass

UnspecifiedEntityUnitOfInformation(*, id_: str = make_uuid4_as_str(), label: str | None = None)

Bases: UnitOfInformation

Unspecified entity unit of information.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'36d927d2-189a-4f5d-ad67-5d7576311658'
label str | None

The label of the unit of information.

None

Methods:

Name Description
descendants

Return every ModelElement reachable from self, excluding self.

descendants

descendants() -> list[ModelElement]

Return every ModelElement reachable from self, excluding self.

This reflectively walks the dataclass field-graph (i.e. reference reachability) across scalar ModelElement fields and frozenset/tuple containers, deduplicating by object identity. A model element referenced by several parents therefore appears once.

Note the deliberate contrast with LayoutElement.descendants, which instead walks the explicit children() tree (visual containment): there a layout element contained under two parents is reached through each, with no identity dedup.

Returns:

Type Description
list[ModelElement]

The list of reachable ModelElement instances in visit

list[ModelElement]

order, without self.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["ModelElement"]:
    """Return every `ModelElement` reachable from `self`, excluding `self`.

    This reflectively walks the dataclass field-graph (i.e. *reference
    reachability*) across scalar `ModelElement` fields and
    `frozenset`/`tuple` containers, deduplicating by object identity. A
    model element referenced by several parents therefore appears once.

    Note the deliberate contrast with
    [`LayoutElement.descendants`][momapy.core.elements.LayoutElement.descendants],
    which instead walks the explicit `children()` tree (visual
    *containment*): there a layout element contained under two parents is
    reached through each, with no identity dedup.

    Returns:
        The list of reachable `ModelElement` instances in visit
        order, without `self`.
    """
    seen: set[int] = {id(self)}
    result: list[ModelElement] = []
    if dataclasses.is_dataclass(self):
        for field in dataclasses.fields(type(self)):
            _walk_model_graph(getattr(self, field.name), seen, result)
    return result

UnspecifiedEntityUnitOfInformationLayout dataclass

UnspecifiedEntityUnitOfInformationLayout(*, id_: str = make_uuid4_as_str(), layout_elements: tuple[LayoutElement, ...] = tuple(), group_fill: NoneValueType | Color | None = None, group_fill_rule: FillRule | None = None, group_filter: NoneValueType | Filter | None = None, group_font_family: str | None = None, group_font_size: float | None = None, group_font_style: FontStyle | None = None, group_font_weight: FontWeight | float | None = None, group_stroke: NoneValueType | Color | None = None, group_stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, group_stroke_dashoffset: NoneValueType | float | None = None, group_stroke_width: NoneValueType | float | None = None, group_text_anchor: TextAnchor | None = None, group_transform: NoneValueType | tuple[Transformation, ...] | None = None, fill: NoneValueType | Color | None = white, filter_: NoneValueType | Filter | None = None, height: float = 12.0, label: TextLayout | None = None, position: Point, stroke: NoneValueType | Color | None = black, stroke_dasharray: NoneValueType | tuple[float, ...] | None = None, stroke_dashoffset: NoneValueType | float | None = None, stroke_width: float | None = 1.25, transform: NoneValueType | tuple[Transformation, ...] | None = None, width: float = 18.0)

Bases: _SimpleMixin, SBGNNode

Unspecified entity unit of information layout.

Parameters:

Name Type Description Default
id_ str

The id of the map element. This id is purely for the user to keep track of the element, it does not need to be unique and is not part of the identity of the element, i.e., it is not considered when testing for equality between two map elements or when hashing the map element

'ceba0879-0128-4dcb-9934-46150fe49c01'
layout_elements tuple[LayoutElement, ...]

The sub-layout elements of the group layout. These are part of the children of the group layout

<dynamic>
group_fill NoneValueType | Color | None

The fill color of the group layout

None
group_fill_rule FillRule | None

The fill rule of the group layout

None
group_filter NoneValueType | Filter | None

The filter of the group layout

None
group_font_family str | None

The font family of the group layout

None
group_font_size float | None

The font size of the group layout

None
group_font_style FontStyle | None

The font style of the group layout

None
group_font_weight FontWeight | float | None

The font weight of the group layout

None
group_stroke NoneValueType | Color | None

The stroke color of the group layout

None
group_stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the group layout

None
group_stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the group layout

None
group_stroke_width NoneValueType | float | None

The stroke width of the group layout

None
group_text_anchor TextAnchor | None

The text anchor of the group layout

None
group_transform NoneValueType | tuple[Transformation, ...] | None

The transform of the group layout

None
fill NoneValueType | Color | None

The fill color of the node

Color(red=255, green=255, blue=255, alpha=1.0)
filter_ NoneValueType | Filter | None

The filter of the node

None
height float

The height of the node

12.0
label TextLayout | None

The label of the node

None
position Point

The position of the node

required
stroke NoneValueType | Color | None

The stroke color of the node

Color(red=0, green=0, blue=0, alpha=1.0)
stroke_dasharray NoneValueType | tuple[float, ...] | None

The stroke dasharray of the node

None
stroke_dashoffset NoneValueType | float | None

The stroke dashoffset of the node

None
stroke_width float | None

The stroke width of the node

1.25
transform NoneValueType | tuple[Transformation, ...] | None

The transform of the node

None
width float

The width of the node

18.0

Methods:

Name Description
anchor_point

Return an anchor point of the layout element.

angle

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

bbox

Compute and return the bounding box of the group layout element.

border

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

center

Return the center anchor of the node.

childless

Return a copy of the node with no children.

children

Return the children of the group layout.

contains

Return True if another layout element is a descendant of the layout element, False otherwise.

descendants

Return the descendants of the layout element.

drawing_elements

Return the drawing elements of the group layout.

east

Return the east anchor of the node.

east_north_east

Return the east north east anchor of the node.

east_south_east

Return the east south east anchor of the node.

equals

Return True if the layout element is equal to another layout element, False otherwise.

flattened

Return a list containing copy of the layout element with no children and all its descendants with no children.

label_center

Return the label center anchor of the node.

north

Return the north anchor of the node.

north_east

Return the north east anchor of the node.

north_north_east

Return the north north east anchor of the node.

north_north_west

Return the north north west anchor of the node.

north_west

Return the north west anchor of the node.

own_angle

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

own_bbox

Compute and return the bounding box of the self drawing element of the group layout.

own_border

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

own_children

Return the self children of the node. A node has unique child that is its label.

own_drawing_elements

Return the node's own drawing elements.

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

size

Return the size of the node.

south

Return the south anchor of the node.

south_east

Return the south east anchor of the node.

south_south_east

Return the south south east anchor of the node.

south_south_west

Return the south south west anchor of the node.

south_west

Return the south west anchor of the node.

to_geometry

Return a list of geometry primitives from the drawing elements.

west

Return the west anchor of the node.

west_north_west

Return the west north west anchor of the node.

west_south_west

Return the west south west anchor of the node.

Attributes:

Name Type Description
x float

Return the x coordinate of the node.

y float

Return the y coordinate of the node.

anchor_point

anchor_point(anchor_name: str) -> Point

Return an anchor point of the layout element.

Source code in src/momapy/core/elements.py
def anchor_point(self, anchor_name: str) -> Point:
    """Return an anchor point of the layout element."""
    return getattr(self, anchor_name)()

angle

angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

bbox

bbox() -> Bbox

Compute and return the bounding box of the group layout element.

Source code in src/momapy/core/layout.py
def bbox(self) -> Bbox:
    """Compute and return the bounding box of the group layout element."""
    own_bbox = self.own_bbox()
    bboxes = [child.bbox() for child in self.children()]
    min_x = own_bbox.north_west().x
    min_y = own_bbox.north_west().y
    max_x = own_bbox.south_east().x
    max_y = own_bbox.south_east().y
    for bbox in bboxes:
        if bbox.north_west().x < min_x:
            min_x = bbox.north_west().x
        if bbox.north_west().y < min_y:
            min_y = bbox.north_west().y
        if bbox.south_east().x > max_x:
            max_x = bbox.south_east().x
        if bbox.south_east().y > max_y:
            max_y = bbox.south_east().y
    bbox = Bbox(
        Point(min_x / 2 + max_x / 2, min_y / 2 + max_y / 2),
        max_x - min_x,
        max_y - min_y,
    )
    return bbox

border

border(point: Point) -> Point | None

Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.drawing_elements(),
        point=point,
        center=self.center(),
    )

center

center() -> Point

Return the center anchor of the node.

Source code in src/momapy/core/layout.py
def center(self) -> Point:
    """Return the center anchor of the node."""
    return self.position

childless

childless() -> Self

Return a copy of the node with no children.

Source code in src/momapy/core/layout.py
def childless(self) -> typing_extensions.Self:
    """Return a copy of the node with no children."""
    return dataclasses.replace(self, label=None, layout_elements=tuple([]))

children

children() -> list[LayoutElement]

Return the children of the group layout.

These are the self children of the group layout (returned by the own_children method) and the other children of the group layout (given by the layout_elements attribute).

Source code in src/momapy/core/layout.py
def children(self) -> list[LayoutElement]:
    """Return the children of the group layout.

    These are the self children of the group layout (returned by the `own_children` method) and the other children of the group layout (given by the `layout_elements` attribute).
    """
    return self.own_children() + list(self.layout_elements)

contains

contains(other: LayoutElement) -> bool

Return True if another layout element is a descendant of the layout element, False otherwise.

Source code in src/momapy/core/elements.py
def contains(self, other: "LayoutElement") -> bool:
    """Return `True` if another layout element is a descendant of the layout element, `False` otherwise."""
    return other in self.descendants()

descendants

descendants() -> list[LayoutElement]

Return the descendants of the layout element.

This walks the explicit children() tree (i.e. visual containment) depth-first, returning every layout element in the contained subtree (without self).

Note the deliberate contrast with ModelElement.descendants and Model.descendants, which reflectively walk the dataclass field-graph (i.e. reference reachability) and deduplicate by object identity. A model element referenced by several parents therefore appears once across the model graph, whereas layout descendants are strictly the contained subtree and a layout element contained under two parents is reached through each.

Returns:

Type Description
list[LayoutElement]

The list of descendant layout elements in visit order.

Source code in src/momapy/core/elements.py
def descendants(self) -> list["LayoutElement"]:
    """Return the descendants of the layout element.

    This walks the explicit `children()` tree (i.e. visual
    *containment*) depth-first, returning every layout element in the
    contained subtree (without `self`).

    Note the deliberate contrast with
    [`ModelElement.descendants`][momapy.core.elements.ModelElement.descendants]
    and [`Model.descendants`][momapy.core.model.Model.descendants],
    which reflectively walk the dataclass field-graph (i.e. *reference
    reachability*) and deduplicate by object identity. A model element
    referenced by several parents therefore appears once across the
    model graph, whereas layout descendants are strictly the contained
    subtree and a layout element contained under two parents is reached
    through each.

    Returns:
        The list of descendant layout elements in visit order.
    """
    descendants = []
    for child in self.children():
        descendants.append(child)
        descendants += child.descendants()
    return descendants

drawing_elements

drawing_elements() -> list[DrawingElement]

Return the drawing elements of the group layout.

The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.

Source code in src/momapy/core/layout.py
def drawing_elements(self) -> list[DrawingElement]:
    """Return the drawing elements of the group layout.

    The returned drawing elements are a group drawing element formed of the self drawing elements of the group layout and the drawing elements of its children.
    """
    drawing_elements = self.own_drawing_elements()
    for child in self.children():
        if child is not None:
            drawing_elements += child.drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}",
        elements=tuple(drawing_elements),
        id_=f"{self.id_}",
        fill=self.group_fill,
        fill_rule=self.group_fill_rule,
        filter_=self.group_filter,
        font_family=self.group_font_family,
        font_size=self.group_font_size,
        font_style=self.group_font_style,
        font_weight=self.group_font_weight,
        stroke=self.group_stroke,
        stroke_dasharray=self.group_stroke_dasharray,
        stroke_dashoffset=self.group_stroke_dashoffset,
        stroke_width=self.group_stroke_width,
        text_anchor=self.group_text_anchor,
        transform=self.group_transform,
    )
    return [group]

east

east() -> Point

Return the east anchor of the node.

Source code in src/momapy/core/layout.py
def east(self) -> Point:
    """Return the east anchor of the node."""
    return self.own_angle(0)

east_north_east

east_north_east() -> Point

Return the east north east anchor of the node.

Source code in src/momapy/core/layout.py
def east_north_east(self) -> Point:
    """Return the east north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

east_south_east

east_south_east() -> Point

Return the east south east anchor of the node.

Source code in src/momapy/core/layout.py
def east_south_east(self) -> Point:
    """Return the east south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

equals

equals(other: LayoutElement, flattened: bool = False, unordered: bool = False) -> bool

Return True if the layout element is equal to another layout element, False otherwise.

Source code in src/momapy/core/elements.py
def equals(
    self, other: "LayoutElement", flattened: bool = False, unordered: bool = False
) -> bool:
    """Return `True` if the layout element is equal to another layout element, `False` otherwise."""
    if type(self) is type(other):
        if not flattened:
            return self == other
        else:
            if not unordered:
                return self.flattened() == other.flattened()
            else:
                return set(self.flattened()) == set(other.flattened())
    return False

flattened

flattened() -> list[LayoutElement]

Return a list containing copy of the layout element with no children and all its descendants with no children.

Source code in src/momapy/core/elements.py
def flattened(self) -> list["LayoutElement"]:
    """Return a list containing copy of the layout element with no children and all its descendants with no children."""
    flattened = [self.childless()]
    for child in self.children():
        flattened += child.flattened()
    return flattened

label_center

label_center() -> Point

Return the label center anchor of the node.

Source code in src/momapy/core/layout.py
def label_center(self) -> Point:
    """Return the label center anchor of the node."""
    return self.position

north

north() -> Point

Return the north anchor of the node.

Source code in src/momapy/core/layout.py
def north(self) -> Point:
    """Return the north anchor of the node."""
    return self.own_angle(90)

north_east

north_east() -> Point

Return the north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_east(self) -> Point:
    """Return the north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_east

north_north_east() -> Point

Return the north north east anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_east(self) -> Point:
    """Return the north north east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, -self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_north_west

north_north_west() -> Point

Return the north north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_north_west(self) -> Point:
    """Return the north north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

north_west

north_west() -> Point

Return the north west anchor of the node.

Source code in src/momapy/core/layout.py
def north_west(self) -> Point:
    """Return the north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

own_angle

own_angle(angle: float, unit: Literal['degrees', 'radians'] = 'degrees') -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal.

Source code in src/momapy/core/layout.py
def own_angle(
    self,
    angle: float,
    unit: typing.Literal["degrees", "radians"] = "degrees",
) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line passing through the center anchor point of the node and at a given angle from the horizontal."""
    return get_drawing_elements_angle(
        drawing_elements=self.own_drawing_elements(),
        angle=angle,
        unit=unit,
        center=self.center(),
    )

own_bbox

own_bbox() -> Bbox

Compute and return the bounding box of the self drawing element of the group layout.

Source code in src/momapy/core/layout.py
def own_bbox(self) -> Bbox:
    """Compute and return the bounding box of the self drawing element of the group layout."""
    primitives = self.own_to_geometry()
    if not primitives:
        return Bbox(Point(0.0, 0.0), 0, 0)
    bboxes = [p.bbox() for p in primitives]
    return Bbox.union(bboxes)

own_border

own_border(point: Point) -> Point | None

Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

When there are multiple intersection points, the one closest to the given point is returned.

Source code in src/momapy/core/layout.py
def own_border(self, point: Point) -> Point | None:
    """Return the point on the border of the node that intersects the self drawing elements of the node with the line formed of the center anchor point of the node and the given point.

    When there are multiple intersection points, the one closest to the given point is returned.
    """
    return get_drawing_elements_border(
        drawing_elements=self.own_drawing_elements(),
        point=point,
        center=self.center(),
    )

own_children

own_children() -> list[LayoutElement]

Return the self children of the node. A node has unique child that is its label.

Source code in src/momapy/core/layout.py
def own_children(self) -> list[LayoutElement]:
    """Return the self children of the node. A node has unique child that is its label."""
    if self.label is not None:
        return [self.label]
    return []

own_drawing_elements

own_drawing_elements() -> list[DrawingElement]

Return the node's own drawing elements.

Source code in src/momapy/core/layout.py
def own_drawing_elements(self) -> list[DrawingElement]:
    """Return the node's own drawing elements."""
    drawing_elements = self._border_drawing_elements()
    group = Group(
        class_=f"{type(self).__name__}_own",
        elements=tuple(drawing_elements),
        fill=self.fill,
        filter_=self.filter_,
        id_=f"{self.id_}_own",
        stroke=self.stroke,
        stroke_dasharray=self.stroke_dasharray,
        stroke_dashoffset=self.stroke_dashoffset,
        stroke_width=self.stroke_width,
        transform=self.transform,
    )
    return [group]

own_to_geometry

Return a list of geometry primitives from the self drawing elements.

Source code in src/momapy/core/layout.py
def own_to_geometry(
    self,
) -> list[
    Segment | QuadraticBezierCurve | CubicBezierCurve | GeometryEllipticalArc
]:
    """Return a list of geometry primitives from the self drawing elements."""
    return drawing_elements_to_geometry(self.own_drawing_elements())

size

size() -> tuple[float, float]

Return the size of the node.

Source code in src/momapy/core/layout.py
def size(self) -> tuple[float, float]:
    """Return the size of the node."""
    return (self.width, self.height)

south

south() -> Point

Return the south anchor of the node.

Source code in src/momapy/core/layout.py
def south(self) -> Point:
    """Return the south anchor of the node."""
    return self.own_angle(270)

south_east

south_east() -> Point

Return the south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_east(self) -> Point:
    """Return the south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_east

south_south_east() -> Point

Return the south south east anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_east(self) -> Point:
    """Return the south south east anchor of the node."""
    line = Line(self.center(), self.center() + (self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_south_west

south_south_west() -> Point

Return the south south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_south_west(self) -> Point:
    """Return the south south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 4, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

south_west

south_west() -> Point

Return the south west anchor of the node.

Source code in src/momapy/core/layout.py
def south_west(self) -> Point:
    """Return the south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 2))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

to_geometry

Return a list of geometry primitives from the drawing elements.

Source code in src/momapy/core/elements.py
def to_geometry(
    self,
) -> list[Segment | QuadraticBezierCurve | CubicBezierCurve | EllipticalArc]:
    """Return a list of geometry primitives from the drawing elements."""
    return drawing_elements_to_geometry(self.drawing_elements())

west

west() -> Point

Return the west anchor of the node.

Source code in src/momapy/core/layout.py
def west(self) -> Point:
    """Return the west anchor of the node."""
    return self.own_angle(180)

west_north_west

west_north_west() -> Point

Return the west north west anchor of the node.

Source code in src/momapy/core/layout.py
def west_north_west(self) -> Point:
    """Return the west north west anchor of the node."""
    line = Line(self.center(), self.center() - (self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

west_south_west

west_south_west() -> Point

Return the west south west anchor of the node.

Source code in src/momapy/core/layout.py
def west_south_west(self) -> Point:
    """Return the west south west anchor of the node."""
    line = Line(self.center(), self.center() + (-self.width / 2, self.height / 4))
    angle = -line.get_angle_to_horizontal()
    return self.own_angle(angle, unit="radians")

x property

x: float

Return the x coordinate of the node.

y property

y: float

Return the y coordinate of the node.