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]element_re = re.compile("([A-Z][a-z]?)([0-9.]+[0-9.]?|(?=[A-Z])?)")
[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
}