def to_rdkit_mol(self): """ Return an :mod:`rdkit` representation. Returns ------- :class:`rdkit.Mol` The molecule in :mod:`rdkit` format. """ mol = rdkit.EditableMol(rdkit.Mol()) for atom in self._atoms: rdkit_atom = rdkit.Atom(atom.get_atomic_number()) rdkit_atom.SetFormalCharge(atom.get_charge()) mol.AddAtom(rdkit_atom) for bond in self._bonds: mol.AddBond( beginAtomIdx=bond.get_atom1().get_id(), endAtomIdx=bond.get_atom2().get_id(), order=(rdkit.BondType.DATIVE if bond.get_order() == 9 else rdkit.BondType(bond.get_order())), ) mol = mol.GetMol() rdkit_conf = rdkit.Conformer(len(self._atoms)) for atom_id, atom_coord in enumerate(self._position_matrix.T): rdkit_conf.SetAtomPosition(atom_id, atom_coord) mol.GetAtomWithIdx(atom_id).SetNoImplicit(True) mol.AddConformer(rdkit_conf) return mol
def to_rdkit_mol(self): """ Return an :mod:`rdkit` representation. Returns ------- :class:`rdkit.Mol` The molecule in :mod:`rdkit` format. """ mol = rdkit.EditableMol(rdkit.Mol()) for atom in self.atoms: rdkit_atom = rdkit.Atom(atom.atomic_number) rdkit_atom.SetFormalCharge(atom.charge) mol.AddAtom(rdkit_atom) for bond in self.bonds: mol.AddBond(beginAtomIdx=bond.atom1.id, endAtomIdx=bond.atom2.id, order=rdkit.BondType(bond.order)) mol = mol.GetMol() rdkit_conf = rdkit.Conformer(len(self.atoms)) for atom_id, atom_coord in enumerate(self._position_matrix.T): rdkit_conf.SetAtomPosition(atom_id, atom_coord) mol.AddConformer(rdkit_conf) return mol
def to_rdkit_mol_without_metals(mol, metal_atoms, metal_bonds): """ Create :class:`rdkit.Mol` with metals replaced by H atoms. Parameters ---------- mol : :class:`.Molecule` The molecule to be optimized. metal_atoms : :class:`.list` of :class:`stk.Atom` List of metal atoms. metal_bonds : :class:`.list` of :class:`stk.Bond` List of bonds including metal atoms. Returns ------- edit_mol : :class:`rdkit.Mol` RDKit molecule with metal atoms replaced with H atoms. """ edit_mol = rdkit.EditableMol(rdkit.Mol()) for atom in mol.get_atoms(): if atom in metal_atoms: # In place of metals, add H's that will be constrained. # This allows the atom ids to not be changed. rdkit_atom = rdkit.Atom(1) rdkit_atom.SetFormalCharge(0) else: rdkit_atom = rdkit.Atom(atom.get_atomic_number()) rdkit_atom.SetFormalCharge(atom.get_charge()) edit_mol.AddAtom(rdkit_atom) for bond in mol.get_bonds(): if bond in metal_bonds: # Do not add bonds to metal atoms (replaced with H's). continue edit_mol.AddBond( beginAtomIdx=bond.get_atom1().get_id(), endAtomIdx=bond.get_atom2().get_id(), order=rdkit.BondType(bond.get_order()) ) edit_mol = edit_mol.GetMol() rdkit_conf = rdkit.Conformer(mol.get_num_atoms()) for atom_id, atom_coord in enumerate(mol.get_position_matrix()): rdkit_conf.SetAtomPosition(atom_id, atom_coord) edit_mol.GetAtomWithIdx(atom_id).SetNoImplicit(True) edit_mol.AddConformer(rdkit_conf) return edit_mol
def get_rdkit_mol(molecule): rdkit_mol = rdkit.EditableMol(rdkit.Mol()) for atom in molecule.get_atoms(): rdkit_atom = rdkit.Atom(atom.get_atomic_number()) rdkit_atom.SetFormalCharge(atom.get_charge()) rdkit_mol.AddAtom(rdkit_atom) for bond in molecule.get_bonds(): rdkit_mol.AddBond( beginAtomIdx=bond.get_atom1().get_id(), endAtomIdx=bond.get_atom2().get_id(), order=(rdkit.BondType.DATIVE if bond.get_order() == 9 else rdkit.BondType(bond.get_order())), ) return rdkit_mol.GetMol()
def with_hydrogens(molecule): rdkit_molecule = rdkit.EditableMol(rdkit.Mol()) for atom in molecule.get_atoms(): rdkit_atom = rdkit.Atom(atom.get_atomic_number()) rdkit_atom.SetFormalCharge(atom.get_charge()) rdkit_molecule.AddAtom(rdkit_atom) for bond in molecule.get_bonds(): rdkit_molecule.AddBond( beginAtomIdx=bond.get_atom1_id(), endAtomIdx=bond.get_atom2_id(), order=rdkit.BondType(bond.get_order()), ) rdkit_molecule = rdkit_molecule.GetMol() rdkit.SanitizeMol(rdkit_molecule) return rdkit.AddHs(rdkit_molecule)
def vabene_to_smiles(molecule): editable = rdkit.EditableMol(rdkit.Mol()) for atom in molecule.get_atoms(): rdkit_atom = rdkit.Atom(atom.get_atomic_number()) rdkit_atom.SetFormalCharge(atom.get_charge()) editable.AddAtom(rdkit_atom) for bond in molecule.get_bonds(): editable.AddBond( beginAtomIdx=bond.get_atom1_id(), endAtomIdx=bond.get_atom2_id(), order=rdkit.BondType(bond.get_order()), ) rdkit_molecule = editable.GetMol() rdkit.SanitizeMol(rdkit_molecule) rdkit.Kekulize(rdkit_molecule) return rdkit.MolToSmiles(rdkit_molecule)
def init_from_vabene_molecule( cls, molecule: vabene.Molecule, functional_groups: typing.Iterable[typing.Union[ FunctionalGroup, FunctionalGroupFactory]] = (), placer_ids: typing.Optional[tuple[int, ...]] = None, position_matrix: typing.Optional[np.ndarray] = None, ) -> BuildingBlock: """ Initialize from a :mod:`vabene.Molecule`. Notes: The molecule is given 3D coordinates with :func:`rdkit.ETKDGv2()`. Parameters: molecule: The :class:`vabene.Molecule` from which to initialize. functional_groups: An :class:`iterable` of :class:`.FunctionalGroup` or :class:`.FunctionalGroupFactory` or both. :class:`.FunctionalGroup` instances are added to the building block and :class:`.FunctionalGroupFactory` instances are used to create :class:`.FunctionalGroup` instances the building block should hold. :class:`.FunctionalGroup` instances are used to identify which atoms are modified during :class:`.ConstructedMolecule` construction. placer_ids: The ids of *placer* atoms. These are the atoms which should be used for calculating the position of the building block. Depending on the values passed to `placer_ids`, and the functional groups in the building block, different *placer* ids will be used by the building block. #. `placer_ids` is passed to the initializer: the passed *placer* ids will be used by the building block. #. `placer_ids` is ``None`` and the building block has functional groups: The *placer* ids of the functional groups will be used as the *placer* ids of the building block. #. `placer_ids` is ``None`` and `functional_groups` is empty. All atoms of the molecule will be used for *placer* ids. position_matrix: The position matrix the building block should use. If ``None``, :func:`rdkit.ETKDGv2` will be used to calculate it. Returns: The building block. Raises: :class:`RuntimeError` If embedding the molecule fails. """ editable = rdkit.EditableMol(rdkit.Mol()) for atom in molecule.get_atoms(): rdkit_atom = rdkit.Atom(atom.get_atomic_number()) rdkit_atom.SetFormalCharge(atom.get_charge()) editable.AddAtom(rdkit_atom) for bond in molecule.get_bonds(): editable.AddBond( beginAtomIdx=bond.get_atom1_id(), endAtomIdx=bond.get_atom2_id(), order=rdkit.BondType(bond.get_order()), ) rdkit_molecule = editable.GetMol() rdkit.SanitizeMol(rdkit_molecule) rdkit_molecule = rdkit.AddHs(rdkit_molecule) if position_matrix is None: params = rdkit.ETKDGv2() random_seed = 4 params.randomSeed = random_seed if rdkit.EmbedMolecule(rdkit_molecule, params) == -1: raise RuntimeError( f'Embedding with seed value of {random_seed} ' 'failed.') else: # Make sure the position matrix always holds floats. position_matrix = np.array( position_matrix, dtype=np.float64, ) conformer = rdkit.Conformer(rdkit_molecule.GetNumAtoms()) for atom_id, position in enumerate(position_matrix): conformer.SetAtomPosition(atom_id, position) rdkit_molecule.AddConformer(conformer) rdkit.Kekulize(rdkit_molecule) return cls.init_from_rdkit_mol( molecule=rdkit_molecule, functional_groups=functional_groups, placer_ids=placer_ids, )
def init_from_vabene_molecule( cls, molecule, functional_groups=(), placer_ids=None, random_seed=None, position_matrix=None, ): """ Initialize from a :mod:`vabene.Molecule`. Notes ----- The molecule is given 3D coordinates with :func:`rdkit.ETKDGv2()`. Parameters ---------- molecule : :class:`vabene.Molecule` The molecule from which to initialize. functional_groups : :class:`iterable`, optional An :class:`iterable` of :class:`.FunctionalGroup` or :class:`.FunctionalGroupFactory` or both. :class:`.FunctionalGroup` instances are added to the building block and :class:`.FunctionalGroupFactory` instances are used to create :class:`.FunctionalGroup` instances the building block should hold. :class:`.FunctionalGroup` instances are used to identify which atoms are modified during :class:`.ConstructedMolecule` construction. placer_ids : :class:`tuple` of :class:`int`, optional The ids of *placer* atoms. These are the atoms which should be used for calculating the position of the building block. Depending on the values passed to `placer_ids`, and the functional groups in the building block, different *placer* ids will be used by the building block. #. `placer_ids` is passed to the initializer: the passed *placer* ids will be used by the building block. #. `placer_ids` is ``None`` and the building block has functional groups: The *placer* ids of the functional groups will be used as the *placer* ids of the building block. #. `placer_ids` is ``None`` and `functional_groups` is empty. All atoms of the molecule will be used for *placer* ids. random_seed : :class:`int`, optional Random seed passed to :func:`rdkit.ETKDGv2`. This argument is deprecated and will be removed in any version of :mod:`stk` released on, or after, 01/08/20. If you want to change the position matrix of the initialized building block, please use `position_matrix`. position_matrix : :class:`numpy.ndarray`, optional The position matrix the building block should use. If ``None``, :func:`rdkit.ETKDGv2` will be used to calculate it. Returns ------- :class:`.BuildingBlock` The building block. Raises ------ :class:`RuntimeError` If embedding the molecule fails. """ if random_seed is not None: warnings.warn( 'The init_from_vabene_molecule random seed parameter ' 'will be removed in any ' 'version of stk released on, or after, 01/08/20. ' 'If you want to change the position matrix of the ' 'initialized building block, please use the ' 'position_matrix parameter.', FutureWarning, ) else: random_seed = 4 editable = rdkit.EditableMol(rdkit.Mol()) for atom in molecule.get_atoms(): rdkit_atom = rdkit.Atom(atom.get_atomic_number()) rdkit_atom.SetFormalCharge(atom.get_charge()) editable.AddAtom(rdkit_atom) for bond in molecule.get_bonds(): editable.AddBond( beginAtomIdx=bond.get_atom1_id(), endAtomIdx=bond.get_atom2_id(), order=rdkit.BondType(bond.get_order()), ) rdkit_molecule = editable.GetMol() rdkit.SanitizeMol(rdkit_molecule) rdkit_molecule = rdkit.AddHs(rdkit_molecule) if position_matrix is None: params = rdkit.ETKDGv2() params.randomSeed = random_seed if rdkit.EmbedMolecule(rdkit_molecule, params) == -1: raise RuntimeError( f'Embedding with seed value of {random_seed} ' 'failed.' ) else: # Make sure the position matrix always holds floats. position_matrix = np.array( position_matrix, dtype=np.float64, ) conformer = rdkit.Conformer(rdkit_molecule.GetNumAtoms()) for atom_id, position in enumerate(position_matrix): conformer.SetAtomPosition(atom_id, position) rdkit_molecule.AddConformer(conformer) rdkit.Kekulize(rdkit_molecule) return cls.init_from_rdkit_mol( molecule=rdkit_molecule, functional_groups=functional_groups, placer_ids=placer_ids, )