Skip to main content

ToothNotation

Convert between dental tooth-numbering systems — FDI (ISO 3950), Universal, and Palmer — with one source of truth and 293 verifying tests.

Tooth numbering is a perennial source of error and re-implementation in dental software: the US uses the Universal system (1–32, A–T), most of the world uses FDI / ISO 3950 (two-digit quadrant codes), and clinicians often chart in Palmer notation. Every project that touches teeth ends up rewriting these conversions, usually with subtle off-by-one and inverted-quadrant bugs.

ToothNotation does it once, correctly, with FDI as the canonical internal key — so every conversion is derived from a single representation rather than a tangle of pairwise lookup tables. It ships as a small dependency-free Python package, a CLI, and an interactive React odontogram you can drop into a teaching site or chart UI.

from toothnotation import convert, parse

convert("36", "fdi", "universal")   # "19"
convert("19", "universal", "fdi")    # "36"
convert("UR6", "palmer", "universal") # "3"

t = parse("36")          # auto-detects the system
t.name                   # "lower left first molar"
t.universal              # "19"
str(t.palmer)            # "LL6"
t.dentition, t.arch      # ("permanent", "lower")

Why trust it

Tooth maps are easy to get wrong, so correctness is the whole point of the library:

  • FDI-canonical design. Every system parses to an FDI code and every output is derived from it. There is exactly one source of truth, not six pairwise maps to keep in sync.
  • 293 tests, including every one of the 52 teeth round-tripped through all three systems (FDI → system → FDI must return the original). This catches any off-by-one or inverted quadrant across the whole dentition, not just spot checks.
  • Hand-verified anchors against ISO 3950 and ADA references (e.g. FDI 11 = Universal 8 = Palmer UR1; FDI 48 = Universal 32).
$ pytest -q
293 passed

Install

pip install toothnotation

No runtime dependencies. Python 3.9+.

Use it

Python

from toothnotation import convert, parse, all_teeth, detect_system

detect_system("19")          # "universal"  (not a valid FDI code)
detect_system("36")          # "fdi"
detect_system("UR6")         # "palmer"

[t.universal for t in all_teeth("primary")]   # ['A', 'B', ... 'T']

tooth = parse("65")
tooth.name                   # "upper left second primary molar"
tooth.tooth_type             # "second primary molar"

The Tooth object exposes fdi, universal, palmer, name, quadrant, arch, side, dentition, tooth_type, and position (counting from the midline), plus .to("fdi" | "universal" | "palmer").

Command line

toothnotation convert 36 fdi universal     # 19
toothnotation info UR6                       # full detail, auto-detected
toothnotation chart --system universal       # print the chart

Interactive chart (React)

toothchart.jsx is a self-contained component — an anatomically arranged odontogram that displays any of the three systems, lets you click a tooth for full detail, and converts codes live. Palmer brackets are drawn the way they appear on a paper chart (the quadrant corner is marked with real borders, not an approximated glyph). The conversion logic is ported from the Python package and verified with the same round-trip checks.

Drop it into a teaching site, a charting UI, or a patient-education page.

The three systems, briefly

System Permanent Primary Example (lower-left first molar)
FDI (ISO 3950) 1148 (quadrant + position) 5185 36
Universal (US) 132 AT 19
Palmer quadrant + 18 quadrant + AE LL6

Contributing

Issues and PRs welcome — especially additional reference anchors, alternative Palmer text conventions, and bindings in other languages. Every conversion change must keep the exhaustive round-trip tests green.

Citing

If this is useful in research or software, please cite it (see CITATION.cff). A short software paper is in paper.md.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

toothnotation-0.1.0.tar.gz (17.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

toothnotation-0.1.0-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

Details for the file toothnotation-0.1.0.tar.gz.

File metadata

  • Download URL: toothnotation-0.1.0.tar.gz
  • Upload date:
  • Size: 17.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for toothnotation-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5d3481933f67cf811ab6192239c9f2eb6e15df195679aae9f1c624b866a15560
MD5 4a864e8a9b680b4dd796c9f9af013a27
BLAKE2b-256 06d50e4ff8a2ebb96d4a4086c797e9b3820df20a520dab22a71c6d50cef09fb8

See more details on using hashes here.

File details

Details for the file toothnotation-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: toothnotation-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for toothnotation-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0342c35ed0e781d8aa681e4022d4a361cd4b90bad64b7350c1e7078336b37889
MD5 cf9066a9b0a89faf1553c394a147f0af
BLAKE2b-256 c15f78476c6650c17853e4a8e57d30243a9734d9de88a674c9eaabf1a13803bf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page