Progress in Wolfram Chemistry

Jason Biggs, Wolfram Research Inc
Wolfram Technology Conference 2021

The Outline Slide

A Brief History of Chemistry in the Wolfram Language

ChemicalData -> Entity -> Molecule

Updates to Molecule visualization

Atom and Bond Labels

New drawing capabilities

Chemical representations

ChemicalFormula

ChemicalReaction

MoleculeName

FindIsomers

Pattern matching

MoleculeMatchQ

MoleculeSubstructureCount, MoleculeContainsQ, MoleculeFreeQ

MoleculeAlign

MoleculeMaximumCommonSubstructure

FeaturespacePlot

Molecule Resource Functions

A Brief History of Chemistry in the Wolfram Language

TimelinePlot[<|"Version 6.0: ChemicalData"->(DateObject["May 2007", DateObject[{2007,5},"Month","Gregorian",-5.`]]),"Version 10.0: EntityValue"->(DateObject["Jul 2014", DateObject[{2014,7},"Month","Gregorian",-5.`]]),"Version 12.0: Molecule"->DateObject["April 2019"],"PubChem Service Connection"->DateObject["March 2016"],"Version 12.1: MoleculeRecognize, new Import/Export formats"->DateObject["March 2020"],"Version 12.2: MoleculeDraw"->DateObject["December 16, 2020"],"Version 12.3: MoleculeName, MoleculeAlign, MoleculeMaximumCommonSubstructure"->DateObject["May 20, 2021"],"Version 13.0: MoleculeMatchQ, AtomLabels, ChemicalFormula, ChemicalReaction"->DateObject["November 15, 2021"](*estimated*)|>]

(HyperlinkDefault[ChemicalData, paclet:ref/ChemicalData, paclet:ref/ChemicalData])

?ChemicalData

(HyperlinkDefault["\"Chemical\"", paclet:ref/entity/Chemical, paclet:ref/entity/Chemical]) entities

Introduced in version 10, Entities provide a unified interface to the Wolfram Knowledgebase

Expanded syntax for querying multiple entity or multiple properties

EntityValue[{(Entity["diphenylmethane", Entity["Chemical","Diphenylmethane"], "Entity[\"Chemical\", \"Diphenylmethane\"]", "chemical"]),(Entity["piperidine", Entity["Chemical","Piperidine"], "Entity[\"Chemical\", \"Piperidine\"]", "chemical"])},{(EntityProperty[(Subscript["K", "a"]), EntityProperty["Chemical","AcidityConstants"], "EntityProperty[\"Chemical\", \"AcidityConstants\"]"]),(EntityProperty["critical pressure", EntityProperty["Chemical","CriticalPressure"], "EntityProperty[\"Chemical\", \"CriticalPressure\"]"]),(EntityProperty["critical temperature", EntityProperty["Chemical","CriticalTemperature"], "EntityProperty[\"Chemical\", \"CriticalTemperature\"]"]),(EntityProperty["density", EntityProperty["Chemical","Density"], "EntityProperty[\"Chemical\", \"Density\"]"]),(EntityProperty["vapor pressure", EntityProperty["Chemical","VaporPressure"], "EntityProperty[\"Chemical\", \"VaporPressure\"]"])},"Dataset"]

Molecule: A Computable Chemical Object

Version 12 introduces Molecule, a computable object that can represent any single molecule:

mol=Molecule["water"]

InputForm@%

A molecule is composed of atoms and bonds:

{AtomList[mol],BondList[mol]}

Molecule properties are computed on demand:

{mol["MolecularMass"],mol["PointGroupDisplay"]}

MoleculeValue[mol,"AdjacencyMatrix"]

MatrixPlot@%

Easily change the structure using MoleculeModify:

MoleculeModify[mol,{"SetMassNumber",{2->2,3->2}}]

MoleculeDraw

Interactively create and edit molecules

Add and modify atoms and bonds

MoleculeDraw[]

MoleculeDraw@MoleculeRecognize@

AtomLabels

AtomLabels and BondLabels are new options for MoleculePlot and MoleculePlot3D

MoleculePlot[Molecule["water"],AtomLabels->"AtomIndex"]

MoleculePlot[Molecule["water"],AtomLabels->Table[i->(Subscript[a, i]),{i,3}]]

