chempy package

ChemPy is a Python package useful for solving problems in chemistry.

Submodules

chempy.arrhenius module

chempy.chemistry module

class chempy.chemistry.Equilibrium(reac, prod, param=None, inact_reac=None, inact_prod=None, name=None, ref=None, data=None, checks=('any_effect', 'all_positive', 'all_integral'))[source]

Bases: chempy.chemistry.Reaction

Represents an equilibrium reaction

See Reaction for parameters

Methods

K([variables, backend]) Return equilibrium constant
Q(substances, concs) Calculates the equilibrium qoutient
all_prod_stoich(substances) Per substance product stoichiometry tuple (active & inactive)
all_reac_stoich(substances) Per substance reactant stoichiometry tuple (active & inactive)
as_reactions([kf, kb, units, variables, backend]) Creates a forward and backward Reaction pair
cancel(rxn) multiplier of how many times rxn can be added/subtracted
charge_neutrality_violation(substances) Net amount of charge produced
check_all_integral() Checks if all stoichiometric coefficents are integers
check_all_positive() Checks if all stoichiometric coefficients are positive
check_any_effect() Checks if the reaction has any effect
composition_violation(substances[, ...]) Net amount of constituent produced
copy(**kwargs)
dimensionality()
eliminate(rxns, wrt) Linear combination coefficients for elimination of a substance
equilibrium_constant([variables, backend]) Return equilibrium constant
from_string(string[, substance_keys, globals_]) Parses a string into a Reaction instance
has_precipitates(substances)
html(substances[, with_param]) Returns a HTML representation of the reaction
keys()
latex(substances[, with_param, magnitude_fmt]) Returns a LaTeX representation of the reaction
mass_balance_violation(substances) Net amount of mass produced
net_stoich(substance_keys) Per substance net stoichiometry tuple (active & inactive)
non_precipitate_stoich(substances) Only stoichiometry of non-precipitates
order() Sum of (active) reactant stoichiometries
precipitate_factor(substances, sc_concs)
precipitate_stoich(substances) Only stoichiometry of precipitates
rate([variables, backend, substance_keys]) Evaluate the rate of a reaction
rate_expr() Turns self.param into a RateExpr instance (if not already)
string([substances, with_param, magnitude_fmt]) Returns a string representation of the reaction
unicode(substances[, with_param]) Returns a unicode string representation of the reaction
K(variables=None, backend=<module 'math' (built-in)>)

Return equilibrium constant

Parameters:

variables : dict, optional

backend : module, optional

Q(substances, concs)[source]

Calculates the equilibrium qoutient

as_reactions(kf=None, kb=None, units=None, variables=None, backend=<module 'math' (built-in)>)[source]

Creates a forward and backward Reaction pair

Parameters:

kf : float or RateExpr

kb : float or RateExpr

units : module

variables : dict, optional

backend : module

cancel(rxn)[source]

multiplier of how many times rxn can be added/subtracted

Parameters:rxn : Equilibrium

Examples

>>> e1 = Equilibrium({'Cd(OH)2(s)': 4, 'H2O': 4},
...                  {'Cd4(OH)4+4': 1, 'H+': 4, 'OH-': 8}, 7.94e-91)
>>> e2 = Equilibrium({'H2O': 1}, {'H+': 1, 'OH-': 1}, 10**-14)
>>> e1.cancel(e2)
-4
>>> print(e1 - 4*e2)
4 Cd(OH)2(s) = 4 OH- + Cd4(OH)4+4; 7.94e-35
dimensionality()[source]
static eliminate(rxns, wrt)[source]

Linear combination coefficients for elimination of a substance

Parameters:

rxns : iterable of Equilibrium instances

wrt : str (substance key)

Examples

>>> e1 = Equilibrium({'Cd+2': 4, 'H2O': 4}, {'Cd4(OH)4+4': 1, 'H+': 4}, 10**-32.5)
>>> e2 = Equilibrium({'Cd(OH)2(s)': 1}, {'Cd+2': 1, 'OH-': 2}, 10**-14.4)
>>> Equilibrium.eliminate([e1, e2], 'Cd+2')
[1, 4]
>>> print(1*e1 + 4*e2)
4 Cd(OH)2(s) + 4 H2O = 4 H+ + 8 OH- + Cd4(OH)4+4; 7.94e-91
equilibrium_constant(variables=None, backend=<module 'math' (built-in)>)[source]

Return equilibrium constant

Parameters:

variables : dict, optional

backend : module, optional

html_arrow = '&harr;'
latex_arrow = '\\rightleftharpoons'
param_char = 'K'
precipitate_factor(substances, sc_concs)[source]
str_arrow = '='
unicode_arrow = '\xe2\x87\x8c'
class chempy.chemistry.Reaction(reac, prod, param=None, inact_reac=None, inact_prod=None, name=None, ref=None, data=None, checks=('any_effect', 'all_positive', 'all_integral'))[source]

Bases: object

Class representing a chemical reaction

Consider for example:

2 R –> A + P; r = k*A*R*R

this would be represented as Reaction({'A': 1, 'R': 2}, {'A': 2, 'P': 1}, param=k). Some reactions have a larger stoichiometric coefficient than what appears in the rate expression, e.g.:

5 A + B –> C; r = k*A*B

this can be represented as Reaction({'C1': 1, 'C2': 1}, {'B': 1}, inact_reac={'C1': 4}, param=k).

The rate constant information in param may be a subclass of chempy.kinetics.rates.RateExpr or carry a _as_RateExpr(), if neither: param will be assumed to be a rate constant for a mass-action type of kinetic expression.

Additional data may be stored in the data dict.

Parameters:

reac : dict (str -> int)

if reac is a set multiplicities are assumed to be 1

prod : dict (str -> int)

if reac is a set multiplicities are assumed to be 1

param : float or callable

