Source code for stko._internal.molecular.functional_groups.three_site

import logging
from collections import abc
from typing import Self

import stk

logger = logging.getLogger(__name__)


[docs] class ThreeSiteFG: """Represents FG sites like N atom in pyridine functional group. .. warning:: This code is only present in the latest versions of stko that require Python 3.11! The structure of the functional group is given by the pseudo-SMILES ``[neighbour][binder][neighbour]``. Contains :class:`stk.GenericFunctionalGroup`. Parameters: neigh1: The first neighbour atom. binder: The central atom that forms the bond. neigh2: The second neighbour atom. bonders: The bonder atoms, this should be the same ID as `binder`. deleters: The deleter atoms, there should be none. """ def __init__( self, neigh1: stk.Atom, binder: stk.Atom, neigh2: stk.Atom, bonders: tuple[stk.Atom, ...], deleters: tuple[stk.Atom, ...], ) -> None: self._neigh1 = neigh1 self._binder = binder self._neigh2 = neigh2 atoms = (neigh1, binder, neigh2) self._functional_group = stk.GenericFunctionalGroup( atoms=atoms, bonders=bonders, deleters=deleters, )
[docs] def get_neigh1(self) -> stk.Atom: return self._neigh1
[docs] def get_neigh2(self) -> stk.Atom: return self._neigh2
[docs] def get_binder(self) -> stk.Atom: return self._binder
[docs] def clone(self) -> Self: clone = self.__class__.__new__(self.__class__) clone._neigh1 = self._neigh1 # noqa: SLF001 clone._binder = self._binder # noqa: SLF001 clone._neigh2 = self._neigh2 # noqa: SLF001 clone._functional_group = self._functional_group.clone() # noqa: SLF001 return clone
[docs] def get_bonders(self) -> abc.Iterator[stk.Atom]: return self._functional_group.get_bonders()
[docs] def get_num_bonders(self) -> int: return self._functional_group.get_num_bonders()
[docs] def get_bonder_ids(self) -> abc.Iterator[int]: return self._functional_group.get_bonder_ids()
[docs] def get_deleters(self) -> abc.Iterator[stk.Atom]: return self._functional_group.get_deleters()
[docs] def get_deleter_ids(self) -> abc.Iterator[int]: return self._functional_group.get_deleter_ids()
[docs] def get_atoms(self) -> abc.Iterator[stk.Atom]: return self._functional_group.get_atoms()
[docs] def get_atom_ids(self) -> abc.Iterator[int]: return self._functional_group.get_atom_ids()
[docs] def get_placer_ids(self) -> abc.Iterator[int]: return self._functional_group.get_placer_ids()
[docs] def get_core_atom_ids(self) -> abc.Iterator[int]: return self._functional_group.get_core_atom_ids()
[docs] def with_atoms(self, atom_map: dict[int, stk.Atom]) -> Self: clone = self.__class__.__new__(self.__class__) clone._functional_group = stk.GenericFunctionalGroup( # noqa: SLF001 atoms=tuple( atom_map.get(a.get_id(), a) for a in self._functional_group.get_atoms() ), bonders=tuple( atom_map.get(a.get_id(), a) for a in self._functional_group.get_bonders() ), deleters=tuple( atom_map.get(a.get_id(), a) for a in self._functional_group.get_deleters() ), placers=tuple( atom_map.get(a.get_id(), a) for a in self._functional_group._placers # noqa: SLF001 ), ) clone._neigh1 = atom_map.get(self._neigh1.get_id(), self._neigh1) # noqa: SLF001 clone._binder = atom_map.get(self._binder.get_id(), self._binder) # noqa: SLF001 clone._neigh2 = atom_map.get(self._neigh2.get_id(), self._neigh2) # noqa: SLF001 return clone
[docs] def with_ids(self, id_map: dict[int, int]) -> Self: clone = self.__class__.__new__(self.__class__) clone._functional_group = self._functional_group.with_ids(id_map) # noqa: SLF001 clone._neigh1 = self._neigh1.with_id( # noqa: SLF001 id_map.get(self._neigh1.get_id(), self._neigh1.get_id()) ) clone._binder = self._binder.with_id( # noqa: SLF001 id_map.get(self._binder.get_id(), self._binder.get_id()) ) clone._neigh2 = self._neigh2.with_id( # noqa: SLF001 id_map.get(self._neigh2.get_id(), self._neigh2.get_id()) ) return clone
def __repr__(self) -> str: return ( f"{self.__class__.__name__}(" f"{self._neigh1}, {self._binder}, {self._neigh2}, " f"bonders={self._functional_group._bonders})" # noqa: SLF001 )
[docs] class ThreeSiteFactory(stk.FunctionalGroupFactory): """Find ThreeSite functional groups in molecules. .. warning:: This code is only present in the latest versions of stko that require Python 3.11! Parameters: smarts: SMARTS string to use to find functional group. Of form ``[neighbour][binder][neighbour]``. bonders: The bonder atoms, this should be the same ID as `binder`. deleters: The deleter atoms, there should be none. """ def __init__( self, smarts: str, bonders: tuple[int, ...] = (1,), deleters: tuple[int, ...] = (), ) -> None: self._smarts = smarts self._bonders = bonders self._deleters = deleters
[docs] def get_functional_groups( self, molecule: stk.Molecule, ) -> abc.Iterable[ThreeSiteFG]: generic_functional_groups = stk.SmartsFunctionalGroupFactory( smarts=self._smarts, bonders=self._bonders, deleters=self._deleters, ).get_functional_groups(molecule) for fg in generic_functional_groups: atom_ids = (i.get_id() for i in fg.get_atoms()) atoms = tuple(molecule.get_atoms(atom_ids)) yield ThreeSiteFG( neigh1=atoms[0], binder=atoms[1], neigh2=atoms[2], bonders=tuple(atoms[i] for i in self._bonders), deleters=tuple(atoms[i] for i in self._deleters), )
[docs] class CNCFactory(ThreeSiteFactory): """A subclass of :class:`.ThreeSiteFactory`. .. warning:: This code is only present in the latest versions of stko that require Python 3.11! SMARTs string for [carbon][nitrogen][carbon]: "[#6]~[#7X2]~[#6]" """ def __init__( self, bonders: tuple[int, ...] = (1,), deleters: tuple[int, ...] = (), ) -> None: self._smarts = "[#6]~[#7X2]~[#6]" self._bonders = bonders self._deleters = deleters
[docs] class CNNFactory(ThreeSiteFactory): """A subclass of :class:`.ThreeSiteFactory`. .. warning:: This code is only present in the latest versions of stko that require Python 3.11! SMARTs string for [nitrogen][nitrogen][carbon]: "[#7]~[#7X2]~[#6]" """ def __init__( self, bonders: tuple[int, ...] = (1,), deleters: tuple[int, ...] = (), ) -> None: self._smarts = "[#7]~[#7X2]~[#6]" self._bonders = bonders self._deleters = deleters
[docs] class NNNFactory(ThreeSiteFactory): """A subclass of :class:`.ThreeSiteFactory`. .. warning:: This code is only present in the latest versions of stko that require Python 3.11! SMARTs string for [nitrogen][nitrogen][nitrogen]: "[#7]~[#7X2]~[#7]" """ def __init__( self, bonders: tuple[int, ...] = (1,), deleters: tuple[int, ...] = (), ) -> None: self._smarts = "[#7]~[#7X2]~[#7]" self._bonders = bonders self._deleters = deleters