MoleculePlot[Molecule["(2S,3S,4R)-3-(carboxymethyl)-4-(2-methoxyphenyl)pyrrolidine-2-carboxylic acid"],
AtomLabels->"AtomChirality"]

Example: Plot of TNT labeling all carbon and nitrogen atoms by their oxidation state

MoleculePlot[(Entity["trinitrotoluene", Entity["Chemical","Trinitrotoluene"], "Entity[\"Chemical\", \"Trinitrotoluene\"]", "chemical"]),AtomLabels->{"C"|"N"->MoleculeProperty["OxidationStates"]}]

MoleculePlot3D[(Entity["trinitrotoluene", Entity["Chemical","Trinitrotoluene"], "Entity[\"Chemical\", \"Trinitrotoluene\"]", "chemical"]),AtomLabels->{"C"|"N"->MoleculeProperty["OxidationStates"]}]

Example: Make a 2D plot of a sugar labelling atoms by their stereo

GraphicsColumn[{
MoleculePlot["D-Gulose",AtomLabels->"AtomChirality"],
MoleculePlot["mannose",AtomLabels->"AtomChirality"]
}]

ChemicalFormula

A “Chemical” entity represents a single chemical species with a record in the knowledgebase, complete with curated properties, e.g. melting point, specific heat capacity, etc

A Molecule can be any chemical structure, must have connectivity specified

A ChemicalFormula has only a list of atom types and their coefficients - it represents any (or all) chemical species with a given formula

Molecule["C6H5OH"]

ChemicalFormula["C6H5OH"]

A formula has a distinct molecular mass and charge

ChemicalFormula["C6H5OH"]["MolecularMass"]

ChemicalFormula["C6H5OH"]["NetCharge"]

A Molecule can match to a given formula

MoleculeMatchQ[Molecule[],ChemicalFormula["C6H5OH"]]

Example: Parse an arbitrarily nested chemical formula

atomicSymbols=EntityValue["Element","AtomicSymbol"]