Special case (side-effect): if param is a subclass of kinetics.rates.RateExpr and its rxn is None it will be set to self.

inact_reac : dict (optional)

inact_prod : dict (optional)

name : str (optional)

k : deprecated (alias for param)

ref : object

reference

data : dict (optional)

checks : iterable of str

raises value error if any method check_%s returns False for all %s in checks.

Examples

>>> r = Reaction({'H2': 2, 'O2': 1}, {'H2O': 2})
>>> r.keys() == {'H2', 'O2', 'H2O'}
True
>>> r.order()
3
>>> r.net_stoich(['H2', 'H2O', 'O2'])
(-2, 2, -1)
>>> print(r)
2 H2 + O2 -> 2 H2O

Attributes

reac: dict  
prod: dict  
param: object  
inact_reac: dict  
inact_prod: dict  
name: str  
ref: str  
data: dict  

Methods

all_prod_stoich(substances) Per substance product stoichiometry tuple (active & inactive)
all_reac_stoich(substances) Per substance reactant stoichiometry tuple (active & inactive)
charge_neutrality_violation(substances) Net amount of charge produced
check_all_integral() Checks if all stoichiometric coefficents are integers
check_all_positive() Checks if all stoichiometric coefficients are positive
check_any_effect() Checks if the reaction has any effect
composition_violation(substances[, ...]) Net amount of constituent produced
copy(**kwargs)
from_string(string[, substance_keys, globals_]) Parses a string into a Reaction instance
has_precipitates(substances)
html(substances[, with_param]) Returns a HTML representation of the reaction
keys()
latex(substances[, with_param, magnitude_fmt]) Returns a LaTeX representation of the reaction
mass_balance_violation(substances) Net amount of mass produced
net_stoich(substance_keys) Per substance net stoichiometry tuple (active & inactive)
non_precipitate_stoich(substances) Only stoichiometry of non-precipitates
order() Sum of (active) reactant stoichiometries
precipitate_stoich(substances) Only stoichiometry of precipitates
rate([variables, backend, substance_keys]) Evaluate the rate of a reaction
rate_expr() Turns self.param into a RateExpr instance (if not already)
string([substances, with_param, magnitude_fmt]) Returns a string representation of the reaction
unicode(substances[, with_param]) Returns a unicode string representation of the reaction
all_prod_stoich(substances)[source]

Per substance product stoichiometry tuple (active & inactive)

all_reac_stoich(substances)[source]

Per substance reactant stoichiometry tuple (active & inactive)

charge_neutrality_violation(substances)[source]

Net amount of charge produced

Parameters:substances: dict
Returns:float: amount of net charge produced/consumed
check_all_integral()[source]

Checks if all stoichiometric coefficents are integers

check_all_positive()[source]

Checks if all stoichiometric coefficients are positive

check_any_effect()[source]

Checks if the reaction has any effect

composition_violation(substances, composition_keys=None)[source]

Net amount of constituent produced

If composition keys correspond to conserved entities e.g. atoms in chemical reactions, this function should return a list of zeros.

copy(**kwargs)[source]
classmethod from_string(string, substance_keys=None, globals_=None, **kwargs)[source]

Parses a string into a Reaction instance

Parameters:

string : str

String representation of the reaction.

substance_keys : iterable of strings or string or None

Used prevent e.g. misspelling. if str: split is invoked, if None: no checking done.

globals_ : dict (optional)

Dictionary for eval for (default: None -> {‘chempy’: chempy}) If False: no eval will be called (useful for web-apps).

**kwargs :

Passed on to constructor.

Notes

chempy.util.parsing.to_reaction() is used which in turn calls eval() which is a severe security concern for untrusted input.

Examples

>>> r = Reaction.from_string("H2O -> H+ + OH-; 1e-4", 'H2O H+ OH-')
>>> r.reac == {'H2O': 1} and r.prod == {'H+': 1, 'OH-': 1}
True
>>> r2 = Reaction.from_string("2 H2O -> 2 H2 + O2", 'H2O H2 O2')
>>> r2.reac == {'H2O': 2} and r2.prod == {'H2': 2, 'O2': 1}
True
>>> r3 = Reaction.from_string("A -> B; 1/second", 'A B')
>>> from chempy.units import to_unitless, default_units as u
>>> to_unitless(r3.param, u.hour**-1)
3600.0
has_precipitates(substances)[source]
html(substances, with_param=False)[source]

Returns a HTML representation of the reaction

Examples

>>> keys = 'H2O H+ OH-'.split()
>>> subst = {k: Substance.from_formula(k) for k in keys}
>>> r = Reaction.from_string("H2O -> H+ + OH-; 1e-4", subst)
>>> r.html(subst)
'H<sub>2</sub>O &rarr; H<sup>+</sup> + OH<sup>-</sup>'
>>> r2 = Reaction.from_string("H2O -> H+ + OH-; 1e-8/molar/second", subst)
>>> r2.html(subst, with_param=True)
'H<sub>2</sub>O &rarr; H<sup>+</sup> + OH<sup>-</sup>&#59; 1&sdot;10<sup>-8</sup> 1/(s*M)'
html_arrow = '&rarr;'
keys()[source]
latex(substances, with_param=False, magnitude_fmt=<function <lambda>>)[source]

Returns a LaTeX representation of the reaction

Parameters:

substances: dict

mapping substance keys to Substance instances

with_param: bool

whether to print the parameter (default: False)

magnitude_fmt: callback

how to format the number (default requires siunitx’s num)

Examples

