Source code for stk._internal.ea.mutation.random_topology_graph

from collections.abc import Callable, Iterable
from typing import Any

import numpy as np

from stk._internal.ea.molecule_record import MoleculeRecord
from stk._internal.ea.mutation.record import MutationRecord
from stk._internal.topology_graphs.topology_graph.topology_graph import (
    TopologyGraph,
)


[docs] class RandomTopologyGraph: """ Changes topology graphs at random. Examples: *Constructed Molecule Mutation* .. testcode:: constructed-molecule-mutation import stk # Create a molecule which is to be mutated. bb1 = stk.BuildingBlock('NCCN', [stk.PrimaryAminoFactory()]) bb2 = stk.BuildingBlock( smiles='O=CCC(C=O)CC=O', functional_groups=[stk.AldehydeFactory()], ) cage = stk.MoleculeRecord( topology_graph=stk.cage.FourPlusSix((bb1, bb2)), ) # Create functions which replace the topology graph. replacement_funcs = ( lambda graph: stk.cage.TwoPlusThree(graph.get_building_blocks()), lambda graph: stk.cage.EightPlusTwelve(graph.get_building_blocks()), lambda graph: stk.cage.TwentyPlusThirty(graph.get_building_blocks()), ) # Create the mutator. random_topology = stk.RandomTopologyGraph(replacement_funcs) # Mutate a molecule. mutation_record1 = random_topology.mutate(cage) # Mutate the molecule a second time. mutation_record2 = random_topology.mutate(cage) """ def __init__( self, replacement_funcs: Iterable[Callable[[TopologyGraph], TopologyGraph]], name: str = "RandomTopologyGraph", random_seed: int | np.random.Generator | None = None, ) -> None: """ Parameters: replacement_funcs \ (list[collections.abc.Callable[[TopologyGraph], TopologyGraph]]): Functions which take a topology graph and return its replacement. One is selected at random each time :meth:`.mutate` is called. name: A name to help identify the mutator instance. random_seed: The random seed to use. """ if random_seed is None or isinstance(random_seed, int): random_seed = np.random.default_rng(random_seed) self._replacement_funcs = tuple(replacement_funcs) self._name = name self._generator = random_seed
[docs] def mutate( self, record: MoleculeRecord[Any], ) -> MutationRecord[MoleculeRecord[Any]]: """ Return a mutant of `record`. Parameters: record: The molecule to be mutated. Returns: A record of the mutation or ``None`` if `record` cannot be mutated. """ replacement_func = self._generator.choice( a=self._replacement_funcs, # type: ignore ) replacement = replacement_func(record.get_topology_graph()) return MutationRecord( molecule_record=MoleculeRecord(replacement), mutator_name=self._name, )