Source code for stk._internal.topology_graphs.small.internal_reaction

import typing
from collections import abc

from stk._internal.building_block import BuildingBlock
from stk._internal.optimizers.null import NullOptimizer
from stk._internal.optimizers.optimizer import Optimizer
from stk._internal.reaction_factories.generic_reaction_factory import (
    GenericReactionFactory,
)
from stk._internal.reaction_factories.reaction_factory import (
    ReactionFactory,
)
from stk._internal.topology_graphs.edge import Edge
from stk._internal.topology_graphs.topology_graph.topology_graph import (
    TopologyGraph,
)
from stk._internal.topology_graphs.vertex import Vertex

from .vertices import SingleVertex


[docs] class InternalReaction(TopologyGraph): """Represents an intramolecular reaction(s). Here, we designed a way to take a single building block (maybe constructed from another series of building blocks) and perform any number of intramolecular reactions. Examples: *Construction* The number of functional groups in the core building block define the topology graph .. moldoc:: import moldoc.molecule as molecule import stk building_block = stk.BuildingBlock( smiles="CCCC(CCCCI)CCCCCC(I)CC", functional_groups=stk.IodoFactory(), ) moldoc_display_molecule = molecule.Molecule( atoms=( molecule.Atom( atomic_number=atom.get_atomic_number(), position=position, ) for atom, position in zip( building_block.get_atoms(), building_block.get_position_matrix(), ) ), bonds=( molecule.Bond( atom1_id=bond.get_atom1().get_id(), atom2_id=bond.get_atom2().get_id(), order=bond.get_order(), ) for bond in building_block.get_bonds() ), ) .. testcode:: construction-internal import stk building_block = stk.BuildingBlock( smiles="CCCC(CCCCI)CCCCCC(I)CC", functional_groups=stk.IodoFactory(), ) reacted = stk.ConstructedMolecule(stk.small.InternalReaction( building_block=building_block, num_reactions=1 )) .. moldoc:: import moldoc.molecule as molecule import stk building_block = stk.BuildingBlock( smiles="CCCC(CCCCI)CCCCCC(I)CC", functional_groups=stk.IodoFactory(), ) reacted = stk.ConstructedMolecule(stk.small.InternalReaction( building_block=building_block, num_reactions=1 )) moldoc_display_molecule = molecule.Molecule( atoms=( molecule.Atom( atomic_number=atom.get_atomic_number(), position=position, ) for atom, position in zip( reacted.get_atoms(), reacted.get_position_matrix(), ) ), bonds=( molecule.Bond( atom1_id=bond.get_atom1().get_id(), atom2_id=bond.get_atom2().get_id(), order=bond.get_order(), ) for bond in reacted.get_bonds() ), ) And multiple reactions can be performed, where the closest pairs should react. .. moldoc:: import moldoc.molecule as molecule import stk building_block = stk.BuildingBlock( smiles="ICCCCC(CCCI)CCCCCC(I)CCI", functional_groups=stk.IodoFactory(), ) moldoc_display_molecule = molecule.Molecule( atoms=( molecule.Atom( atomic_number=atom.get_atomic_number(), position=position, ) for atom, position in zip( building_block.get_atoms(), building_block.get_position_matrix(), ) ), bonds=( molecule.Bond( atom1_id=bond.get_atom1().get_id(), atom2_id=bond.get_atom2().get_id(), order=bond.get_order(), ) for bond in building_block.get_bonds() ), ) .. testcode:: construction import stk building_block = stk.BuildingBlock( smiles="ICCCCC(CCCI)CCCCCC(I)CCI", functional_groups=stk.IodoFactory(), ) reacted = stk.ConstructedMolecule(stk.small.InternalReaction( building_block=building_block, num_reactions=2, )) .. moldoc:: import moldoc.molecule as molecule import stk building_block = stk.BuildingBlock( smiles="ICCCCC(CCCI)CCCCCC(I)CCI", functional_groups=stk.IodoFactory(), ) reacted = stk.ConstructedMolecule(stk.small.InternalReaction( building_block=building_block, num_reactions=2 )) moldoc_display_molecule = molecule.Molecule( atoms=( molecule.Atom( atomic_number=atom.get_atomic_number(), position=position, ) for atom, position in zip( reacted.get_atoms(), reacted.get_position_matrix(), ) ), bonds=( molecule.Bond( atom1_id=bond.get_atom1().get_id(), atom2_id=bond.get_atom2().get_id(), order=bond.get_order(), ) for bond in reacted.get_bonds() ), ) *Suggested Optimization* For :class:`.InternalReaction` topologies, no :mod:`stk` optimizer is appropriate, as they all assume distinct building blocks. """ def __init__( self, building_block: BuildingBlock, num_reactions: int, num_processes: int = 1, optimizer: Optimizer = NullOptimizer(), scale_multiplier: float = 1.0, reaction_factory: ReactionFactory = GenericReactionFactory(), ) -> None: """ Parameters: building_block: The only building block. num_reactions: The number of internal reactions to run. num_processes: The number of parallel processes to create during :meth:`construct`. optimizer: Used to optimize the structure of the constructed molecule. scale_multiplier: Scales the positions of the vertices. reaction_factory: The factory to use for creating reactions between functional groups of building blocks. Raises: :class:`ValueError` If the number of reactions does not match the number of pairs of functional groups. """ self._repr = f"Internal({building_block!r}, {num_reactions!r})" self._num_reactions = num_reactions num_functional_groups = building_block.get_num_functional_groups() if num_functional_groups != 2 * self._num_reactions: raise ValueError( f"The number of reactions {num_reactions} does match the number" f" of pairs of functional groups ({num_functional_groups})." ) vertices = (SingleVertex(0, (0, 0, 0)),) edges = [] for potential_edge in range(self._num_reactions): edges.append( Edge( id=potential_edge, vertex1=vertices[0], vertex2=vertices[0], ) ) super().__init__( building_block_vertices={building_block: vertices}, edges=tuple(edges), reaction_factory=reaction_factory, construction_stages=(), optimizer=optimizer, num_processes=num_processes, scale_multiplier=scale_multiplier, )
[docs] def clone(self) -> typing.Self: clone = self._clone() clone._repr = self._repr clone._num_reactions = self._num_reactions return clone
@staticmethod def _get_scale( building_block_vertices: dict[BuildingBlock, abc.Sequence[Vertex]], scale_multiplier: float, ) -> float: return 1
[docs] def with_building_blocks( self, building_block_map: dict[BuildingBlock, BuildingBlock], ) -> typing.Self: return self.clone()._with_building_blocks(building_block_map)
def __repr__(self) -> str: return self._repr