>>> keys = 'H2O H+ OH-'.split()
>>> subst = {k: Substance.from_formula(k) for k in keys}
>>> r = Reaction.from_string("H2O -> H+ + OH-; 1e-4", subst)
>>> r.latex(subst) == r'H_{2}O \rightarrow H^{+} + OH^{-}'
True
>>> r2 = Reaction.from_string("H2O -> H+ + OH-; 1e-8/molar/second", subst)
>>> ref = r'H_{2}O \rightarrow H^{+} + OH^{-}; 1\cdot 10^{-8} $\mathrm{\frac{1}{(s{\cdot}M)}}$'
>>> r2.latex(subst, with_param=True) == ref
True
latex_arrow = '\\rightarrow'
mass_balance_violation(substances)[source]

Net amount of mass produced

Parameters:substances: dict
Returns:float: amount of net mass produced/consumed
net_stoich(substance_keys)[source]

Per substance net stoichiometry tuple (active & inactive)

non_precipitate_stoich(substances)[source]

Only stoichiometry of non-precipitates

order()[source]

Sum of (active) reactant stoichiometries

param_char = 'k'
precipitate_stoich(substances)[source]

Only stoichiometry of precipitates

rate(variables=None, backend=<module 'math' (built-in)>, substance_keys=None)[source]

Evaluate the rate of a reaction

Parameters:

variables: dict

backend: module, optional

substance_keys: iterable of str, optional

Examples

>>> rxn = Reaction.from_string('2 H2 + O2 -> 2 H2O; 3', None)
>>> r = 3*5*5*7
>>> rxn.rate({'H2': 5, 'O2': 7}) == {'H2': -2*r, 'O2': -r, 'H2O': 2*r}
True
rate_expr()[source]

Turns self.param into a RateExpr instance (if not already)

Examples

>>> r = Reaction.from_string('2 A + B -> 3 C; 7')
>>> ratex = r.rate_expr()
>>> ratex.args[0] == 7
True
str_arrow = '->'
string(substances=None, with_param=False, magnitude_fmt=<function <lambda>>)[source]

Returns a string representation of the reaction

Parameters:

substances: dict

mapping substance keys to Substance instances

with_param: bool

whether to print the parameter (default: False)

Examples

>>> r = Reaction({'H+': 1, 'Cl-': 1}, {'HCl': 1}, 1e10)
>>> r.string(with_param=False)
'Cl- + H+ -> HCl'
unicode(substances, with_param=False)[source]

Returns a unicode string representation of the reaction

Examples

>>> keys = 'H2O H+ OH-'.split()
>>> subst = {k: Substance.from_formula(k) for k in keys}
>>> r = Reaction.from_string("H2O -> H+ + OH-; 1e-4", subst)
>>> r.unicode(subst) == u'H₂O → H⁺ + OH⁻'
True
>>> r2 = Reaction.from_string("H2O -> H+ + OH-; 1e-8/molar/second", subst)
>>> r2.unicode(subst, with_param=True) == u'H₂O → H⁺ + OH⁻; 1·10⁻⁸ 1/(s·M)'
True
unicode_arrow = u'\u2192'
class chempy.chemistry.ReactionSystem(rxns, substances=None, name=None, checks=('balance', 'substance_keys', 'duplicate', 'duplicate_names'), substance_factory=<class 'chempy.chemistry.Substance'>)[source]

Bases: object

Collection of reactions forming a system (model).

Parameters:

rxns : sequence

sequence of Reaction instances

substances : OrderedDict or string or None

mapping str -> Substance instances, None => deduced from reactions.

name : string (optional)

Name of ReactionSystem (e.g. model name / citation key)

checks : iterable of str, optional

raises value error if any method check_%s returns False for all %s in checks.

substance_factory : callback

Raises:

ValueError

When any reaction occurs more than once

Examples

>>> from chempy import Reaction
>>> r1 = Reaction({'R1': 1}, {'P1': 1}, 42.0)
>>> rsys = ReactionSystem([r1], 'R1 P1')
>>> rsys.as_per_substance_array({'R1': 2, 'P1': 3})
array([ 2.,  3.])

Attributes

ns Number of substances
nr Number of reactions
rxns (list of objects) sequence of Reaction instances
substances (OrderedDict or string or iterable of strings/Substance) mapping substance name to substance index

Methods

all_prod_stoichs([keys])
all_reac_stoichs([keys])
as_per_substance_array(cont[, dtype, unit, ...]) Turns a dict into an ordered array
as_per_substance_dict(arr)
as_substance_index(substance_key) Returns the index of a Substance in the system
bimolecular_html_table([title]) Returns a HTML table of bimolecular reactions
check_balance([strict, throw]) Raies ValueError there are unbalanecd reactions in self.rxns
check_duplicate([throw]) Raies ValueError if there are duplicates in self.rxns
check_duplicate_names([throw])
check_substance_keys([throw])
composition_balance_vectors()
from_string(s, **kwargs) Create a reaction system from a string
net_stoichs([keys])
obeys_charge_neutrality() Returns False if any reaction violate charge neutrality.
obeys_mass_balance() Returns True if all reactions obeys mass balance, else False.
params() Returns list of per reaction param value
per_substance_varied(per_substance[, varied]) Dense nd-array for all combinations of varied levels per substance
rates([variables, backend, substance_keys]) Per substance sums of reaction rates rates.
stoichs([non_precip_rids]) Conditional stoichiometries depending on precipitation status
substance_names() Returns a tuple of the substances’ names
substance_participation(substance_key) Returns indices of reactions where substance_key occurs
unimolecular_html_table([title]) Returns a HTML table of unimolecular reactions
all_prod_stoichs(keys=None)[source]
all_reac_stoichs(keys=None)[source]
as_per_substance_array(cont, dtype='float64', unit=None, raise_on_unk=False)[source]

Turns a dict into an ordered array

Parameters:

cont : array_like or dict

dtype : str or numpy.dtype object

unit : unit, optional

raise_on_unk : bool

as_per_substance_dict(arr)[source]
as_substance_index(substance_key)[source]

Returns the index of a Substance in the system

bimolecular_html_table(title=True)[source]

Returns a HTML table of bimolecular reactions

Parameters:

title: bool

Returns:

string: html representation

list: reactions not considered

check_balance(strict=False, throw=False)[source]

Raies ValueError there are unbalanecd reactions in self.rxns

check_duplicate(throw=False)[source]

Raies ValueError if there are duplicates in self.rxns

check_duplicate_names(throw=False)[source]
check_substance_keys(throw=False)[source]
composition_balance_vectors()[source]
classmethod from_string(s, **kwargs)[source]

Create a reaction system from a string

Parameters:

s : str

multiline string

Examples

>>> rs = ReactionSystem.from_string('\n'.join(['2 HNO2 -> H2O + NO + NO2; 3', '2 NO2 -> N2O4; 4']))
>>> r1, r2 = 5*5*3, 7*7*4
>>> rs.rates({'HNO2': 5, 'NO2': 7}) == {'HNO2': -2*r1, 'H2O': r1, 'NO': r1, 'NO2': r1 - 2*r2, 'N2O4': r2}
True
net_stoichs(keys=None)[source]
nr

Number of reactions

ns

Number of substances

obeys_charge_neutrality()[source]

Returns False if any reaction violate charge neutrality.

obeys_mass_balance()[source]

Returns True if all reactions obeys mass balance, else False.

params()[source]

Returns list of per reaction param value

per_substance_varied(per_substance, varied=None)[source]

Dense nd-array for all combinations of varied levels per substance

Parameters:

per_substance: dict or array

varied: dict

Returns:

ndarray : with len(varied) + 1 number of axes, and with last axis length == self.ns

Examples

>>> rsys = ReactionSystem([], 'A B C')
>>> arr, keys = rsys.per_substance_varied({'A': 2, 'B': 3, 'C': 5}, {'C': [5, 7, 9, 11]})
>>> arr.shape, keys
((4, 3), ('C',))
>>> all(arr[1, :] == [2, 3, 7])
True
rates(variables=None, backend=<module 'math' (built-in)>, substance_keys=None)[source]

Per substance sums of reaction rates rates.

Parameters:

variables : dict

backend : module, optional

substance_keys : iterable of str, optional

Returns:

dict

per substance_key time derivatives of concentrations.

Examples

>>> r = Reaction({'R': 2}, {'P': 1}, 42.0)
>>> rsys = ReactionSystem([r])
>>> rates = rsys.rates({'R': 3, 'P': 5})
>>> abs(rates['P'] - 42*3**2) < 1e-14
True
stoichs(non_precip_rids=())[source]

Conditional stoichiometries depending on precipitation status

substance_names()[source]

Returns a tuple of the substances’ names

substance_participation(substance_key)[source]

Returns indices of reactions where substance_key occurs

Parameters:substance_key: str
Returns:List of indices for self.rxns where substance_key participates
unimolecular_html_table(title=True)[source]

Returns a HTML table of unimolecular reactions

Parameters:

title: bool

Returns:

string: html representation

list: reactions not considered

class chempy.chemistry.Solute(_self, *args, **kwargs)[source]

Bases: chempy.chemistry.Solute

Solute is deprecated since (not including) 0.3.0, it will be missing in 0.5.0. Use Species instead.

[DEPRECATED] Use .Species instead

Counter-intuitive to its name Solute has an additional property ‘precipitate’

Attributes

charge Convenience property for accessing composition[0]
mass Convenience property for accessing data['mass']
other_properties other_properties is deprecated, it will be missing in 0.5.0.

Methods

composition_keys(substance_iter) Occuring composition keys among a series of substances
from_formula(formula, **kwargs)
molar_mass([units]) Returns the molar mass (with units) of the substance
class chempy.chemistry.Species(*args, **kwargs)[source]

Bases: chempy.chemistry.Substance

Substance belonging to a phase

Species extends Substance with the new attribute phase_idx

Attributes

phase_idx: int Index of the phase (default is 0)

Methods

composition_keys(substance_iter) Occuring composition keys among a series of substances
from_formula(formula[, phases, ...]) Create a Species instance from its formula
molar_mass([units]) Returns the molar mass (with units) of the substance
classmethod from_formula(formula, phases=('(s)', '(l)', '(g)'), default_phase_idx=0, **kwargs)[source]

Create a Species instance from its formula

Analogous to Substance.from_formula() but with the addition that phase_idx is determined from the formula (and a mapping provided by phases)

Parameters:

formula: str

e.g. ‘H2O’, ‘NaCl(s)’, ‘CO2(aq)’, ‘CO2(g)’

phases: iterable of str or dict mapping str -> int

if not in **kwargs, phase_idx is determined from the suffix of formula where the suffixes is mapped from phases:

if phases is a dictionary:

phase_idx = phases[suffix]

else:

phase_idx = phases.index(suffix) + 1

and if suffixes is missing in phases phase_idx is taken to be 0

default_phase_idx: int or None (default: 0)

If default_phase_idx is None, ValueError is raised for

unkown suffixes.

Else default_phase_idx is used as phase_idx in those cases.

**kwargs:

Keyword arguments passed on.

Raises:

ValueError:

if default_phase_idx is None and no suffix found in phases

Examples

>>> water = Species.from_formula('H2O')
>>> water.phase_idx
0
>>> NaCl = Species.from_formula('NaCl(s)')
>>> NaCl.phase_idx
1
>>> Hg_l = Species.from_formula('Hg(l)')
>>> Hg_l.phase_idx
2
>>> CO2g = Species.from_formula('CO2(g)')
>>> CO2g.phase_idx
3
>>> CO2aq = Species.from_formula('CO2(aq)', default_phase_idx=None)
Traceback (most recent call last):
    ...
ValueError: Could not determine phase_idx
>>> CO2aq = Species.from_formula('CO2(aq)')
>>> CO2aq.phase_idx
0
>>> CO2aq = Species.from_formula('CO2(aq)', ['(aq)'],
...     default_phase_idx=None)
>>> CO2aq.phase_idx
1
>>> Species.from_formula('CO2(aq)', {'(aq)': 0}, None).phase_idx
0
precipitate

precipitate is deprecated since (not including) 0.3.0, it will be missing in 0.5.0.

deprecated attribute, provided for compatibility for now

class chempy.chemistry.Substance(name=None, charge=None, latex_name=None, unicode_name=None, html_name=None, composition=None, data=None, other_properties=None)[source]

Bases: object

Class representing a chemical substance

Parameters:

name : str

charge : int (optional, default: None)

will be stored in composition[0], prefer composition when possible

latex_name : str

unicode_name : str

html_name : str

composition : dict or None (default)

dict (int -> number) e.g. {atomic number: count}, zero has special meaning (net charge)

data : dict

free form dictionary. Could be simple such as {'mp': 0, 'bp': 100} or considerably more involved, e.g.: {'diffusion_coefficient': { 'water': lambda T: 2.1*m**2/s/K*(T - 273.15*K)}}

Examples

>>> ammonium = Substance('NH4+', 1, 'NH_4^+', composition={7: 1, 1: 4},
...     data={'mass': 18.0385, 'pKa': 9.24})
>>> ammonium.name
'NH4+'
>>> ammonium.composition  # note that charge was inserted as composition[0]
{0: 1, 1: 4, 7: 1}
>>> ammonium.data['mass']
18.0385
>>> ammonium.data['pKa']
9.24
>>> ammonium.mass  # mass is a special case (also attribute)
18.0385
>>> ammonium.pKa
Traceback (most recent call last):
    ...
AttributeError: 'Substance' object has no attribute 'pKa'
>>> nh4p = Substance.from_formula('NH4+')  # simpler
>>> nh4p.composition == {7: 1, 1: 4, 0: 1}
True
>>> nh4p.latex_name
'NH_{4}^{+}'

Attributes

mass Convenience property for accessing data['mass']
other_properties other_properties is deprecated, it will be missing in 0.5.0.
attrs a tuple of attribute names for serialization
data free form dict

Methods

composition_keys(substance_iter) Occuring composition keys among a series of substances
from_formula(formula, **kwargs) Creates a Substance instance from its formula
molar_mass([units]) Returns the molar mass (with units) of the substance
attrs = ('name', 'latex_name', 'unicode_name', 'html_name', 'composition', 'data')
charge

Convenience property for accessing composition[0]

static composition_keys(substance_iter)[source]

Occuring composition keys among a series of substances

classmethod from_formula(formula, **kwargs)[source]

Creates a Substance instance from its formula

Parameters:

formula: str

e.g. ‘Na+’, ‘H2O’, ‘Fe(CN)6-4’

**kwargs:

keyword arguments passed on to .Substance

Examples

>>> NH3 = Substance.from_formula('NH3')
>>> NH3.composition == {1: 3, 7: 1}
True
>>> '%.2f' % NH3.mass
'17.03'
>>> NH3.charge
0
>>> NH3.latex_name
'NH_{3}'
mass

Convenience property for accessing data['mass']

when data['mass'] is missing the mass is calculated from the composition using chempy.util.parsing.mass_from_composition().

molar_mass(units=None)[source]

Returns the molar mass (with units) of the substance

Examples

>>> nh4p = Substance.from_formula('NH4+')  # simpler
>>> from chempy.units import default_units as u
>>> nh4p.molar_mass(u)
array(18.0384511) * g/mol
other_properties

other_properties is deprecated, it will be missing in 0.5.0.

chempy.chemistry.balance_stoichiometry(reactants, products, substances=None, substance_factory=<bound method type.from_formula of <class 'chempy.chemistry.Substance'>>)[source]

Balances stoichiometric coefficients of a reaction

Parameters:

reactants: iterable of reactant keys

products: iterable of product keys

substances: OrderedDict or string or None

mapping reactant/product keys to instances of Substance

substance_factory: callback

Returns:

balanced reactants : dict

balanced products : dict

Examples

>>> ref = {'C2H2': 2, 'O2': 3}, {'CO': 4, 'H2O': 2}
>>> balance_stoichiometry({'C2H2', 'O2'}, {'CO', 'H2O'}) == ref
True
>>> ref2 = {'H2': 1, 'O2': 1}, {'H2O2': 1}
>>> balance_stoichiometry('H2 O2'.split(), ['H2O2'], 'H2 O2 H2O2') == ref2
True
chempy.chemistry.equilibrium_quotient(concs, stoich)[source]

Calculates the equilibrium quotient of an equilbrium

Parameters:

concs: array_like

per substance concentration

stoich: iterable of integers

per substance stoichiometric coefficient

Examples

>>> '%.12g' % equilibrium_quotient([1.0, 1e-7, 1e-7], [-1, 1, 1])
'1e-14'
chempy.chemistry.mass_fractions(stoichiometries, substances=None, substance_factory=<bound method type.from_formula of <class 'chempy.chemistry.Substance'>>)[source]

Calculates weight fractions of each substance in a stoichiometric dict

Parameters:

stoichiometries: dict or set

if a set: all entries are assumed to correspond to unit multiplicity

substances: dict or None

Examples

>>> r = mass_fractions({'H2': 1, 'O2': 1})
>>> mH2, mO2 = 1.008*2, 15.999*2
>>> abs(r['H2'] - mH2/(mH2+mO2)) < 1e-4
True
>>> abs(r['O2'] - mO2/(mH2+mO2)) < 1e-4
True
>>> mass_fractions({'H2O2'}) == {'H2O2': 1.0}
True

chempy.debye_huckel module

chempy.einstein_smoluchowski module

chempy.einstein_smoluchowski.electrical_mobility_from_D(D, charge, T, constants=None, units=None)[source]

Calculates the electrical mobility through Einstein-Smoluchowski relation.

Parameters:

D: float with unit

Diffusion coefficient

charge: integer

charge of the species

T: float with unit

Absolute temperature

constants: object (optional, default: None)

if None:

T assumed to be in Kelvin and b0 = 1 mol/kg

else:

see source code for what attributes are used. Tip: pass quantities.constants

units: object (optional, default: None)

attributes accessed: meter, Kelvin and mol

Returns:

Electrical mobility

chempy.electrolytes module

This modules collects expressions related to ionic strenght, e.g. the Debye-Hückel expressions.

chempy.electrolytes.A(eps_r, T, rho, b0=1, constants=None, units=None, backend=None)[source]

Debye Huckel constant A

Parameters:

eps_r: float

relative permittivity

T: float with unit

Temperature (default: assume Kelvin)

rho: float with unit

density (default: assume kg/m**3)

b0: float, optional

Reference molality, optionally with unit (amount / mass) IUPAC defines it as 1 mol/kg. (default: 1).

units: object (optional, default: None)

attributes accessed: meter, Kelvin and mol

constants: object (optional, default: None)

if None:

T assumed to be in Kelvin and b0 = 1 mol/kg

else:

see source code for what attributes are used. Tip: pass quantities.constants

Notes

Remember to divide by ln(10) if you want to use the constant with log10 based expression.

References

Atkins, De Paula, Physical Chemistry, 8th edition

chempy.electrolytes.B(eps_r, T, rho, b0=1, constants=None, units=None, backend=None)[source]

Extended Debye-Huckel parameter B

Parameters:

eps_r: float

relative permittivity

T: float with unit

temperature

rho: float with unit

density

b0: float with unit

reference molality

units: object (optional, default: None)

attributes accessed: meter, Kelvin and mol

constants: object (optional, default: None)

if None:

T assumed to be in Kelvin, rho in kg/m**3 and b0 = 1 mol/kg

else:

attributes accessed: molar_gas_constant, Faraday_constant Tip: pass quantities.constants

Returns:

Debye Huckel B constant (default in m**-1)

class chempy.electrolytes.ExtendedDebyeHuckelActivityProduct(stoich, *args)[source]

Bases: chempy.electrolytes._ActivityProductBase

Methods

__call__(c)
class chempy.electrolytes.LimitingDebyeHuckelActivityProduct(stoich, *args)[source]

Bases: chempy.electrolytes._ActivityProductBase

Methods

__call__(c)
chempy.electrolytes.davies_activity_product(I, stoich, z, a, T, eps_r, rho, C=-0.3, backend=None)[source]
chempy.electrolytes.davies_log_gamma(I, z, A, C=-0.3, I0=1, backend=None)[source]

Davies formula

chempy.electrolytes.extended_activity_product(I, stoich, z, a, T, eps_r, rho, C=0, backend=None)[source]
chempy.electrolytes.extended_log_gamma(I, z, a, A, B, C=0, I0=1, backend=None)[source]

Debye-Huckel extended formula

chempy.electrolytes.ionic_strength(molalities, charges=None, b0=1, units=None, substances=None, substance_factory=<bound method type.from_formula of <class 'chempy.chemistry.Substance'>>)[source]

Calculates the ionic strength

Parameters:

molalities: array_like or dict

Optionally with unit (amount / mass). when dict: mapping substance key to molality.

charges: array_like

Charge of respective ion, taken for substances when None.

units: object (optional, default: None)

Attributes accessed: molal.

substances: dict, optional

Mapping of substance keys to Substance instances (used when molalities is a dict).

substance_factory: callback

Used if substances is a string.

Examples

>>> ionic_strength([1e-3, 3e-3], [3, -1]) == .5 * (9 + 3) * 1e-3
True
>>> ionic_strength({'Mg+2': 6, 'PO4-3': 4})
30.0
chempy.electrolytes.limiting_activity_product(I, stoich, z, T, eps_r, rho, backend=None)[source]

Product of activity coefficients based on DH limiting law.

chempy.electrolytes.limiting_log_gamma(I, z, A, I0=1, backend=None)[source]

Debye-Hyckel limiting formula

chempy.equilibria module

Module collecting classes and functions for dealing with (multiphase) chemical equilibria.

Note

This module is provisional at the moment, i.e. the API is not stable and may break without a deprecation cycle.

class chempy.equilibria.EqSystem(rxns, substances=None, name=None, checks=('balance', 'substance_keys', 'duplicate', 'duplicate_names'), substance_factory=<class 'chempy.chemistry.Substance'>)[source]

Bases: chempy.chemistry.ReactionSystem

Attributes

nr Number of reactions
ns Number of substances
precipitate_rxn_idxs precipitate_rxn_idxs is deprecated since (not including) 0.3.1, it will be missing in 0.5.0. Use phase_transfer_reaction_idxs instead.
precipitate_substance_idxs precipitate_substance_idxs is deprecated since (not including) 0.3.1, it will be missing in 0.5.0. Use other_phase_species_idxs instead.

Methods

composition_conservation(concs, init_concs)
dissolved(concs) Return dissolved concentrations
eq_constants([non_precip_rids, eq_params, small])
equilibrium_quotients(concs)
get_neqsys(neqsys_type, init_concs[, NumSys])
get_neqsys_chained_conditional(init_concs[, ...])
get_neqsys_conditional_chained(init_concs[, ...])
get_neqsys_static_conditions(init_concs[, ...])
non_precip_rids(precipitates)
other_phase_species_idxs([phase_idx])
phase_transfer_reaction_idxs([phase_idx])
plot_errors(concs, init_concs, varied_data, ...)
root(init_concs[, x0, neqsys, NumSys, ...])
roots(init_concs, varied_data, varied[, x0, ...])
Parameters:
solve(init_concs[, varied])
stoichs_constants(eq_params[, rref, Matrix, ...])
substance_labels([latex])
upper_conc_bounds(init_concs[, min_, dtype])
composition_conservation(concs, init_concs)[source]
dissolved(concs)[source]

Return dissolved concentrations

eq_constants(non_precip_rids=(), eq_params=None, small=0)[source]
equilibrium_quotients(concs)[source]
get_neqsys(neqsys_type, init_concs, NumSys=<class 'chempy._eqsys.NumSysLin'>, **kwargs)[source]
get_neqsys_chained_conditional(init_concs, rref_equil=False, rref_preserv=False, NumSys=<class 'chempy._eqsys.NumSysLin'>)[source]
get_neqsys_conditional_chained(init_concs, rref_equil=False, rref_preserv=False, NumSys=<class 'chempy._eqsys.NumSysLin'>)[source]
get_neqsys_static_conditions(init_concs, rref_equil=False, rref_preserv=False, NumSys=<class 'chempy._eqsys.NumSysLin'>, precipitates=None)[source]
non_precip_rids(precipitates)[source]
other_phase_species_idxs(phase_idx=0)[source]
phase_transfer_reaction_idxs(phase_idx=0)[source]
plot_errors(concs, init_concs, varied_data, varied, axes=None, compositions=True, Q=True, subplot_kwargs=None)[source]
precipitate_rxn_idxs

precipitate_rxn_idxs is deprecated since (not including) 0.3.1, it will be missing in 0.5.0. Use phase_transfer_reaction_idxs instead.

precipitate_substance_idxs

precipitate_substance_idxs is deprecated since (not including) 0.3.1, it will be missing in 0.5.0. Use other_phase_species_idxs instead.

root(init_concs, x0=None, neqsys=None, NumSys=<class 'chempy._eqsys.NumSysLog'>, neqsys_type='chained_conditional', **kwargs)[source]
roots(init_concs, varied_data, varied, x0=None, NumSys=<class 'chempy._eqsys.NumSysLog'>, plot_kwargs=None, neqsys_type='chained_conditional', **kwargs)[source]
Parameters:

init_concs : array or dict

varied_data : array

varied_idx : int or str

x0 : array

NumSys : _NumSys subclass

See NumSysLin, NumSysLog, etc.

plot_kwargs : dict

See py:meth:pyneqsys.NeqSys.solve. Two additional keys are intercepted here:

latex_names: bool (default: False) conc_unit_str: str (default: ‘M’)

neqsys_type : str

what method to use for NeqSys construction (get_neqsys_*)

**kwargs :

kwargs passed on to py:meth:pyneqsys.NeqSys.solve_series

solve(init_concs, varied=None, **kwargs)[source]
stoichs_constants(eq_params, rref=False, Matrix=None, backend=None, non_precip_rids=())[source]
substance_labels(latex=False)[source]
upper_conc_bounds(init_concs, min_=<built-in function min>, dtype=<type 'numpy.float64'>)[source]

chempy.eyring module

chempy.henry module

Module for dealing with constants Henry’s law.

class chempy.henry.Henry[source]

Bases: chempy.util.pyutil.Henry

Henry’s gas constant

Note that the reference temperature is set by the attribute T0 which defaults to 298.15 (Kelvin).

Parameters:

kH0: float

Henry’s constant [M/atm]

derivative: float

dln(kH)/d(1/T) [K] Equivalent to Delta_soln H / R

ref: object

Reference for origin of parameters

units: object (optional)

object with attributes: kelvin

Examples

>>> H_H2 = Henry(1.2e-3, 1800, ref='carpenter_1966')
>>> '%.2g' % H_H2(298.15)
'0.0012'

Attributes

Hcp Alias for field number 0
T0 Alias for field number 2
Tderiv Alias for field number 1
ref Alias for field number 3

Methods

__call__(T[, units, backend]) Evaluates Henry’s constant for provided temperature
count(...)
get_P_at_T_and_c(T, c, **kwargs) Convenience method for calculating concentration
get_c_at_T_and_P(T, P, **kwargs) Convenience method for calculating concentration
get_kH_at_T(*args, **kwargs) get_kH_at_T is deprecated since (not including) 0.3.1, it will be missing in 0.5.0. Use __call__ instead.
index((value, [start, ...) Raises ValueError if the value is not present.
get_P_at_T_and_c(T, c, **kwargs)[source]

Convenience method for calculating concentration

Calculate the partial pressure for given temperature and concentration

Parameters:

T: float

Temperature

P: float

Pressure

**kwargs:

Keyword arguments passed on to __call__()

get_c_at_T_and_P(T, P, **kwargs)[source]

Convenience method for calculating concentration

Calculate what concentration is needed to achieve a given partial pressure at a specified temperature

Parameters:

T: float

Temperature

P: float

Pressure

**kwargs:

Keyword arguments passed on to __call__()

get_kH_at_T(*args, **kwargs)[source]

get_kH_at_T is deprecated since (not including) 0.3.1, it will be missing in 0.5.0. Use __call__ instead.

class chempy.henry.HenryWithUnits[source]

Bases: chempy.henry.Henry

Analogous to Henry

Examples

>>> from chempy.units import to_unitless, default_units as u
>>> H_CO = HenryWithUnits(9.7e-6 * u.mol/u.m**3/u.Pa, 1300*u.K, ref='sander_2015')
>>> '%.2g' % to_unitless(H_CO(298.15 * u.K), u.molar/u.bar)
'0.00097'

Attributes

Hcp Alias for field number 0
T0 Alias for field number 2
Tderiv Alias for field number 1
ref Alias for field number 3

Methods

__call__(T[, units, backend]) Evaluates Henry’s constant for provided temperature
count(...)
get_P_at_T_and_c(T, c, **kwargs) Convenience method for calculating concentration
get_c_at_T_and_P(T, P, **kwargs) Convenience method for calculating concentration
get_kH_at_T(*args, **kwargs) get_kH_at_T is deprecated since (not including) 0.3.1, it will be missing in 0.5.0. Use __call__ instead.
index((value, [start, ...) Raises ValueError if the value is not present.
chempy.henry.Henry_H_at_T(T, H, Tderiv, T0=None, units=None, backend=None)[source]

Evaluate Henry’s constant H at temperature T

Parameters:

T: float

Temperature (with units), assumed to be in Kelvin if units == None

H: float

Henry’s constant

Tderiv: float (optional)

dln(H)/d(1/T), assumed to be in Kelvin if units == None. default: 298.15 K

T0: float

Reference temperature, assumed to be in Kelvin if units == None

units: object (optional)

object with attributes: kelvin (e.g. chempy.units.default_units)

backend : module (optional)

module with “exp”, default: numpy, math

chempy.printing module

class chempy.printing.Table(rows, headers=None)[source]

Bases: object

Methods

html()
html()[source]
chempy.printing.as_per_substance_html_table(cont, substances, header='Concentration')[source]

chempy.symbolic module

chempy.symbolic.get_constant_symbols(Symbol=None)[source]

chempy.units module

The units module provides the following attributes:

  • chempy.units.default_units
  • chempy.units.default_constants
  • chempy.units.SI_base_registry

together with some functions.

Currently quantities is used as the underlying package to handle units. If it is possible you should try to only use the chempy.units module (in case ChemPy changes this backend), and avoid relying on any attributes of the Quantity instances (and rather use functions in chempy.units).

class chempy.units.Backend(underlying_backend=('numpy', 'math'))[source]

Bases: object

Wrapper around modules such as numpy and math

Instances of Backend wraps a module, e.g. numpy and ensures that arguments passed on are unitless, i.e. it raises an error if a transcendental function is used with quantities with units.

Parameters:

underlying_backend : module, str or tuple of str

e.g. ‘numpy’ or (‘sympy’, ‘math’)

Examples

>>> import math
>>> km, m = default_units.kilometre, default_units.metre
>>> math.exp(3*km) == math.exp(3*m)
True
>>> be = Backend('math')
>>> be.exp(3*km)
Traceback (most recent call last):
    ...
ValueError: Unable to convert between units of "km" and "dimensionless"
>>> import numpy as np
>>> np.sum([1000*pq.metre/pq.kilometre, 1])
1001.0
>>> be_np = Backend(np)
>>> be_np.sum([[1000*pq.metre/pq.kilometre, 1], [3, 4]], axis=1)
array([ 2.,  7.])
chempy.units.allclose(a, b, rtol=1e-08, atol=None)[source]

Analogous to numpy.allclose.

chempy.units.default_unit_in_registry(value, registry)[source]
chempy.units.format_string(value, precision='%.5g', tex=False)[source]

Formats a scalar with unit as two strings

Parameters:

value: float with unit

precision: str

tex: bool

LaTeX formatted or not? (no ‘$’ signs)

Examples

>>> print(' '.join(format_string(0.42*default_units.mol/default_units.decimetre**3)))
0.42 mol/decimetre**3
>>> print(' '.join(format_string(2/default_units.s, tex=True)))
2 \mathrm{\frac{1}{s}}
chempy.units.get_derived_unit(registry, key)[source]

Get the unit of a physcial quantity in a provided unit system.

Parameters:

registry: dict (str: unit)

mapping ‘length’, ‘mass’, ‘time’, ‘current’, ‘temperature’, ‘luminous_intensity’, ‘amount’. If registry is None the function returns 1.0 unconditionally.

key: str

one of the registry keys or one of: ‘diffusion’, ‘electrical_mobility’, ‘permittivity’, ‘charge’, ‘energy’, ‘concentration’, ‘density’, ‘radiolytic_yield’

Examples

>>> m, s = default_units.meter, default_units.second
>>> get_derived_unit(SI_base_registry, 'diffusion') == m**2/s
True
chempy.units.get_physical_quantity(value)[source]
chempy.units.is_unitless(expr)[source]

Returns True if expr is unitless, otherwise False

Examples

>>> is_unitless(42)
True
>>> is_unitless(42*default_units.kilogram)
False
chempy.units.latex_of_unit(quant)[source]

Returns LaTeX reperesentation of the unit of a quantity

Examples

>>> print(latex_of_unit(1/default_units.kelvin))
\mathrm{\frac{1}{K}}
chempy.units.linspace(start, stop, num=50)[source]

Analogous to numpy.linspace.

Examples

>>> abs(linspace(2, 8, num=3)[1] - 5) < 1e-15
True
chempy.units.logspace_from_lin(start, stop, num=50)[source]

Logarithmically spaced data points

Examples

>>> abs(logspace_from_lin(2, 8, num=3)[1] - 4) < 1e-15
True
chempy.units.magnitude(value)[source]
chempy.units.to_unitless(value, new_unit=None)[source]

Nondimensionalization of a quantity.

Parameters:

value: quantity

new_unit: unit

Examples

>>> '%.1g' % to_unitless(1*default_units.metre, default_units.nm)
'1e+09'
chempy.units.unit_of(expr, simplified=False)[source]

Returns the unit of a quantity

Examples

>>> unit_of(42*pq.second) == unit_of(12*pq.second)
True
>>> unit_of(42)
1
chempy.units.unit_registry_from_human_readable(unit_registry)[source]

Deserialization of unit_registry.

chempy.units.unit_registry_to_human_readable(unit_registry)[source]

Serialization of a unit registry.

chempy.units.unitless_in_registry(value, registry)[source]