
Introduction
The Raku package “Chemistry::Stoichiometry” is for Stoichiometry procedures and related data. The primary functionalities are:
- Calculation of molecular masses for chemical compound formulas
- Chemical equations balancing
- Multi-language support
Here are corresponding examples:
use Chemistry::Stoichiometry;
say molecular-mass('SO2');
# 64.058
say balance-chemical-equation('C2H5OH + O2 = H2O + CO2');
# [1*C2H5OH + 3*O2 -> 2*CO2 + 3*H2O]
The package has also functions for chemical element data retrieval and functions that convert between chemical names, symbols/abbreviations, and atomic numbers.
Here are a couple of examples:
say atomic-number('actinium');
# 89
say chemical-symbol('ガリウム');
# Ga
Remark: Multiple languages can be used for the names of the chemical elements. The corresponding functions automatically detect the language.
Remark: At this point the package has standard element names in the following languages:
my Chemistry::Stoichiometry::ResourceAccess $resources.instance;
say $resources.get-language-names-data.keys.sort;
# (Arabic Bulgarian Chinese Czech English German Greek Japanese Korean Persian Polish Portuguese Russian Spanish)
Adding new languages can be easily done by adding CSV files into the resources directory.
Related work
The package “Chemistry::Elements” developed by Brian D. Foy, [BF1], also has functions that convert between chemical names, symbols/abbreviations, and atomic numbers. (Several languages are supported.)
Mathematica / Wolfram Language (WL) has the function ElementData
, [WRI1].
In 2007 I wrote the original versions of the chemical equation balancing and molecular functionalities in WolframAlpha. See for example this output.
Installation
Package installations from both sources use zef installer (which should be bundled with the “standard” Rakudo installation file.)
To install the package from Zef ecosystem use the shell command:
zef install Chemistry::Stoichiometry
To install the package from the GitHub repository use the shell command:
zef install https://github.com/antononcube/Raku-Chemistry-Stoichiometry.git
Element data retrieval
Element data records
Element data of one or several elements can be obtained with the function chemical-element-data
:
say chemical-element-data('Cl');
# {Abbreviation => Cl, AtomicNumber => 17, AtomicWeight => 35.45, Block => p, Group => 17, Name => chlorine, Period => 3, Series => Halogen, StandardName => Chlorine}
.say for chemical-element-data(['H', 'Li', 'Na', 'K', 'Rb', 'Cs', 'Fr']);
# {Abbreviation => H, AtomicNumber => 1, AtomicWeight => 1.008, Block => s, Group => 1, Name => hydrogen, Period => 1, Series => Nonmetal, StandardName => Hydrogen}
# {Abbreviation => Li, AtomicNumber => 3, AtomicWeight => 6.94, Block => s, Group => 1, Name => lithium, Period => 2, Series => AlkaliMetal, StandardName => Lithium}
# {Abbreviation => Na, AtomicNumber => 11, AtomicWeight => 22.98976928, Block => s, Group => 1, Name => sodium, Period => 3, Series => AlkaliMetal, StandardName => Sodium}
# {Abbreviation => K, AtomicNumber => 19, AtomicWeight => 39.0983, Block => s, Group => 1, Name => potassium, Period => 4, Series => AlkaliMetal, StandardName => Potassium}
# {Abbreviation => Rb, AtomicNumber => 37, AtomicWeight => 85.4678, Block => s, Group => 1, Name => rubidium, Period => 5, Series => AlkaliMetal, StandardName => Rubidium}
# {Abbreviation => Cs, AtomicNumber => 55, AtomicWeight => 132.90545196, Block => s, Group => 1, Name => cesium, Period => 6, Series => AlkaliMetal, StandardName => Cesium}
# {Abbreviation => Fr, AtomicNumber => 87, AtomicWeight => 223, Block => s, Group => 1, Name => francium, Period => 7, Series => AlkaliMetal, StandardName => Francium}
Element names
say chemical-element('Cl');
# Chlorine
say chemical-element('Cl', 'Russian');
# Хлор
Chemical element names can be obtained using the function chemical-element-data
with the adverbs :name
or :standard-name
:
say chemical-element-data('Cl'):name;
# Chlorine
say chemical-element-data('Cl'):standard-name;
# Chlorine
Element symbols / abbreviations
say chemical-symbol('oxygen'); # 'O' from English
# O
say chemical-symbol('кислород'); # 'O' from Bulgarian
# O
Chemical element abbreviations can be obtained using the function chemical-element-data
with the adverbs :symbol
or :abbr
:
say chemical-element-data('oxygen'):symbol; # 'O' from English
# O
say chemical-element-data('кислород'):abbr; # 'O' from Bulgarian
# O
Note, that chemical-element
will automatically detect the language.
Atomic numbers
say atomic-number('Cl');
# 17
say atomic-number('actinium'); # from the English name of Ac
# 89
say atomic-number('берилий'); # from the Bulgarian name of Be
# 4
Alternatively, chemical-element-data
can be used with the adverbs :number
or :atomic-number
:
say chemical-element-data('Cl'):number;
# 17
say chemical-element-data('Cl'):atomic-number;
# 17
Atomic weights
say atomic-weight('Se');
# 78.971
say atomic-weight('ガリウム'); # from the Japanese name of Ga
# 69.723
Alternatively, chemical-element-data
can be used with the adverbs :weight
or :atomic-weight
:
say chemical-element-data('Cl'):weight;
# 35.45
say chemical-element-data('Cl'):atomic-weight;
# 35.45
Stoichiometry procedures
The functions molecular-mass
and balance-chemical-equation
are based on a parser for Simplified Molecular-Input Line-Entry System (SMILES), [OS1].
Molecular mass
Molecular mass for a compound:
say molecular-mass('SO2');
# 64.058
Molecular masses of the sides of a chemical equation:
say molecular-mass('C2H5OH + O2 -> H2O + CO2');
# 78.06700000000001 => 62.024
Note that the masses in the output above are different because the equation is not balanced.
Equation balancing
For a given chemical equation the function balance-chemical-equation
returns a list of balanced equations.
say balance-chemical-equation('C2H5OH + O2 = H2O + CO2');
# [1*C2H5OH + 3*O2 -> 2*CO2 + 3*H2O]
say balance-chemical-equation( 'K4Fe(CN)6 + H2SO4 + H2O = K2SO4 + FeSO4 + (NH4)2SO4 + CO' );
# [6*H2O + 6*H2SO4 + 1*K4Fe(CN)6 -> 3*(NH4)2SO4 + 6*CO + 1*FeSO4 + 2*K2SO4]
Remark: The result of the balancing is a list because certain chemical equations can be balanced in several ways corresponding to different reactions.
Abstract syntax tree
Here is a way to get Abstract Syntax Tree of a (parse-able) molecule formula:
my $cf = 'K4Fe(CN)6';
say Chemistry::Stoichiometry::Grammar.parse( $cf );
# 「K4Fe(CN)6」
# molecule => 「K4Fe(CN)6」
# sub-molecule => 「K4」
# chemical-element-mult => 「K4」
# chemical-element => 「K」
# K-stoichiometry => 「K」
# number => 「4」
# sub-molecule => 「Fe」
# chemical-element => 「Fe」
# Fe-stoichiometry => 「Fe」
# sub-molecule => 「(CN)6」
# group-mult => 「(CN)6」
# group => 「(CN)」
# molecule => 「CN」
# sub-molecule => 「C」
# chemical-element => 「C」
# C-stoichiometry => 「C」
# sub-molecule => 「N」
# chemical-element => 「N」
# N-stoichiometry => 「N」
# number => 「6」
References
[BF1] Brian D. Foy, Chemistry::Elements Raku package, (2016-2018), GitHub/briandfoy.
[CJ1] Craig A. James, OpenSMILES specification, (2007-2016), OpenSMILES.org.
[WRI1] Wolfram Research, ElementData, Wolfram Language function, (2007), (updated 2014), Wolfram Language System Documentation Center.