Skip to content

Parser

Chemical string notation, parsed by the chemistry engine. Two notations are supported — SMILES and SMARTS — and both are reached through a type, not a helper function.

Quick reference

Expression Input Output Use when
mp.io.read_smiles(s) SMILES, one component Atomistic One specific molecule
mp.SmilesIR(s) SMILES SmilesIR Inspect before converting
mp.SmilesIR(s).n_components SMILES int How many molecules the string names
mp.SmilesIR(s).to_atomistic() SMILES Atomistic Every component as one graph
mp.SmilesIR(s).components() dot-separated SMILES list[Atomistic] One graph per component ([Li+].[F-])
mp.SmartsPattern(p) SMARTS SmartsPattern Pattern matching / typification

There is no parse_smiles / parse_smarts / parse_molecule / parse_mixture: each was a wrapper whose body was a constructor call. Name the type instead.

Canonical example

import molpy as mp

mol = mp.io.read_smiles("CCO") # Atomistic (heavy atoms only)
mol = mp.Perceive().find_hydrogens(mol) #... with hydrogens

ions = [
 mp.Atomistic.adopt(m) # [Atomistic, Atomistic]
 for m in mp.SmilesIR("[Li+].[F-]").components()
]

query = mp.SmartsPattern("[C;X4][O;H1]") # compiled query
query.find_matches(mol) # -> list[SmartsMatch]

read_smiles raises on a .-separated string: that names a set of molecules, not a molecule. Use components().

Polymer notations

BigSMILES, CGSmiles and G-BigSMILES are no longer parsed. Polymer architecture is built explicitly with molpy.builder.assemblyMonomerLibrary, PolymerBuilder, GraphAssembler — where the architecture is code rather than a string to decode.

  • mp.Perceive — hydrogens, aromaticity, rings, stereo (perceive before you match: X4 and H1 count what is actually in the graph)
  • mp.RingInfo — ring / ring-system queries
  • Guide: Parsing Chemistry

Full API

parser

Parsing façade — SMILES / SMARTS from molrs; moltemplate stays local.

Chemistry notation is parsed by molrs only, and it is parsed by types, not by helper functions:

  • :class:molrs.io.SmilesIRSmilesIR("CCO") parses; .to_atomistic() / .components() / .n_components read the result.
  • :class:~molpy.core.atomistic.Atomisticmp.io.read_smiles("CCO") when a molpy graph is what you want.
  • :class:molrs.perceive.SmartsPatternSmartsPattern("[#6]") compiles a query.

There is deliberately nothing else here. parse_smiles / parse_smarts / parse_molecule / parse_mixture / smiles_to_atomistic / smilesir_to_atomistic were wrappers whose bodies were a constructor call — one was literally return SmartsPattern(pattern), and two were aliases of a third. A free function that only forwards to a constructor is a second name for that constructor, and a second name is a thing to keep in sync.

parse_mixture also split the string on '.' and re-parsed each piece, which decides what a separator is before the parser has said so; SmilesIR.components() splits the parsed components instead.

:mod:molpy.parser.moltemplate is a separate, non-Lark .lt reader and is not chemistry-notation parsing.

Migration:

============================= ============================================== was now ============================= ============================================== parse_smiles(s) SmilesIR(s) parse_smarts(p) SmartsPattern(p) parse_molecule(s) mp.io.read_smiles(s) smiles_to_atomistic(s) mp.io.read_smiles(s) smilesir_to_atomistic(ir) Atomistic.adopt(ir.to_atomistic()) parse_mixture(s) [Atomistic.adopt(m) for m in SmilesIR(s).components()] ============================= ==============================================

SmartsMatch

One SMARTS embedding.

SmartsPattern

SmartsPattern(smarts)

Compiled, atom-map-aware SMARTS query over an :class:Atomistic.

Wraps the core Rust SMARTS engine (non-uniquified, RDKit uniquify=False). Daylight atom maps ([C:1]) add no match constraint; pass mapped=True to :meth:find_matches for the legacy dict shortcut.

SmilesIR

Intermediate representation of a parsed SMILES string.