|
|
import warnings |
|
|
|
|
|
from rdkit import Chem |
|
|
from rdkit.Chem.rdForceFieldHelpers import UFFOptimizeMolecule, UFFHasAllMoleculeParams |
|
|
|
|
|
from src.data import sanifix |
|
|
|
|
|
|
|
|
def uff_relax(mol, max_iter=200): |
|
|
""" |
|
|
Uses RDKit's universal force field (UFF) implementation to optimize a |
|
|
molecule. |
|
|
""" |
|
|
if not UFFHasAllMoleculeParams(mol): |
|
|
warnings.warn('UFF parameters not available for all atoms. ' |
|
|
'Returning None.') |
|
|
return None |
|
|
|
|
|
try: |
|
|
more_iterations_required = UFFOptimizeMolecule(mol, maxIters=max_iter) |
|
|
if more_iterations_required: |
|
|
warnings.warn(f'Maximum number of FF iterations reached. ' |
|
|
f'Returning molecule after {max_iter} relaxation steps.') |
|
|
|
|
|
except RuntimeError: |
|
|
return None |
|
|
|
|
|
return mol |
|
|
|
|
|
|
|
|
def add_hydrogens(rdmol): |
|
|
return Chem.AddHs(rdmol, addCoords=(len(rdmol.GetConformers()) > 0)) |
|
|
|
|
|
|
|
|
def get_largest_fragment(rdmol): |
|
|
mol_frags = Chem.GetMolFrags(rdmol, asMols=True, sanitizeFrags=False) |
|
|
largest_frag = max(mol_frags, default=rdmol, key=lambda m: m.GetNumAtoms()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return largest_frag |
|
|
|
|
|
|
|
|
def process_all(rdmol, largest_frag=True, adjust_aromatic_Ns=True, relax_iter=0): |
|
|
""" |
|
|
Apply all filters and post-processing steps. Returns a new molecule. |
|
|
|
|
|
Returns: |
|
|
RDKit molecule or None if it does not pass the filters or processing |
|
|
fails |
|
|
""" |
|
|
|
|
|
|
|
|
if rdmol.GetNumAtoms() < 1: |
|
|
return None |
|
|
|
|
|
|
|
|
mol = Chem.Mol(rdmol) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if largest_frag: |
|
|
mol = get_largest_fragment(mol) |
|
|
|
|
|
|
|
|
|
|
|
if adjust_aromatic_Ns: |
|
|
mol = sanifix.fix_mol(mol) |
|
|
if mol is None: |
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if relax_iter > 0: |
|
|
mol = uff_relax(mol, relax_iter) |
|
|
if mol is None: |
|
|
return None |
|
|
|
|
|
try: |
|
|
Chem.SanitizeMol(mol) |
|
|
except ValueError: |
|
|
warnings.warn('Sanitization failed. Returning None.') |
|
|
return None |
|
|
|
|
|
return mol |
|
|
|