Source code for molfoundry.vertexmap
from typing import Iterator, List, Optional
import molfoundry.rule as rule
from .core import TSObject
from .graph import Vertex
_class_ref = TSObject.get_class_ref("VertexMap")
[docs]
class VertexMapEntry:
"""One atom of an atom-atom map.
``source`` is the educt atom and ``target`` the product atom. A ``source`` of
``None`` means the rule created the atom, a ``target`` of ``None`` that it
destroyed it. ``sourceInstance`` and ``targetInstance`` say which copy of its
species the atom belongs to, 1-based, since a hyperedge may consume or
produce several copies of the same molecule. ``ruleNodeId`` is the rule
vertex the atom plays, or ``None`` for an atom the rule does not name.
"""
__slots__ = ("source", "sourceInstance", "target", "targetInstance", "ruleNodeId")
def __init__(self, source: Optional[Vertex], sourceInstance: int,
target: Optional[Vertex], targetInstance: int,
ruleNodeId: Optional[int]) -> None:
self.source = source
self.sourceInstance = sourceInstance
self.target = target
self.targetInstance = targetInstance
self.ruleNodeId = ruleNodeId
def __repr__(self) -> str:
def side(v: Optional[Vertex], instance: int) -> str:
return "None" if v is None else f"{v.stringLabel}#{v.id}/{instance}"
return (f"VertexMapEntry({side(self.source, self.sourceInstance)} -> "
f"{side(self.target, self.targetInstance)}, rule={self.ruleNodeId})")
[docs]
class VertexMap(TSObject):
"""An atom-atom map of a hyperedge, as a sequence of :class:`VertexMapEntry`."""
def __init__(self) -> None:
super().__init__(_class_ref)
@property
def rule(self) -> "rule.Rule":
return rule.Rule.wrap(self._ref.getRule())
[docs]
def reactionSMILES(self, explicit_hydrogens: bool = False) -> str:
"""A reaction SMILES ``educts>>products`` built from this atom-atom map.
Every atom the map pairs carries a shared atom-map number linking its educt
and product occurrence (``[C:1]``); atoms the reaction creates, destroys, or
otherwise leaves unpaired carry none, so a partial map renders too. Set
``explicit_hydrogens`` to write hydrogens as their own atoms rather than
folding them into a neighbor's bracket.
"""
return str(self._ref.getReactionSMILES(explicit_hydrogens))
[docs]
def entries(self) -> List[VertexMapEntry]:
def vertex(v) -> Optional[Vertex]:
wrapped = Vertex.wrap(v)
return None if wrapped.isNull() else wrapped
result = []
for i in range(int(self._ref.getSize())):
ruleNodeId = int(self._ref.getRuleNodeId(i))
result.append(VertexMapEntry(
vertex(self._ref.getSourceVertex(i)),
int(self._ref.getSourceInstance(i)),
vertex(self._ref.getTargetVertex(i)),
int(self._ref.getTargetInstance(i)),
None if ruleNodeId < 0 else ruleNodeId,
))
return result
def __iter__(self) -> Iterator[VertexMapEntry]:
return iter(self.entries())
def __str__(self) -> str:
return self._ref.toString()
def __repr__(self) -> str:
return self._ref.toString()