Source code for exatomic.formula
# -*- coding: utf-8 -*-
# Copyright (c) 2015-2022, Exa Analytics Development Team
# Distributed under the terms of the Apache License 2.0
"""
Simple Formula
##################
"""
import numpy as np
import pandas as pd
from .core.error import StringFormulaError
from exatomic.base import isotopes, sym2mass
[docs]class SimpleFormula(pd.Series):
"""
A simple way of storing a chemical formula that contains no structural
information. Element symbols are in alphabetical order (e.g. 'B', 'C', 'Cl', 'Uuo')
>>> water = SimpleFormula('H(2)O(1)')
>>> naoh = SimpleFormula('Na(1)O(1)H(1)')
>>> naoh
SimpleFormula('H(1)Na(1)O(1)')
"""
@property
def mass(self):
"""
Returns:
mass (float): Mass (in atomic units) of the associated formula
"""
df = self.to_frame()
df['mass'] = df.index.map(sym2mass)
return (df['mass'] * df['count']).sum()
[docs] def as_string(self):
"""
Returns:
formula (str): String representation of the chemical formula.
"""
return ''.join(('{0}({1})'.format(key.title(), self[key]) for key in sorted(self.index)))
def __init__(self, data):
if isinstance(data, str):
data = string_to_dict(data)
super().__init__(data=data, dtype=np.int64, name='count')
self.index.names = ['symbol']
def __repr__(self):
return "{}('{}')".format(self.__class__.__name__, self.as_string())
def __str__(self):
return self.__repr__()
[docs]def string_to_dict(formula):
"""
Convert string formula to a dictionary.
Args:
formula (str): String formula representation
Returns:
fdict (dict): Dictionary formula representation
"""
obj = []
if ')' not in formula and len(formula) <= 3 and all((not char.isdigit() for char in formula)):
return {formula: 1}
elif ')' not in formula:
raise StringFormulaError(formula)
for s in formula.split(')'):
if s != '':
symbol, count = s.split('(')
obj.append((symbol, np.int64(count)))
return dict(obj)
[docs]def dict_to_string(formula):
"""
Convert a dictionary formula to a string.
Args:
formula (dict): Dictionary formula representation
Returns:
fstr (str): String formula representation
"""
return ''.join(('{0}({1})'.format(key.title(), formula[key]) for key in sorted(formula.keys()) if formula[key] > 0))