forked from enviPath/enviPy
[Feature] Implemented SMARTS filtering for Rules (#246)
Reactant Filter SMARTS as well as Product Filter SMARTS are now reflected when applying rules. Fixes #245 Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Reviewed-on: enviPath/enviPy#246
This commit is contained in:
@ -279,6 +279,24 @@ class FormatConverter(object):
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def smarts_matches(mol: str | Chem.Mol, smarts: str) -> bool:
|
||||
"""
|
||||
Returns True if the SMARTS pattern matches the given SMILES / Molecule.
|
||||
"""
|
||||
_mol = mol
|
||||
if isinstance(mol, str):
|
||||
_mol = Chem.MolFromSmiles(mol)
|
||||
|
||||
if _mol is None:
|
||||
raise ValueError(f"Invalid Molecule: {mol}")
|
||||
|
||||
pattern = Chem.MolFromSmarts(smarts)
|
||||
if pattern is None:
|
||||
raise ValueError(f"Invalid SMARTS: {smarts}")
|
||||
|
||||
return _mol.HasSubstructMatch(pattern)
|
||||
|
||||
@staticmethod
|
||||
def apply(
|
||||
smiles: str,
|
||||
@ -288,6 +306,8 @@ class FormatConverter(object):
|
||||
standardize: bool = True,
|
||||
kekulize: bool = True,
|
||||
remove_stereo: bool = True,
|
||||
reactant_filter_smarts: str | None = None,
|
||||
product_filter_smarts: str | None = None,
|
||||
) -> List["ProductSet"]:
|
||||
logger.debug(f"Applying {smirks} on {smiles}")
|
||||
|
||||
@ -306,6 +326,15 @@ class FormatConverter(object):
|
||||
Chem.SanitizeMol(mol)
|
||||
mol = Chem.AddHs(mol)
|
||||
|
||||
# Check if reactant_filter_smarts matches and we shouldn't apply the rule
|
||||
if reactant_filter_smarts and FormatConverter.smarts_matches(
|
||||
mol, reactant_filter_smarts
|
||||
):
|
||||
logger.debug(
|
||||
f"Reactant {FormatConverter.to_smiles(mol)} matches {reactant_filter_smarts}, skipping"
|
||||
)
|
||||
return list(pss)
|
||||
|
||||
# apply!
|
||||
sites = rxn.RunReactants((mol,))
|
||||
logger.debug(f"{len(sites)} products sets generated")
|
||||
@ -321,6 +350,17 @@ class FormatConverter(object):
|
||||
p = FormatConverter.standardize(
|
||||
Chem.MolToSmiles(p), remove_stereo=remove_stereo
|
||||
)
|
||||
|
||||
if product_filter_smarts and FormatConverter.smarts_matches(
|
||||
p, product_filter_smarts
|
||||
):
|
||||
logger.debug(
|
||||
f"Product {FormatConverter.to_smiles(mol)} matches {product_filter_smarts}, skipping"
|
||||
)
|
||||
# clear products we might have already collected
|
||||
prods.clear()
|
||||
break
|
||||
|
||||
prods.append(p)
|
||||
|
||||
# if kekulize:
|
||||
@ -357,7 +397,7 @@ class FormatConverter(object):
|
||||
except Exception as e:
|
||||
logger.error(f"Applying {smirks} on {smiles} failed:\n{e}")
|
||||
|
||||
return pss
|
||||
return list(pss)
|
||||
|
||||
@staticmethod
|
||||
def MACCS(smiles):
|
||||
|
||||
Reference in New Issue
Block a user