ChemicalFormula@Nest[RandomChoice[atomicSymbols]<>"("<>#<>")"<>IntegerString[RandomInteger[{2,5}]]&,"C2H4",10]

%["HillFormula"]

%%["MolecularMass"]

FindIsomers[%%%]

MoleculeMatchQ

Joins other Molecule pattern-matching functions:

FindMoleculeSubstructure

MoleculeContainsQ

MoleculeFreeQ

MoleculeSubstructureCount

Test whether two molecules match each other:

MoleculeMatchQ[
Molecule[{"H","H","O"},{Bond[{1,3},"Single"],Bond[{2,3},"Single"]}],
Molecule[{"H","O","H"},{Bond[{2,1},"Single"],Bond[{3,2},"Single"]}]
]

Test whether a molecule matches a formula:

MoleculeMatchQ[
Molecule[],
ChemicalFormula[]
]

Test whether a molecule matches a pattern:

MoleculeMatchQ[
Molecule[],
MoleculePattern["a1aaaaa1"]
]

A diatomic molecule can be matched against a Bond:

MoleculeMatchQ[(Entity["hydrogen chloride", Entity["Chemical","HydrogenChloride"], "Entity[\"Chemical\", \"HydrogenChloride\"]", "chemical"]),Bond[{"Cl",_}]]

By default stereoisomers do not match each other:

MoleculeMatchQ[Molecule["l-alanine"],Molecule["d-alanine"]]

MoleculeMatchQ[Molecule["l-alanine"],Molecule["d-alanine"],IgnoreStereochemistry->True]

MoleculeMatchQ[(Entity["water", Entity["Chemical","Water"], "Entity[\"Chemical\", \"Water\"]", "chemical"]),(Entity["heavy water", Entity["Chemical","DeuteriumOxide"], "Entity[\"Chemical\", \"DeuteriumOxide\"]", "chemical"])]

MoleculeMatchQ[(Entity["water", Entity["Chemical","Water"], "Entity[\"Chemical\", \"Water\"]", "chemical"]),(Entity["heavy water", Entity["Chemical","DeuteriumOxide"], "Entity[\"Chemical\", \"DeuteriumOxide\"]", "chemical"]),IgnoreIsotopes->True]

Overview of Chemical representations

BioSequence["Peptide","T"]

Molecule@%

ToEntity@%

ChemicalFormula@%

MoleculeMatchQ[BioSequence[],ChemicalFormula[]]

Outer

FindIsomers

FindIsomers will return a list of molecules with the same chemical formula.  By default it returns molecules

FindIsomers[ChemicalFormula["C6H5OH"]]

Use the second argument to specify you want entities

FindIsomers[ChemicalFormula["C6H5OH"],"Entity"]

For some formulas the number of isomers returned is large, storing them as SMILES strings is useful in this case:

FindIsomers[ChemicalFormula["C12H17NO2"],"SMILES"]//Short

Example:Find all isomers 2-hexene

ChemicalFormula[Molecule@"2-hexene"]

WordCloud[MoleculePlot/@FindIsomers[%]]

Example: Filter a list of isomers using a substructure pattern

Find isomers of caffeine that have an aromatic bond between oxygen and nitrogen and align them on their maximum common substructure

This example uses FindIsomers, MoleculeContainsQ, MoleculeMaximumCommonSubstructure, and MoleculeAlign

mols=Select[Echo[FindIsomers[((Entity["caffeine", Entity["Chemical","Caffeine"], "Entity[\"Chemical\", \"Caffeine\"]", "chemical"]))],"number of isomers found",Length],MoleculeContainsQ[Bond[{Atom["O","AromaticAtomQ"->True],Atom["N","AromaticAtomQ"->True]}]]];

Length[mols]

SeedRandom[1234];
selection=RandomSample[mols,5];
mcs=MoleculeMaximumCommonSubstructure[selection,"CompleteRings"]

MoleculePlot3D[#,mcs]&/@selection

Now take every molecule and align them in 3D

aligned=MoleculeAlign[First@selection,selection,mcs];
Show[MoleculePlot3D[#,mcs]&/@aligned]

ChemicalReaction

?ChemicalReaction

rxn=ChemicalReaction[\[LeftAssociation](Entity["zinc hydroxide", Entity["Chemical","ZincHydroxide"], "Entity[\"Chemical\", \"ZincHydroxide\"]", "chemical"])->1,(Entity["sulfuric acid", Entity["Chemical","SulfuricAcid"], "Entity[\"Chemical\", \"SulfuricAcid\"]", "chemical"])->1\[RightAssociation]->\[LeftAssociation](Entity["zinc sulfate", Entity["Chemical","ZincSulfate"], "Entity[\"Chemical\", \"ZincSulfate\"]", "chemical"])->1,(Entity["water", Entity["Chemical","Water"], "Entity[\"Chemical\", \"Water\"]", "chemical"])->2\[RightAssociation]]

Get the reactants or products

rxn["Reactants"]

rxn["Products"]

Get the counts for the products:

rxn["ProductCounts"]

Get a display equation:

rxn["ReactionEquation"]//TraditionalForm

Create a chemical reaction from an equation string:

ChemicalReaction["Bi(NO3)3 + NaOH -> Bi(OH)3 + NaNO3"]

Here the inputs are interpreted as chemical formulas:

%["Reactants"]

Create a reaction from a ReactionSMILES string:

ChemicalReaction["CSCC[C@H](N)C(=O)O.O=CC(=O)O>>CSCCC(=O)C(=O)O.NCC(=O)O"]

Here the components of the reaction are Molecule objects:

%["Products"]

Balancing chemical reactions

A ChemicalReaction object need not be balanced:

ChemicalReaction[{(Entity["zinc hydroxide", Entity["Chemical","ZincHydroxide"], "Entity[\"Chemical\", \"ZincHydroxide\"]", "chemical"]),(Entity["sulfuric acid", Entity["Chemical","SulfuricAcid"], "Entity[\"Chemical\", \"SulfuricAcid\"]", "chemical"])}->{(Entity["zinc sulfate", Entity["Chemical","ZincSulfate"], "Entity[\"Chemical\", \"ZincSulfate\"]", "chemical"]),(Entity["water", Entity["Chemical","Water"], "Entity[\"Chemical\", \"Water\"]", "chemical"])}]

Mass and charge balance can be checked with ReactionBalancedQ:

ReactionBalancedQ@%

Balance the reaction:

ReactionBalance@%%

ReactionBalance takes charge into consideration:

ReactionBalancedQ@ChemicalReaction["Cu+(aq) + Fe(s) → Fe+3(aq) + Cu(s)"]

ReactionBalance@ChemicalReaction["Cu+(aq) + Fe(s) → Fe+3(aq) + Cu(s)"]

Some reactions cannot be balanced:

ReactionBalance@ChemicalReaction[{(Entity["zinc hydroxide", Entity["Chemical","ZincHydroxide"], "Entity[\"Chemical\", \"ZincHydroxide\"]", "chemical"]),ChemicalFormula["HCl"]}->{(Entity["zinc sulfate", Entity["Chemical","ZincSulfate"], "Entity[\"Chemical\", \"ZincSulfate\"]", "chemical"]),(Entity["water", Entity["Chemical","Water"], "Entity[\"Chemical\", \"Water\"]", "chemical"])}]

ReactionBalance["C8H10N4O2 + O2 -> CO2 + H2O + N4"]

ReactionBalance["C8H10N4O2 + O2 ⟶ C7H8N4O2 + H2O + CO2"]

ReactionBalance["AlPO4 + Ca(NO3)2 -> Al(NO3)3 + Ca3(PO4)2"]

Example: Write a function to return balanced combustion reactions

simpleCombustableQ=MoleculeFreeQ[Atom[Except["C"|"H"|"O"]]]

combustionReaction[mol_?simpleCombustableQ]:=ReactionBalance[ChemicalReaction[{mol,(Entity["oxygen", Entity["Chemical","MolecularOxygen"], "Entity[\"Chemical\", \"MolecularOxygen\"]", "chemical"])}->{(Entity["carbon dioxide", Entity["Chemical","CarbonDioxide"], "Entity[\"Chemical\", \"CarbonDioxide\"]", "chemical"]),(Entity["water", Entity["Chemical","Water"], "Entity[\"Chemical\", \"Water\"]", "chemical"])}]]

combustionReaction[Molecule["benzene"]]

combustionReaction[Molecule["hexane"]]

combustionReaction[(Entity["isobutane", Entity["Chemical","2Methylpropane"], "Entity[\"Chemical\", \"2Methylpropane\"]", "chemical"])]

combustionReaction[LinguisticAssistant]

FeatureSpacePlot

Version 12.3 introduced new built-in feature extractors for molecule objects:

FeatureSpacePlot[Molecule/@,FeatureExtractor->"MoleculeTopologicalFeatures",LabelingFunction->(Placed[MoleculePlot[#1],Tooltip]&)]

FeatureSpacePlot[Molecule/@,FeatureExtractor->"AtomPairs",LabelingFunction->(Placed[MoleculePlot[#1],Tooltip]&)]

WFR: ElementDesignator

Find the IUPAC temporary name for undiscovered elements

Information[ResourceFunction["ElementDesignator"],{"Description","Usage"}]

[242,"Name"]

[1242,"Name"]

[123454321,"Name"]

WFR: ChemicalConvert

Information[ResourceFunction["ChemicalConvert"],{"Description","Usage"}]

[(Quantity[5, "mol", moles, "Moles"]),(Entity["mercury", Entity["Element","Mercury"], "Entity[\"Element\", \"Mercury\"]", "element"]),"Liters"]

[(Quantity[10, "mL", milliliters, "Milliliters"]),(Entity["water", Entity["Chemical","Water"], "Entity[\"Chemical\", \"Water\"]", "chemical"]),"Molecules"]

[(Quantity[10, "mL", milliliters, "Milliliters"]),(Entity["heavy water", Entity["Chemical","DeuteriumOxide"], "Entity[\"Chemical\", \"DeuteriumOxide\"]", "chemical"]),"Grams"]

WFR: MoleculeView

Information[ResourceFunction["MoleculeView"],"Description"]

ResourceFunction["MoleculeView"]["5-fluoro-1-(2R,5S)-[2(hydroxymethyl)-1,3-oxathiolan-5-yl]cytosine"]

The Last Slide

The Wolfram Chemistry Team

GraphicsGrid[{{,,},{,,}}]