Source code for rdkit_to_params.rdkitside.utilities

__all__ = ['neutralise', 'neutralize', 'DummyMasker']

from rdkit import Chem
from rdkit.Chem import AllChem
import warnings


[docs]def neutralize(mol: Chem) -> Chem: """ Alters the protonation of tne molecule to be that at pH 7. Not great, but does the job. * Protonates amines, but not aromatic bound amines. * Deprotonates carboxylic acid, phosphoric acid and sulfuric acid, without ruining esters. """ mol = Chem.RemoveHs(mol) protons_added = 0 protons_removed = 0 for indices in mol.GetSubstructMatches(Chem.MolFromSmarts('[N;D1]')): atom = mol.GetAtomWithIdx(indices[0]) if atom.GetNeighbors()[0].GetIsAromatic(): continue # aniline atom.SetFormalCharge(1) atom.SetNumExplicitHs(3) protons_added += 1 for indices in mol.GetSubstructMatches(Chem.MolFromSmarts('C(=O)[O;D1]')): atom = mol.GetAtomWithIdx(indices[2]) # benzoic acid pKa is low. atom.SetFormalCharge(-1) atom.SetNumExplicitHs(0) protons_removed += 1 for indices in mol.GetSubstructMatches(Chem.MolFromSmarts('P(=O)[Oh1]')): atom = mol.GetAtomWithIdx(indices[2]) # benzoic acid pKa is low. atom.SetFormalCharge(-1) atom.SetNumExplicitHs(0) protons_removed += 1 for indices in mol.GetSubstructMatches(Chem.MolFromSmarts('S(=O)(=O)[Oh1]')): atom = mol.GetAtomWithIdx(indices[3]) atom.SetNumExplicitHs(0) # benzoic acid pKa is low. atom.SetFormalCharge(-1) protons_removed += 1 AllChem.ComputeGasteigerCharges(mol) # return dict(protons_added=protons_added, # protons_removed=protons_removed) return mol
[docs]def neutralise(*args, **kwargs): warnings.warn('The GB spelling has been changed to US', category=DeprecationWarning) return neutralize(*args, **kwargs)
[docs]class DummyMasker: """ A context manager that allows operations on a mol containing dummy atoms (R/*) that otherwise would raise an RDKit error. It simply masks and unmasks the dummy atoms. >>> mol = Chem.MolFromSmiles('*CCC(C)C') >>> with DummyMasker(mol): >>> AllChem.EmbedMolecule(mol) The input options for dummy maker are ``mol`` (Chem.Mol), ``placekeeper_zahl`` (Z for atomic number), and ``blank_Gasteiger`` to make the dummy atom's '_GasteigerCharge' property zero if present. The Zahl of the placekeeping element will affect the Gasteiger partial chargers of nearby atoms though. """
[docs] def __init__(self, mol: Chem.Mol, placekeeper_zahl:int=6, blank_Gasteiger:bool=True): self.mol = mol self.is_masked = False self.zahl = int(placekeeper_zahl) self.blank_Gasteiger = bool(blank_Gasteiger) self.dummies = list( mol.GetAtomsMatchingQuery(Chem.rdqueries.AtomNumEqualsQueryAtom(0)) )
[docs] def mask(self): for dummy in self.dummies: dummy.SetAtomicNum(self.zahl) dummy.SetBoolProp('dummy', True) dummy.SetHybridization(Chem.HybridizationType.SP3) self.is_masked = True
[docs] def unmask(self): for dummy in self.dummies: assert dummy.HasProp('dummy'), 'The atoms have changed somehow? (weird cornercase)' dummy.SetAtomicNum(0) if dummy.HasProp('_GasteigerCharge') and self.blank_Gasteiger: dummy.SetDoubleProp('_GasteigerCharge', 0.) self.is_masked = False
def __enter__(self): self.mask() return self def __exit__(self, exc_type: Exception, exc_value: str, exc_traceback: 'bultins.traceback'): self.unmask()