Skip to content
Steinbeck-LabPublic

About

Deterministic structure-to-IUPAC-name generator. Names are checked by an OPSIN round trip, the engine declines rather than guess, and --provenance says how each name was checked.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

14 stars

Watchers

1 watching

Forks

Repository files navigation

Orthonym engine. Checked IUPAC Names for Chemical Structures. Deterministic, rule-based, following the IUPAC 2013 recommendations.

Try it online  Quick start


A SMILES string goes in. A verified IUPAC name comes out, or a clear "no". Never a guess.

Licence: MIT Python 3.10+ IUPAC 2013 CI Docs DOI Web app: Orthonym-Web Built with: orthonym-skills

What it names: seven cards, each with a drawing, the name the engine prints and its tier. Bridged fused rings: (4R,4aR,7S,7aR,12bS)-3-methyl-2,3,4,4a,7,7a-hexahydro-1H-4,12-methano[1]benzofuro[3,2-e]isoquinoline-7,9-diol, pin_verified. Hypervalent iodine: iodylbenzene, pin_verified. Stereocentre at phosphorus: (1S,2R)-1,2-diphenylphospholane, pin_verified. Isotope labels: (2R,4S)-(4-2H1,2-3H1)pentane, pin_verified. Metal salt: zinc diacetate, pin_verified. Cage, with --emit-tier best-effort: pentacyclo[9.3.1.0^3,14.0^6,13.0^8,12]pentadecane, systematic_verified. Spiro: spiro[4.5]decane, pin_verified.

Quick start

pip install orthonym                      # or: conda install -c conda-forge orthonym
orthonym --fetch-jars                     # one time: downloads and checks the OPSIN and centres jars

You need Python 3.10+ and a Java 11+ runtime on your PATH (the conda package brings Java with it). More in Install.

from orthonym import name_compound

name_compound("CCO")                          # 'ethanol'
name_compound("CC(=O)Oc1ccccc1C(=O)O")        # '2-(acetyloxy)benzoic acid'
name_compound("Cn1cnc2c1c(=O)n(C)c(=O)n2C")   # '1,3,7-trimethyl-3,7-dihydro-1H-purine-2,6-dione'
name_compound("C/C=C/C")                      # '(2E)-but-2-ene'
name_compound("C[C@H](O)CC")                  # '(2S)-butan-2-ol'

name_compound also takes an RDKit Chem.Mol, for example a molecule read from an SDF file.

orthonym "CCO"                                # ethanol
orthonym "CC(=O)Oc1ccccc1C(=O)O" --provenance # the name plus its tier and how it was checked, as JSON
orthonym --batch molecules.smi -o names.txt   # one SMILES per line

These commands use the default, the best-effort tier: the verified Preferred IUPAC Name (PIN) when the strict PIN path builds one, and otherwise a systematic name that OPSIN read back to your structure. When a name is not the PIN, orthonym says so once on the error stream, and --provenance shows the tier of each name. For the PIN only, add --emit-tier pin (one SMILES or --batch), or in Python name_compound(smiles, emit_tier="pin"). See Output tiers.

Five commands and what they print. orthonym CCO prints ethanol, tier pin_verified. Ibuprofen prints (2R)-2-[4-(2-methylpropyl)phenyl]propanoic acid, pin_verified. With --emit-tier valid, sphingosine prints (2S,3R,4E)-2-aminooctadec-4-ene-1,3-diol, pin_unverified, and retinol prints (2E,4E,6E,8E)-3,7-dimethyl-9-(2,6,6-trimethylcyclohex-1-en-1-yl)nona-2,4,6,8-tetraen-1-ol, pin_verified. Uranium trioxide, with --on-failure label, prints inorganic compound (not supported), abstain.

Real output, generated from the engine. The tier at the right comes from --provenance.

How names are checked

The round trip for caffeine. Orthonym writes the name 1,3,7-trimethyl-3,7-dihydro-1H-purine-2,6-dione. OPSIN reads that name back into a structure. The InChIKey of your structure and the InChIKey of what OPSIN read are both RYYVLZVUVIJVGH-UHFFFAOYSA-N, so OPSIN confirms that the name describes your structure; the strict PIN path built and certified it, so it is labelled pin_verified. Below, the four tiers a name can land on: PIN, fallback, best effort and no name, with the engine's tier ids.
  • Deterministic. Names are built from the rules of the IUPAC 2013 recommendations (the "Blue Book"). No neural network, no sampling: the same input always gives the same name.
  • Checked. OPSIN, which never saw your structure, reads every name back. The result must match your structure in constitution, charge and stereo. A few name forms OPSIN cannot read are checked another way, and --provenance marks them.
  • Honest. A name that fails a check is withdrawn. When no name is left, Orthonym says so and gives the reason. It never guesses.

More in How every name is checked and Declines.

Output tiers

