6
$\begingroup$

Background Info: SMARTS is a convention for specifying molecular patterns. It is supported by Mathematica 12's MoleculePattern function.

Problem Setup: Consider MoleculePattern["[!#6;!#1;!H0]"]] This means "match atoms that are not carbon and not hydrogen and have more than zero hydrogens attached."

What seems to work OK: The Molecule["CNO"] has two atoms satisfying that pattern, and indeed, MoleculePlot correctly highlights both the nitrogen and oxygen atoms:

MoleculePlot[
 Molecule["CNO"],
 MoleculePattern["[!#6;!#1;!H0]"]]

molecule image showing O and N highlighted

What seems to be a problem: FindMoleculeSubstructure does not find both atoms; it incorrectly only finds the nitrogen (atom 2) but not the oxygen:

FindMoleculeSubstructure[
 Molecule["CNO"],
 MoleculePattern["[!#6;!#1;!H0]"]]

{<|1 -> 2|>}

(the returned association means "pattern 1 matched by atom 2 in the molecule)

Updated: I think this is an error with the arguments/documentation for FindMoleculeSubstructure. The documentation says that providing no third argument searches for all matches, but if I add the third argument, then I find the correct number of matches. For example:

FindMoleculeSubstructure[
 Molecule["CNO"],
 MoleculePattern["[!#6;!#1;!H0]"],
 10]

{<|1 -> 2|>, <|1 -> 3|>}

(which is correct)

Gratuitous additional examples: This appears to occurs with other MoleculePattern types. The exact same type of problem (two matches correctly found with MoleculePlot, but only one found with FindMoleculeSubstructure) also occurs with MoleculePattern["[C;H3,H4]"]] for Molecule["CCC"], as well as the same "fix".

$\endgroup$
7
$\begingroup$

FindMoleculeSubstructure is modeled after FindGraphIsomorphism, and by default returns only a single match. The third argument controls how many mappings are returned.

In[14]:= FindMoleculeSubstructure[
    Molecule @ "CNO", 
    MoleculePattern @ "[!#6;!#1;!H0]", 
    All
]

Out[14]= {<|1 -> 2|>, <|1 -> 3|>}

n has to have a default value, it can't be $\infty$ because you can easily ask for matches on a very general pattern and get way too many back.

In[12]:= Length@
 FindMoleculeSubstructure[
  Molecule[Entity["Chemical", "FullereneC60"]], 
  MoleculePattern["*.*.*"], All]

Out[12]= 34220
$\endgroup$
2
  • 2
    $\begingroup$ Makes total sense. Perhaps there is an opportunity to clarify the documentation? ?FindMoleculeSubstructure says that "FindMoleculeSubstructure[mol,patt] finds a mapping between the atom indices in mol and all occurrences of patt in mol." $\endgroup$ – Joshua Schrier Dec 18 '19 at 14:52
  • 1
    $\begingroup$ I will change the wording on the usage messages, you are right. $\endgroup$ – Jason B. Dec 18 '19 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.