Chemical Formula Manipulation

ChemistryLab allows you to create and manipulate chemical formulas. It provides the Formula type (holds a formula string, multiple string representations, an atom composition map and a charge) and AtomGroup helper values, plus utilities to convert between notations (Phreeqc ↔ Unicode), to format/colour formulas, to perform arithmetic on formulas, and to validate atom symbols.

struct Formula{T<:Number}
    expr::String
    phreeqc::String
    unicode::String
    colored::String
    composition::OrderedDict{Symbol,T}
    charge::Int8
end

Formula construction

Formulas can be constructed:

  • by parsing a string containing eventually fractional or decimal coefficients
f = Formula("C3AFS5//8H4.32")
Formula{Real}
    formula: C3AFS5//8H4.32 ◆ C₃AFS⅝H₄.₃₂
composition: C => 3, A => 1, F => 1, S => 5//8, H => 4.32
     charge: 0
  • from a dictionary
fCaCO3 = Formula(Dict(:Ca => 1, :C => 1, :O => 3))
Formula{Int64}
    formula: CaCO3 ◆ CaCO₃
composition: Ca => 1, O => 3, C => 1
     charge: 0
  • from atom groups
fCO2 = AtomGroup(:C) + AtomGroup(2,:O)
Formula{Int64}
    formula: CO2 ◆ CO₂
composition: O => 2, C => 1
     charge: 0

Charges can also be included during the creation in two different ways:

fHSO₄⁻ = AtomGroup(:H)+AtomGroup(:S)+AtomGroup(4,:O)+AtomGroup(:e)
Formula{Int64}
    formula: HSO4- ◆ HSO₄-
composition: H => 1, S => 1, O => 4
     charge: -1

Or:

fNa⁺ = AtomGroup(:Na)+AtomGroup(:Zz)
Formula{Int64}
    formula: Na+
composition: Na => 1
     charge: 1

Formula accessors

All fields of a Formula are accessible through dedicated functions:

f = Formula("Ca(HSiO3)+")
expr(f)         # canonical string (as given)
phreeqc(f)      # Phreeqc notation: "Ca(HSiO3)+"
unicode(f)      # Unicode notation: "Ca(HSiO₃)⁺"
colored(f)      # colored terminal string (ANSI)
composition(f)  # OrderedDict{Symbol,Int}: composition by atom
charge(f)       # Int8: net charge
1

Notation conversion

Switch between Phreeqc (plain text) and Unicode (pretty) notations without creating a full Formula:

phreeqc_to_unicode("SO4-2")   # "SO₄²⁻"
unicode_to_phreeqc("SO₄²⁻")  # "SO4-2"
phreeqc_to_unicode("Ca+2")    # "Ca²⁺"
"Ca²⁺"

Type of Formula

The type of the Formula struct being associated with the most complex type of the set of coefficients.

typeof(Formula("H2O"))
Formula{Int64}
typeof(Formula("C3AFS5//8H4.32"))
Formula{Real}

Change of type

Coefficient types can be converted a posteriori.

convert(Float64, Formula("H2O"))
Formula{Float64}
    formula: H2O ◆ H₂O
composition: H => 2.0, O => 1.0
     charge: 0

Formula arithmetic

Scalar multiplication and division return a new Formula with all coefficients scaled:

f = Formula("H2O")

f * 2     # H₄O₂  — all coefficients × 2
f / 2     # H₁O½  — all coefficients ÷ 2 (Float64)
f // 2    # H₁O½  — rational coefficients (Rational)
Formula{Rational{Int64}}
    formula: HO½ ◆ HO1//2
composition: H => 1//1, O => 1//2
     charge: 0

Individual atoms can be appended with + AtomGroup(n, :Symbol):

fCO2 = Formula("CO2")
fCO2 + AtomGroup(2, :H)   # CO₂H₂  — add 2 hydrogen atoms
Formula{Int64}
    formula: CH2O2 ◆ CH₂O₂
composition: C => 1, O => 2, H => 2
     charge: 0

For element-wise transformations, use apply:

apply(x -> x * 0.5, Formula("H2O"))   # H₁O½  — same as f / 2
Formula{Float64}
    formula: H2O ◆ H₂O
composition: H => 1.0, O => 0.5
     charge: 0
Advanced operations

For fractional stoichiometry, reaction algebra, and notation conversion see the Advanced Topics page.