By default Orthonym returns the name of the best-effort tier: the Preferred IUPAC Name (PIN) when the strict PIN path builds it and OPSIN reads it back, and otherwise a systematic name that is not the PIN, labelled with its tier. --emit-tier pin returns only the verified PIN, or no name, as releases up to 1.0.x did by default. The other tiers are asked for by name with --emit-tier (name_compound(..., emit_tier=...) in Python) and label every name they return. On 2,000 held-out ChEBI molecules the default names 1,994 (99.70 %) and declines 5, and --emit-tier pin names 1,106 (55.30 %) and declines 891. A name counts only when OPSIN 2.9.0 reads it back to the molecule (both on three sets).

--emit-tier Returns
(none), the default the best-effort tier
pin the verified PIN (with a few listed exceptions), or no name: the default of releases up to 1.0.x
valid also other systematic names that OPSIN reads back to your structure
complete also general names for aromatic and heterocyclic ring systems
best-effort also the last-resort names, such as von Baeyer and spiro names for ring systems of up to 100 skeletal atoms and 15 rings (200 and 30 where no other producer names the structure)
full-coverage also coordination names for metal tetrapyrrole and corrin complexes

Without OPSIN to read the names back (a host without Java, in the reduced mode), and for --style general and cas, the default is the pin tier, as it was.

--provenance labels each name: pin_verified (the PIN, verified), pin_unverified (PIN form, preferred status not certified), systematic_verified (a correct name that is not the PIN), best_effort (a last-resort name) or abstain (no name). Metal compounds are admitted one metal at a time. The exceptions, the labels and the metals are in Output tiers.

Documentation

How Orthonym was built

Orthonym was built with Claude Code under a fixed set of working rules, published as orthonym-skills (20 skills, 2 hooks, 1 agent). Each rule makes a step rest on a measurement instead of a guess: fixed test sets before and after each change, proof that the code to change is on the execution path, a primary source before an expected value in a test changes, a regression gate before every merge, and a written handoff between sessions.

How to cite

Please cite the preprint:

Rajan, K.; Zielesny, A.; Steinbeck, C. Orthonym: verified IUPAC names for chemical structures in the wild. ChemRxiv 2026. doi:10.26434/chemrxiv.15009769/v1

@article{rajan2026orthonym,
  author  = {Rajan, Kohulan and Zielesny, Achim and Steinbeck, Christoph},
  title   = {{Orthonym}: verified {IUPAC} names for chemical structures in the wild},
  journal = {ChemRxiv},
  year    = {2026},
  doi     = {10.26434/chemrxiv.15009769/v1}
}

To cite the software version you used, cite its Zenodo archive:

@software{orthonym,
  author  = {Rajan, Kohulan and Zielesny, Achim and Steinbeck, Christoph},
  title   = {{Orthonym}},
  version = {1.0.9},
  year    = {2026},
  doi     = {10.5281/zenodo.23044199},
  url     = {https://github.com/Steinbeck-Lab/Orthonym}
}

Every release is archived on Zenodo. The DOI 10.5281/zenodo.23044199 stands for all versions and resolves to the newest one.

Built on

Orthonym stands on the IUPAC 2013 recommendations and on open cheminformatics software: RDKit reads the structure, OPSIN 2.9.0 reads the names back to check them, and centres 1.2.1 assigns the CIP descriptors. Without them there would be no Orthonym. orthonym --opsin main reads the names back with OPSIN's main branch instead, built on your machine with a JDK (Install); only then are phane names built for cyclophanes and linear phanes (Phane names).

Favre, H. A.; Powell, W. H. Nomenclature of Organic Chemistry: IUPAC Recommendations and Preferred Names 2013. Royal Society of Chemistry, 2013. doi:10.1039/9781849733069

Lowe, D. M.; Corbett, P. T.; Murray-Rust, P.; Glen, R. C. Chemical Name to Structure: OPSIN, an Open Source Solution. J. Chem. Inf. Model. 2011, 51 (3), 739–753. doi:10.1021/ci100384d

Hanson, R. M.; Musacchio, S.; Mayfield, J. W.; Vainio, M. J.; Yerin, A.; Redkin, D. Algorithmic Analysis of Cahn–Ingold–Prelog Rules of Stereochemistry: Proposals for Revised Rules and a Guide for Machine Implementation. J. Chem. Inf. Model. 2018, 58 (9), 1755–1765. doi:10.1021/acs.jcim.8b00324

Licence

MIT, see LICENSE. The OPSIN and centres jars are not part of this repository; they are downloaded from their official releases and keep their own licences (see NOTICE).


Made with coffee by Kohulan Rajan at

Beilstein-Institut and Steinbeck Lab, Friedrich Schiller University Jena

An official collaboration for open science

About

Deterministic structure-to-IUPAC-name generator. Names are checked by an OPSIN round trip, the engine declines rather than guess, and --provenance says how each name was checked.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

14 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages