Source code for cobra.core.formula
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import re
from warnings import warn
from cobra.core.object import Object
# Numbers are not required because of the |(?=[A-Z])? block. See the
# discussion in https://github.com/opencobra/cobrapy/issues/128 for
# more details.
[docs]class Formula(Object):
"""Describes a Chemical Formula
Parameters
---------
formula : string
A legal formula string contains only letters and numbers.
"""
def __init__(self, formula=None):
Object.__init__(self, formula)
self.formula = formula
self.elements = {}
if self.formula is not None:
self.parse_composition()
[docs] def __add__(self, other_formula):
"""Combine two molecular formulas.
Parameters
----------
other_formula : Formula, str
string for a chemical formula
Returns
-------
Formula
The combined formula
"""
return Formula(self.formula + other_formula.formula)
[docs] def parse_composition(self):
"""Breaks the chemical formula down by element."""
tmp_formula = self.formula
# commonly occuring characters in incorrectly constructed formulas
if "*" in tmp_formula:
warn("invalid character '*' found in formula '%s'" % self.formula)
tmp_formula = self.formula.replace("*", "")
if "(" in tmp_formula or ")" in tmp_formula:
warn("parenthesis found in formula '%s'" % self.formula)
return
composition = {}
parsed = element_re.findall(tmp_formula)
for (element, count) in parsed:
if count == "":
count = 1
else:
try:
count = float(count)
int_count = int(count)
if count == int_count:
count = int_count
else:
warn(
"%s is not an integer (in formula %s)"
% (count, self.formula)
)
except ValueError:
warn("failed to parse %s (in formula %s)" % (count, self.formula))
self.elements = {}
return
if element in composition:
composition[element] += count
else:
composition[element] = count
self.elements = composition
@property
[docs] def weight(self):
"""Calculate the mol mass of the compound
Returns
-------
float
the mol mass
"""
try:
return sum(
[
count * elements_and_molecular_weights[element]
for element, count in self.elements.items()
]
)
except KeyError as e:
warn("The element %s does not appear in the periodic table" % e)
[docs]elements_and_molecular_weights = {
"H": 1.007940,
"He": 4.002602,
"Li": 6.941000,
"Be": 9.012182,
"B": 10.811000,
"C": 12.010700,
"N": 14.006700,
"O": 15.999400,
"F": 18.998403,
"Ne": 20.179700,
"Na": 22.989770,
"Mg": 24.305000,
"Al": 26.981538,
"Si": 28.085500,
"P": 30.973761,
"S": 32.065000,
"Cl": 35.453000,
"Ar": 39.948000,
"K": 39.098300,
"Ca": 40.078000,
"Sc": 44.955910,
"Ti": 47.867000,
"V": 50.941500,
"Cr": 51.996100,
"Mn": 54.938049,
"Fe": 55.845000,
"Co": 58.933200,
"Ni": 58.693400,
"Cu": 63.546000,
"Zn": 65.409000,
"Ga": 69.723000,
"Ge": 72.640000,
"As": 74.921600,
"Se": 78.960000,
"Br": 79.904000,
"Kr": 83.798000,
"Rb": 85.467800,
"Sr": 87.620000,
"Y": 88.905850,
"Zr": 91.224000,
"Nb": 92.906380,
"Mo": 95.940000,
"Tc": 98.000000,
"Ru": 101.070000,
"Rh": 102.905500,
"Pd": 106.420000,
"Ag": 107.868200,
"Cd": 112.411000,
"In": 114.818000,
"Sn": 118.710000,
"Sb": 121.760000,
"Te": 127.600000,
"I": 126.904470,
"Xe": 131.293000,
"Cs": 132.905450,
"Ba": 137.327000,
"La": 138.905500,
"Ce": 140.116000,
"Pr": 140.907650,
"Nd": 144.240000,
"Pm": 145.000000,
"Sm": 150.360000,
"Eu": 151.964000,
"Gd": 157.250000,
"Tb": 158.925340,
"Dy": 162.500000,
"Ho": 164.930320,
"Er": 167.259000,
"Tm": 168.934210,
"Yb": 173.040000,
"Lu": 174.967000,
"Hf": 178.490000,
"Ta": 180.947900,
"W": 183.840000,
"Re": 186.207000,
"Os": 190.230000,
"Ir": 192.217000,
"Pt": 195.078000,
"Au": 196.966550,
"Hg": 200.590000,
"Tl": 204.383300,
"Pb": 207.200000,
"Bi": 208.980380,
"Po": 209.000000,
"At": 210.000000,
"Rn": 222.000000,
"Fr": 223.000000,
"Ra": 226.000000,
"Ac": 227.000000,
"Th": 232.038100,
"Pa": 231.035880,
"U": 238.028910,
"Np": 237.000000,
"Pu": 244.000000,
"Am": 243.000000,
"Cm": 247.000000,
"Bk": 247.000000,
"Cf": 251.000000,
"Es": 252.000000,
"Fm": 257.000000,
"Md": 258.000000,
"No": 259.000000,
"Lr": 262.000000,
"Rf": 261.000000,
"Db": 262.000000,
"Sg": 266.000000,
"Bh": 264.000000,
"Hs": 277.000000,
"Mt": 268.000000,
"Ds": 281.000000,
"Rg": 272.000000,
"Cn": 285.000000,
"Uuq": 289.000000,
"Uuh": 292.000000,
}