chemsynthcalc package¶
Submodules¶
chemsynthcalc.chem_errors module¶
Module that contains custom errors for use in ChemSynthCalc
- exception chemsynthcalc.chem_errors.NoSuchAtom¶
Bases:
Exception
Found atom(s) that are not in the periodic table.
- exception chemsynthcalc.chem_errors.InvalidCharacter¶
Bases:
Exception
Found some characters that do not belong in the chemical formula or reaction.
- exception chemsynthcalc.chem_errors.MoreThanOneAdduct¶
Bases:
Exception
There is more than one adduct (*).
- exception chemsynthcalc.chem_errors.BracketsNotPaired¶
Bases:
Exception
Some brackets do not come in pairs.
- exception chemsynthcalc.chem_errors.NoSuchMode¶
Bases:
Exception
Invalid calculation mode detected.
- exception chemsynthcalc.chem_errors.NoSuchAlgorithm¶
Bases:
Exception
Invalid calculation algorithm detected.
- exception chemsynthcalc.chem_errors.NoSeparator¶
Bases:
Exception
No separator was found in the reaction string.
- exception chemsynthcalc.chem_errors.ReactionNotBalanced¶
Bases:
Exception
This reaction is not balanced.
- exception chemsynthcalc.chem_errors.ReactantProductDifference¶
Bases:
Exception
The elements in reaction are not evenly distributed in reactants and products: some of atoms are only in one part of reaction.
- exception chemsynthcalc.chem_errors.BadCoeffiecients¶
Bases:
Exception
The coefficients are not not compliant (they have no physical meaning).
chemsynthcalc.chem_output module¶
- class chemsynthcalc.chem_output.FormulaOutput(chemical_formula_output: dict)¶
Bases:
object
Outputs for
chemsynthcalc.chemical_formula.ChemicalFormula
A collection of methods for outputing results of
chemsynthcalc.chemical_formula.ChemicalFormula
. Default filenames of output files are "CSC_formula" with formula and nanosecond since the epoch.- Parameters
chemical_formula_output (dict) -- output of
chemsynthcalc.chemical_formula.ChemicalFormula
- print_results(print_rounding_order: int) None ¶
Print results in the terminal.
- Parameters
print_rounding_order (int) -- print precision
- Returns
None
- export_to_txt(filename: str, print_rounding_order: int) None ¶
Prints results into the txt file and saves them.
- Parameters
filename (str) -- filename string (should end with .txt)
print_rounding_order (int) -- print precision
- Returns
None
- dump_to_json(print_rounding_order: int) str ¶
JSON serialization.
- Parameters
print_rounding_order (int) -- print precision
- Returns
A JSON-type object of results output.
- Return type
str
- export_to_json(filename: str, print_rounding_order: int) None ¶
Dump the output dict into an JSON file.
- Parameters
filename (str) -- filename string (should end with .json)
print_rounding_order (int) -- print precision
- Returns
None
- class chemsynthcalc.chem_output.ReactionOutput(chemical_reaction_output: dict)¶
Bases:
object
Outputs for
chemsynthcalc.chemical_reaction.ChemicalReaction
A collection of methods to output the results of
chemsynthcalc.chemical_reaction.ChemicalReaction
.The default filenames of the output files are "CSC_reaction" with target compound and nanoseconds since the epoch.- Parameters
chemical_formula_output (dict) -- output of
chemsynthcalc.chemical_reaction.ChemicalReaction
- print_results(print_rounding_order: int) None ¶
Print results in the terminal.
- Parameters
print_rounding_order (int) -- print precision
- Returns
None
- export_to_txt(filename: str, print_rounding_order: int) None ¶
Prints results into the txt file and saves it.
- Parameters
filename (str) -- filename string (should end with .txt)
print_rounding_order (int) -- print precision
- Returns
None
- dump_to_json(print_rounding_order: int) str ¶
JSON serialization.
- Parameters
print_rounding_order (int) -- print precision
- Returns
A JSON-type object of results output.
- Return type
str
- export_to_json(filename: str, print_rounding_order: int) None ¶
Dump output dict into JSON flie.
- Parameters
filename (str) -- filename string (should end with .json)
print_rounding_order (int) -- print precision
- Returns
None
chemsynthcalc.chemical_formula module¶
- class chemsynthcalc.chemical_formula.ChemicalFormula(formula: str = '', rounding_order: int = 8)¶
Bases:
object
A base class for representing a single chemical formula.
It constructs with a formula string and calculates properties: parsed formula, molar mass, mass percent, atomic percent, oxide percent from this string using
chemsynthcalc.formula_parser.ChemicalFormulaParser
andchemsynthcalc.molar_mass.MolarMassCalculation
.- Parameters
formula (srt) -- string of chemical formula
rounding_order (int) -- value of rounding precision (8 by default)
- Raises
ValueError -- if the input string is empty
ValueError -- if rounding order <= 0
Examples
>>> ChemicalFormula("H2O") H2O >>> ChemicalFormula("H2O").molar_mass 18.015 >>> ChemicalFormula("H2O").mass_percent {'H': 11.19067444, 'O': 88.80932556}
- property parsed_formula: dict¶
Formula parsed into dict.
- Returns
Parsed dictionary representation of formula string created by
chemsynthcalc.formula_parser.ChemicalFormulaParser
.- Return type
dict
Example
>>> ChemicalFormula("K2SO4").parsed_formula {'K': 2.0, 'S': 1.0, 'O': 4.0}
- property molar_mass: float¶
Molar mass of formula.
- Returns
The molar mass of the formula (in g/mol), calculated from parsed the formula using
chemsynthcalc.molar_mass.MolarMassCalculation
.- Return type
float
Example
>>> ChemicalFormula("K2SO4").molar_mass 174.252
- property mass_percent: dict¶
The percentage of mass of atoms in the formula.
- Returns
A mass percent or relative mass fraction of atoms in parsed chemical formula. The values of mass content are in % (with 100% sum), not fraction.
- Return type
dict
Example
>>> ChemicalFormula("K2SO4").mass_percent {'K': 44.87523816, 'S': 18.39864105, 'O': 36.72612079}
- property atomic_percent: dict¶
Atomic percents of atoms in the formula.
- Returns
An atomic percent or relative mole fraction dictionary of atoms in a parsed chemical formula. The values of mole content are in % (with 100% sum), not fraction.
- Return type
dict
Example
>>> ChemicalFormula("K2SO4").atomic_percent {'K': 28.57142857, 'S': 14.28571429, 'O': 57.14285714}
- property oxide_percent: dict¶
Oxide percents of metals in formula.
- Returns
An oxide percent or oxide fraction dictionary of atoms in parsed chemical formula. Oxide types are listed in the
chemsynthcalc.periodic_table
file and can be changed to any oxide formula. The values of oxide content are in % (with 100% sum), not fraction.- Return type
dict
Example
>>> ChemicalFormula("K2SO4").oxide_percent {'K2O': 54.05676836, 'SO3': 45.94323164}
- property output_results: dict¶
Dictionary of the calculation result output for class.
- Returns
Output dictionary for all properties listed above.
- Return type
dict
Example
>>> ChemicalFormula("H2O").output_results {'formula': 'H2O', 'parsed formula': {'H': 2.0, 'O': 1.0}, 'molar mass': 18.015, 'mass percent': {'H': 11.19067444, 'O': 88.80932556}, 'atomic percent': {'H': 66.66666667, 'O': 33.33333333}, 'oxide percent': {'H2O': 100.0}}
- print_results(print_rounding_order: int = 4) None ¶
Method to print a final result of calculations in terminal.
- Parameters
print_rounding_order (int) -- print precision (4 digits by default)
- Returns
None
- export_to_txt(filename: str = 'default', print_rounding_order: int = 4) None ¶
Method to print the final result of the calculations in a txt file.
- Parameters
filename (str) -- filename string (should end with .txt)
print_rounding_order (int) -- print precision (4 digits by default)
- Returns
None
- as_json(print_rounding_order: int = 4) str ¶
Serialization of output into JSON object.
- Parameters
print_rounding_order (int) -- print precision (4 digits by default)
- Returns
A JSON-type object of results output.
- Return type
str
- export_to_json(filename: str = 'default', print_rounding_order: int = 4) None ¶
Method to print a final result of calculations in a JSON file.
- Parameters
filename (str) -- filename string (should end with .json)
print_rounding_order (int) -- print precision (4 digits by default)
- Returns
None
chemsynthcalc.chemical_reaction module¶
- class chemsynthcalc.chemical_reaction.ChemicalReaction(reaction: str = '', target: int = 0, mode: str = 'balance', target_mass: float = 1.0, rounding_order: int = 8, try_comb: bool = False)¶
Bases:
object
A class that represents a chemical reaction and do operations on it.
There are three calculation modes:
1. The "force" mode is used when a user enters coefficients in the reaction string and wants the masses to be calculated whether the reaction is balanced or not.
2. "check" mode is the same as force, but with reaction balance checks.
3. "balance" mode tries to automatically calculate coefficients from the reaction string.
Important
Unlike other properties of this class, the
chemsynthcalc.chemical_reaction.ChemicalReaction.coefficients
property can be set directly.- Parameters
reaction (str) -- a reaction string
target (int) -- index of target compound (0 by default, or first compound in the products)
mode (str) -- coefficients calculation mode
target_mass (float) -- desired mass of target compound (in grams)
rounding_order (int) -- value of rounding precision (8 by default)
try_comb (bool) -- flag, which determines whether an attempt will be made to equalize the reaction using the combinatorial method in the "balance" mode
- allowed_symbols¶
characters that allowed in the reaction string
- Type
str
- possible_reaction_separators¶
list of characters that can be used as reactants-products separator
- Type
list
- reactant_separator¶
character that can be used as compounds separator
- Type
str
- types_of_modes¶
allowed types of calculation modes
- Type
list
- algorithm¶
currently used calculation algorithm
- Type
str
- Raises
ValueError -- if rounding order <=0
NoSuchMode -- if mode is not in types_of_modes
ValueError -- if target is out of bounds of product list
ValueError -- if target < 0
ValueError -- if target_mass <=0
Examples
>>> ChemicalReaction("H2+O2=H2O") H2+O2=H2O >>> ChemicalReaction("2H2+O2=2H2O", mode="balance").coefficients [2, 1, 2] >>> ChemicalReaction("2H2+O2=2H2O", mode="check").masses [0.11190674, 0.88809326, 1.0]
- property reaction: str¶
Initial reaction
- Returns
Initial reaction string with validity check.
- Return type
str
- Raises
ValueError -- if the reaction string is empty
InvalidCharacter -- if some of characters in the string are invalid
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").reaction KMnO4+HCl=MnCl2+Cl2+H2O+KCl
- property separator: str¶
Reactants-product separator.
- Returns
Separator between reactants and products of chemical reaction.
- Return type
str
- Raises
NoSeparator -- if no separator was found in the reaction string
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").separator =
- property reactants: list¶
List of initially split reactants (left side of the reaction string).
- Returns
Formulas on the left side are split by reactant_separator (+) and include initial coefficients (in case of force or check modes).
- Return type
list
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").reactants ['KMnO4', 'HCl']
- property products: list¶
List of initially split products (right side of the reaction string).
- Returns
Formulas on the right side that have been split by reactant_separator (+) and include initial coefficients (in case of force or check modes).
- Return type
list
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").products ['MnCl2', 'Cl2', 'H2O', 'KCl']
- property compounds: list¶
List of all initially split products (left side and right side).
- Returns
Sum of reactants and products
- Return type
list
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").compounds ['KMnO4', 'HCl', 'MnCl2', 'Cl2', 'H2O', 'KCl']
- property initial_coefficients: list¶
Initial coefficients
The coefficients are not equal to 1 in case if they have been entered (generally the case for force and check modes).
- Returns
List of initial coefficients striped from the compounds.
- Return type
list
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").initial_coefficients [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
- property formulas: list¶
Decomposition of a list of formulas from the reaction string.
- Returns
Every formula is striped from coefficient and become the
chemsynthcalc.chemical_formula.ChemicalFormula
object.- Return type
list
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").formulas [KMnO4, HCl, MnCl2, Cl2, H2O, KCl]
- property parsed_formulas: list¶
List of parsed formulas of
chemsynthcalc.chemical_formula.ChemicalFormula
objects list.Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").parsed_formulas [{'K': 1.0, 'Mn': 1.0, 'O': 4.0}, {'H': 1.0, 'Cl': 1.0}, {'Mn': 1.0, 'Cl': 2.0}, {'Cl': 2.0}, {'H': 2.0, 'O': 1.0}, {'K': 1.0, 'Cl': 1.0}]
- property matrix: numpy.array¶
Chemical reaction matrix.
The first implementation of reaction matrix method is probably belongs to Blakley. In general, a chemical reaction matrix is composed of the coefficients of each atom in each compound, giving a 2D array. The matrix composes naturally from previously parsed formulas.
- Returns
2D array of each atom amount in each formula
- Return type
np.array
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").matrix [[1. 0. 0. 0. 0. 1.] (K) [1. 0. 1. 0. 0. 0.] (Mn) [4. 0. 0. 0. 1. 0.] (O) [0. 1. 0. 0. 2. 0.] (H) [0. 1. 2. 2. 0. 1.]] (Cl)
- property reactant_matrix: numpy.array¶
Left half of the reaction matrix
- Returns
2D array of each atom amount in each reactant
- Return type
np.array
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").reactant_matrix [[1. 0.] (K) [1. 0.] (Mn) [4. 0.] (O) [0. 1.] (H) [0. 1.]] (Cl)
- property product_matrix: numpy.array¶
Right half of the reaction matrix
- Returns
2D array of each atom amount in each product
- Return type
np.array
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").product_matrix [[0. 0. 0. 1.] (K) [1. 0. 0. 0.] (Mn) [0. 0. 1. 0.] (O) [0. 0. 2. 0.] (H) [2. 2. 0. 1.]] (Cl)
- property molar_masses: list¶
List of molar masses (in g/mol)
- Returns
List of molar masses of each compound in compounds
- Return type
list
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").molar_masses [158.032, 36.458, 125.838, 70.9, 18.015, 74.548]
- property coefficients: list¶
Coefficients of the chemical reaction.
There are 3 possible modes that the method can run:
1) force mode is when coefficients are entered by user in reaction string and the calculation and the calculation takes place regardless of reaction balance (it gives warning if reaction is not balanced);
2) check mode is basically the force mode but it will raise an error if reaction is not balanced and will not calculate masses);
3) balance mode uses one of three auto-balancing aglorithms described in detail in the
chemsynthcalc.reaction_balance.Balancer
class.In the fisrt two cases, the coefficients are just stripped from original formulas entered by user. In case of balance mode, coefficients are calculated.
Important
Unlike other properties of this class, this property can be set directly.
- Raises
ReactionNotBalanced -- if reaction is not balanced in "check" mode.
- Returns
list of reaction coefficients None: if it cannot balance the reaction
- Return type
list
Examples
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl", mode="balance").coefficients [2, 16, 2, 5, 8, 2] >>> reaction = ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl", mode="check") >>> reaction.coefficients = [2, 16, 2, 5, 8, 2] >>> reaction.coefficients [2, 16, 2, 5, 8, 2] >>> ChemicalReaction("2H2+2O2=H2O", mode="force").coefficients [2, 2, 1]
- property normalized_coefficients: list¶
List of coefficients normalized on target compound.
target coefficient = 1.0
- Returns
Normalized coefficients.
- Return type
list
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").normalized_coefficients [1, 8, 1, 2.5, 4, 1]
- property is_balanced: bool¶
Is the reaction balanced?
- Returns
True if the reaction is balanced with current coefficients
- Return type
bool
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").is_balanced True
- property final_reaction: str¶
Final representation of the reaction with coefficients.
- Returns
string of the final reaction
- Return type
str
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").final_reaction "2KMnO4+16HCl=2MnCl2+5Cl2+8H2O+2KCl"
- property final_reaction_normalized: str¶
Final representation of the reaction with normalized coefficients.
- Returns
String of the final normalized reaction
- Return type
str
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").final_reaction_normalized "KMnO4+8HCl=MnCl2+2.5Cl2+4H2O+KCl"
- property masses: list¶
List of masses of compounds (in grams).
List of masses of the of formulas in reaction calculated with coefficients obtained by any of the 3 methods. Calculates masses by calculating amount of substance nu (nu=mass/molar mass). Coefficients of reaction are normalized to the target. After nu of target compound is calculated, it broadcasted to other compound (with respect to their coefficients).
- Returns
List of masses of compound
- Return type
list
Examples
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").masses [1.25583687, 2.31777365, 1.0, 1.40855703, 0.57264101, 0.59241247] >>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl", target_mass=2.0).masses [2.51167374, 4.63554729, 2.0, 2.81711407, 1.14528203, 1.18482493]
- property output_results: dict¶
Collection of every output of calculated chemical reaction properties.
- Returns
All outputs collected in one dictionary.
- Return type
dict
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").output_results {'initial reaction': 'KMnO4+HCl=MnCl2+Cl2+H2O+KCl', 'reaction matrix': array([[1., 0., 0., 0., 0., 1.], [1., 0., 1., 0., 0., 0.], [4., 0., 0., 0., 1., 0.], [0., 1., 0., 0., 2., 0.], [0., 1., 2., 2., 0., 1.]]), 'mode': 'balance', 'formulas': [KMnO4, HCl, MnCl2, Cl2, H2O, KCl], 'coefficients': [2, 16, 2, 5, 8, 2], 'normalized coefficients': [1, 8, 1, 2.5, 4, 1], 'algorithm': 'inverse', 'is balanced': True, 'final reaction': '2KMnO4+16HCl=2MnCl2+5Cl2+8H2O+2KCl', 'final reaction normalized': 'KMnO4+8HCl=MnCl2+2.5Cl2+4H2O+KCl', 'molar masses': [158.032, 36.458, 125.838, 70.9, 18.015, 74.548], 'target': MnCl2, 'masses': [1.25583687, 2.31777365, 1.0, 1.40855703, 0.57264101, 0.59241247]}
- coefficients_check(coefficients: list) bool ¶
Checking the coefficients.
- Parameters
coefficients (list) -- list of coefficients
- Raises
BadCoeffiecients -- If Coefficients are None
BadCoeffiecients -- If 0 or -x in coefficients
BadCoeffiecients -- If number of coefficients is not equal to number of columns in reaction matrix
- Returns
True, if coefficients are good.
- Return type
bool
Examples
>>> reaction = ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl") >>> reaction.coefficients = [2, 16, 2, 5, 8, 2] >>> reaction.coefficients_check(reaction.coefficients) True >>> reaction.coefficients = [2, 16, 2, 5, 8] >>> reaction.coefficients_check(reaction.coefficients) chemsynthcalc.chem_errors.BadCoeffiecients: number of coefficients should be equal to 6 >>> reaction.coefficients = None >>> reaction.coefficients_check(reaction.coefficients) chemsynthcalc.chem_errors.BadCoeffiecients: Coefficients are None >>> reaction.coefficients = [2, 16, 2, 5, 8, 0] >>> reaction.coefficients_check(reaction.coefficients) chemsynthcalc.chem_errors.BadCoeffiecients: 0 or -x in coefficients
- check_elements_count() set ¶
Checks if all elements are present in both sides of the reaction.
Does not work in the force mode!
- Returns
Set of atom differences on the left and right sides of the reaction.
- Return type
set
Examples
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").check_elements_count() None >>> ChemicalReaction("KMnHoO4+HCl=MnCl2+Cl2+H2O+KCl").check_elements_count() chemsynthcalc.chem_errors.ReactantProductDifference: Cannot balance this reaction, because element(s) {'Ho'} are only in one part of the reaction
- to_integer(coefficients: list) list ¶
Cast a float to integer in a list if it is integer.
- Parameters
coefficients (list) -- list of coefficients
- Returns
List of intified coefficients.
- Return type
list
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").to_integer([1.0, 8.0, 1.0, 2.5, 4.0, 1.0]) [1, 8, 1, 2.5, 4, 1]
- balance_reaction(algorithm: str = 'inv', intify: bool = True, max_comb: int = 100000000.0) list ¶
High-level function call for all balancing algorithms.
Options availiable are: 1) "inv" - matrix inverse Thorne algorithm 2) "gpinv" - general pseudoinverse Risteski algorithm 3) "ppinv" - partial pseudoinverse Risteski algorithm 4) "comb" - combinatorial algorithm
Important
"comb" algorithm works only for integer coefficients less than 127 (see Balancer.comb_algorithm for details).
- Parameters
algorithm (str) --
intify (bool) --
max_comb (int) --
- Returns
List of obtained coefficients.
- Return type
list
Examples
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").balance_reaction(algorithm="inv", intify=True) [2, 16, 2, 5, 8, 2] >>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").balance_reaction(algorithm="gpinv", intify=False) [0.19607843137254966, 1.568627450980392, 0.1960784313725499, 0.49019607843137436, 0.7843137254901958, 0.19607843137254813]
- generate_final_reaction(coefs: list) str ¶
Final reaction string with connotated formulas and calculated coefficients.
- Parameters
coefs (list) -- list of coefficients
- Returns
String of the final reaction
- Return type
str
Example
>>> ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl").generate_final_reaction([2, 16, 2, 5, 8, 2]) "2KMnO4+16HCl=2MnCl2+5Cl2+8H2O+2KCl"
- print_results(print_rounding_order: int = 4) None ¶
Method to print a final result of calculations in terminal.
- Parameters
print_rounding_order (int) -- print precision (4 digits by default)
- Returns
None
- export_to_txt(filename: str = 'default', print_rounding_order: int = 4) None ¶
Method to print a final result of calculations in txt file.
- Parameters
filename (str) -- filename string (should end with .txt)
print_rounding_order (int) -- print precision (4 digits by default)
- Returns
None
- as_json(print_rounding_order: int = 4) str ¶
Serialization of output into JSON object.
- Argruments:
print_rounding_order (int): print precision (4 digits by default).
- Returns
JSON object of the output results.
- Return type
str
- export_to_json(filename: str = 'default', print_rounding_order: int = 4) None ¶
Method to print a final result of calculations in JSON file.
- Parameters
filename (str) -- filename string (should end with .json)
print_rounding_order (int) -- print precision (4 digits by default)
- Returns
None
chemsynthcalc.chemutils module¶
- chemsynthcalc.chemutils.arguments_type_checking(argument, *args) None ¶
Checks for type of function argument.
- Argments:
argument (Any): Argument of the function in question types (Any): Types that allowed for this argument
- Raises
TypeError -- if agrument type is not one of specified types
- Returns
None
- chemsynthcalc.chemutils.find_lcm(int_list: list) int ¶
Finds least common multiple of the list of integers.
- Parameters
int_list (list) -- list of integers
- Returns
Least common multiple
- Return type
int
Example
>>> chemsynthcalc.chemutils.find_lcm([10,20,30] 60
- chemsynthcalc.chemutils.find_gcd(int_list: list) int ¶
Finds the greatest common divider of the list of integers.
- Parameters
int_list (list) -- list of integers
- Returns
greatest common divider
- Return type
int
Example
>>> chemsynthcalc.chemutils.find_gcd([10,20,30] 10
- chemsynthcalc.chemutils.stripe_formula_from_coefficients(formula) tuple ¶
A function to stripe the initially parsed formulas from chemical reaction string.
- Parameters
formula (str) -- a formula string
- Returns
(float, str) tuple of (coefficient, reaction)
- Return type
tuple
Example
>>> chemsynthcalc.chemutils.stripe_formula_from_coefficients("4.3H3PO4") (4.3, 'H3PO4')
chemsynthcalc.formula_parser module¶
- class chemsynthcalc.formula_parser.ChemicalFormulaParser(formula: str)¶
Bases:
object
Parser of chemical formulas.
Methods of this class take string of compound chemical formula and turn it into a dict of atoms as keys and their coefficients as values.
- Parameters
formula (str) -- formula string
- atom_regex¶
regular expression for finding atoms in formula
- Type
str
- coefficient_regex¶
regular expression for atoms amounts in formula
- Type
str
- atom_and_coefficient_regex¶
atom_regex+coefficient_regex
- Type
str
- opener_brackets¶
opener brackets variations
- Type
str
- closer_brackets¶
closer brackets variations
- Type
str
- adduct_symbols¶
symbols for adduct notation (water of crystallization most often)
- Type
str
- allowed_symbols¶
regular expression for all symbols allowed in the formula string
- Type
str
- list_of_atoms¶
list of all atoms in the periodic table
- Type
list
- are_brackets_balanced() bool ¶
Check if all kinds of brackets come in pairs.
- Returns
True if all brackets are in pairs
- Return type
bool
Examples
>>> ChemicalFormulaParser("(K2SO4)*H2O").are_brackets_balanced() True >>> ChemicalFormulaParser("(K2SO4)*H2O").are_brackets_balanced() False
- is_adduct_one() bool ¶
Check if there is only one adduct in formula
- Returns
True if there is only one adduct symbol
- Return type
bool
Examples
>>> ChemicalFormulaParser("K2SO4*H2O").is_adduct_one() True >>> ChemicalFormulaParser("K2SO4*H2O*CO2").is_adduct_one() False
- are_atoms_legal(parsed: dict) None ¶
Checks if all parsed atoms belong to the periodic table.
- Parameters
parsed (dict) -- dictionary of parsed atoms
- Raises
NoSuchAtom -- if one of the parsed atoms are not in the periodic table
- Returns
None
Examples
>>> ChemicalFormulaParser("K2SO4*H2O").are_atoms_legal({'K': 2.0, 'S': 1.0, 'O': 5.0, 'H': 2.0}) None >>> ChemicalFormulaParser("KHuSO4*H2O").are_atoms_legal({'K': 1.0, 'Hu':1.0, 'S': 1.0, 'O': 5.0, 'H': 2.0}) chemsynthcalc.chem_errors.NoSuchAtom: No atom Hu in the periodic table!
- parse_formula() dict ¶
Parse the formula and return a dict with occurrences of each atom.
- Raises
InvalidCharacter -- if some characters in initial string is not in allowed_characters
MoreThanOneAdduct -- if there is more than one adduct symbol (i.e. *)
BracketsNotPaired -- if some bracket type is not coming in pairs
- Returns
Dictionary of parsed atoms
- Return type
dict
Examples
>>> ChemicalFormulaParser("H2O").parse_formula() {'H': 2.0, 'O': 1.0} >>> ChemicalFormulaParser("C2H5OH").parse_formula() {'C': 2.0, 'H': 6.0, 'O': 1.0} >>> ChemicalFormulaParser("(K0.6Na0.4)2SO4*7H2O").parse_formula() {'K': 1.2, 'Na': 0.8, 'S': 1.0, 'O': 11.0, 'H': 14.0}
chemsynthcalc.molar_mass module¶
- class chemsynthcalc.molar_mass.MolarMassCalculation(parsed_formula: dict)¶
Bases:
object
Class for the calculation of molar masses and percentages of compounds.
Compounds should be parsed by
chemsynthcalc.formula_parser.ChemicalFormulaParser
first.- Parameters
parsed_formula (dict) -- formula parsed by
chemsynthcalc.formula_parser.ChemicalFormulaParser
- atomicWeight¶
list of (atom, weight) tuple formed from
chemsynthcalc.periodic_table
- Type
list
- list_of_atoms¶
list of atoms formed from
chemsynthcalc.periodic_table
- Type
list
- calculate_molar_mass() float ¶
Calculation of the molar mass of compound from the atomic masses of atoms in a parsed formula.
Atomic masses are taken from
chemsynthcalc.periodic_table
file.- Returns
molar mass (in g/mol)
- Return type
float
Examples
>>> MolarMassCalculation({'H':2, 'O':1}).calculate_molar_mass() 18.015 >>> MolarMassCalculation({'C':2, 'H':6, 'O':1}).calculate_molar_mass() 46.069
- calculate_mass_percent() dict ¶
Calculation of mass percents of atoms in parsed formula.
- Returns
mass percentages of atoms in formula
- Return type
dict
Examples
>>> MolarMassCalculation({'H':2, 'O':1}).calculate_mass_percent() {'H': 11.19067443796836, 'O': 88.80932556203163} >>> MolarMassCalculation({'C':2, 'H':6, 'O':1}).calculate_mass_percent() {'C': 52.14352384466777, 'H': 13.12813388612733, 'O': 34.72834226920489}
- calculate_atomic_percent() dict ¶
Calculation of atomic percents of atoms in the parsed formula.
- Returns
atomic percentages of atoms in formula
- Return type
dict
Examples
>>> MolarMassCalculation({'H':2, 'O':1}).calculate_atomic_percent() {'H': 66.66666666666666, 'O': 33.33333333333333 >>> MolarMassCalculation({'C':2, 'H':6, 'O':1}).calculate_atomic_percent() {'C': 22.22222222222222, 'H': 66.66666666666666, 'O': 11.11111111111111}
- calculate_oxide_percent() dict ¶
Calculation of oxide percents in parsed formula.
Calculation of oxide percents in parsed formula from the types of oxide declared in the periodic table file. This type of data is mostly used in XRF spectrometry and mineralogy. The oxide percents are calculated by finding the convertion factor between element and its respective oxide (https://www.geol.umd.edu/~piccoli/probe/molweight.html) and normalizing the total sum to 100%. One can change the oxide type for certain elements in the
chemsynthcalc.periodic_table
file. Theoretically, this function should work for other types of binary compound (sulfides, fluorides etc.) or even salts, however, modification of this function is required (for instance, in case of binary compound, removing X atom from the list of future compounds should have X as an argument of this function)- Returns
oxide percentages of oxides in formula
- Return type
dict
Examples
>>> MolarMassCalculation({'C':2, 'H':6, 'O':1}).calculate_oxide_percent() {'CO2': 61.9570190690046, 'H2O': 38.04298093099541} >>> MolarMassCalculation({'Ba':1, 'Ti':1, 'O':3}).calculate_oxide_percent() {'BaO': 65.7516917244869, 'TiO2': 34.24830827551309}
chemsynthcalc.periodic_table module¶
- chemsynthcalc.periodic_table.periodic_table = [('H', 1.008, 2.2, 'H2O'), ('He', 4.0026, 1.2, 'He'), ('Li', 6.94, 0.98, 'Li2O'), ('Be', 9.0122, 1.57, 'BeO'), ('B', 10.81, 2.04, 'B2O3'), ('C', 12.011, 2.55, 'CO2'), ('N', 14.007, 3.04, 'NO2'), ('O', 15.999, 3.44, 'O'), ('F', 18.998, 3.98, 'F2O'), ('Ne', 20.18, 1.3, 'Ne'), ('Na', 22.99, 0.93, 'Na2O'), ('Mg', 24.305, 1.31, 'MgO'), ('Al', 26.982, 1.61, 'Al2O3'), ('Si', 28.085, 1.9, 'SiO2'), ('P', 30.974, 2.19, 'P2O3'), ('S', 32.06, 2.58, 'SO3'), ('Cl', 35.45, 3.16, 'ClO2'), ('Ar', 39.95, 2.2, 'Ar'), ('K', 39.098, 0.82, 'K2O'), ('Ca', 40.078, 1.0, 'CaO'), ('Sc', 44.956, 1.36, 'Sc2O3'), ('Ti', 47.867, 1.54, 'TiO2'), ('V', 50.942, 1.63, 'V2O5'), ('Cr', 51.996, 1.66, 'Cr2O3'), ('Mn', 54.938, 1.55, 'MnO2'), ('Fe', 55.845, 1.83, 'Fe2O3'), ('Co', 58.933, 1.88, 'Co2O3'), ('Ni', 58.693, 1.91, 'NiO'), ('Cu', 63.546, 1.9, 'Cu2O'), ('Zn', 65.38, 1.65, 'ZnO'), ('Ga', 69.723, 1.81, 'Ga2O3'), ('Ge', 72.63, 2.01, 'GeO2'), ('As', 74.922, 2.18, 'As2O3'), ('Se', 78.971, 2.55, 'Se3O4'), ('Br', 79.904, 2.96, 'BrO2'), ('Kr', 83.798, 3.0, 'Kr'), ('Rb', 85.468, 0.82, 'Rb2O'), ('Sr', 87.62, 0.95, 'SrO'), ('Y', 88.906, 1.22, 'Y2O3'), ('Zr', 91.224, 1.33, 'ZrO2'), ('Nb', 92.906, 1.6, 'Nb2O5'), ('Mo', 95.95, 2.16, 'MoO3'), ('Tc', 98.906, 1.9, 'TcO2'), ('Ru', 101.07, 2.2, 'RuO2'), ('Rh', 102.91, 2.28, 'Rh2O3'), ('Pd', 106.42, 2.2, 'PdO'), ('Ag', 107.87, 1.93, 'Ag2O'), ('Cd', 112.41, 1.69, 'CdO'), ('In', 114.82, 1.78, 'In2O3'), ('Sn', 118.71, 1.96, 'SnO2'), ('Sb', 121.76, 2.05, 'Sb2O3'), ('Te', 127.6, 2.1, 'TeO3'), ('I', 126.9, 2.66, 'I2O5'), ('Xe', 131.29, 2.6, 'Xe'), ('Cs', 132.91, 0.79, 'Cs2O'), ('Ba', 137.33, 0.89, 'BaO'), ('La', 138.91, 1.1, 'La2O3'), ('Ce', 140.12, 1.12, 'CeO2'), ('Pr', 140.91, 1.13, 'Pr2O3'), ('Nd', 144.24, 1.14, 'Nd2O3'), ('Pm', 146.92, 1.13, 'Pm2O3'), ('Sm', 150.36, 1.17, 'Sm2O3'), ('Eu', 151.96, 1.2, 'Eu2O3'), ('Gd', 157.25, 1.2, 'Gd2O3'), ('Tb', 158.93, 1.1, 'Tb2O3'), ('Dy', 162.5, 1.22, 'Dy2O3'), ('Ho', 164.93, 1.23, 'Ho2O3'), ('Er', 167.26, 1.24, 'Er2O3'), ('Tm', 168.93, 1.25, 'Tm2O3'), ('Yb', 173.05, 1.1, 'Yb2O3'), ('Lu', 174.97, 1.27, 'Lu2O3'), ('Hf', 178.49, 1.3, 'HfO2'), ('Ta', 180.95, 1.5, 'Ta2O5'), ('W', 183.84, 2.36, 'WO3'), ('Re', 186.21, 1.9, 'Re2O7'), ('Os', 190.23, 2.2, 'OsO3'), ('Ir', 192.22, 2.2, 'Ir2O3'), ('Pt', 195.08, 2.28, 'PtO'), ('Au', 196.97, 2.54, 'Au2O3'), ('Hg', 200.59, 2.0, 'HgO2'), ('Tl', 204.38, 1.62, 'Tl2O'), ('Pb', 207.2, 2.33, 'PbO2'), ('Bi', 208.98, 2.02, 'Bi2O3'), ('Po', 208.98, 2.0, 'PoO2'), ('At', 209.99, 2.2, 'At2O'), ('Rn', 222.02, 2.2, 'Rn'), ('Fr', 223.02, 0.79, 'Fr2O'), ('Ra', 226.03, 0.9, 'RaO'), ('Ac', 227.03, 1.1, 'Ac2O3'), ('Th', 232.04, 1.3, 'ThO2'), ('Pa', 231.04, 1.5, 'Pa2O5'), ('U', 238.03, 1.38, 'UO2'), ('Np', 237.05, 1.36, 'NpO2'), ('Pu', 244.06, 1.28, 'PuO2'), ('Am', 243.06, 1.13, 'AmO2'), ('Cm', 247.07, 1.28, 'Cm2O3'), ('Bk', 247.07, 1.3, 'BkO2'), ('Cf', 251.08, 1.3, 'Cf2O3'), ('Es', 252.08, 1.3, 'Es2O3'), ('Fm', 257.1, 1.3, 'Fm2O3'), ('Md', 258.1, 1.3, 'Md2O3'), ('No', 259.1, 1.3, 'No2O3'), ('Lr', 262, 1.3, 'Lr2O3'), ('Rf', 267, 1.3, 'RfO2'), ('Db', 268, 1.3, 'Db2O5'), ('Hs', 269, 1.3, 'SgO3'), ('Bh', 270, 1.3, 'Bh2O7'), ('Sg', 271, 1.3, 'HsO4'), ('Mt', 278, 1.3, 'Mt2O3'), ('Ds', 281, 1.3, 'DsO2'), ('Rg', 281, 1.3, 'RgO'), ('Nh', 284, 1.3, 'CnO2'), ('Cn', 285, 1.3, 'Nh2O3'), ('Fl', 289, 1.3, 'FlO2'), ('Mc', 289, 1.3, 'Mc2O5'), ('Lv', 292, 1.3, 'LvO3'), ('Ts', 294, 1.3, 'Ts2O7'), ('Og', 294, 1.3, 'Og')]¶
Periodic table of elements in the form of (element symbol, atomic weight, electronegativity, oxide formula). The abridged standard atomic weights are taken from https://doi.org/10.1515/pac-2019-0603. The weights of the radioactive elements are taken from https://iupac.qmul.ac.uk/AtWt/. Pauling electronegativities are taken from https://www.webelements.com/periodicity/eneg_pauling/. Pauling electronegativities for elements with unknown electronegativities (Bk-Og) are set to 1.3.
chemsynthcalc.reaction_balance module¶
- class chemsynthcalc.reaction_balance.Balancer(reactant_matrix: numpy.array, product_matrix: numpy.array, rounding_order: int, intify: bool, try_comb: bool, max_comb: int = 100000000.0)¶
Bases:
object
A class for balancing chemical equations automatically by different matrix methods
Currently implemented: Thorne algorithm (see
inv_algorithm()
method for details), Risteski general pseudo-inverse algorithm (seegpinv_algorithm()
method for details), Risteski partial pseudo-inverse algorithm (seeppinv_algorithm()
method for details), and naive combinational search algorithm (seecomb_algorithm()
for details). Class takes two matrices: matrix of reactants and matrix of products of chemical reaction, derived from general reaction matrix. Matrices are in the form of NumPy 2D array.Note
Why use scipy.linalg.pinv, when numpy.linalg.pinv is doing the same thing and does not require the whole scipy import?
There are some peculiar reaction cases where (especially for
ppinv_algorithm()
method) the results for numpy.linalg.pinv differs from system to system (np version, OS, python version etc.). My understanding is that the cause of this behaviour lies in small differences for pinv algorithm in numpy C-libraries and BLAS-libraries, hence the difference. To avoid this, the more consistent scipy.linalg.pinv was method used.- Argumetns:
reactant_matrix (np.array): matrix of reactants property generated by
chemsynthcalc.chemical_reaction.ChemicalReaction
classproduct_matrix (np.array): matrix of products property generated by
chemsynthcalc.chemical_reaction.ChemicalReaction
classrounding_order (int): coefficients rounding precision
intify (bool): determines whether the coefficients should be integers
try_comb (bool): flag, which determines whether an attempt will be made to equalize the reaction using the combinatorial method
- reaction_matrix¶
sum of reactant_matrix and product_matrix
- Type
np.array
- coef_limit¶
max integer coefficient for
intify_coefficients()
- Type
int
- calculate_coefficients_inv() list ¶
High-level function call to calculate coefficients using inverse Thorne algorithm.
- Returns
list of calculated coefficients None: if cannot calculate
- Return type
list
Example
>>> reaction = ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).calculate_coefficients_inv() [2, 16, 2, 5, 8, 2]
- calculate_coefficients_gpinv() list ¶
High-level function call to calculate coefficients using general Risteski algorithm.
- Returns
list of calculated coefficients None: if cannot calculate
- Return type
list
Example
>>> reaction = ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).calculate_coefficients_gpinv() [2, 16, 2, 5, 8, 2]
- calculate_coefficients_ppinv() list ¶
High-level function call to calculate coefficientsusing partial Risteski algorithm.
- Returns
list of calculated coefficients None: if cannot calculate
- Return type
list
Example
>>> reaction = ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).calculate_coefficients_ppinv() [2, 16, 2, 5, 8, 2]
- calculate_coefficients_comb() list ¶
High-level function call to calculate coefficients using a combinatorial algorithm.
- Returns
list of calculated coefficients None: if cannot calculate
- Return type
list
Example
>>> reaction = ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).calculate_coefficients_comb() [2, 16, 2, 5, 8, 2]
- calculate_coefficients_auto() list ¶
Automatically balance the chemical reaction.
A method that tries to automatically balance the chemical reaction. by sequentially applying the three calculation methods to the reaction matrix: a Thorne algorithm
inv_algorithm()
, two Risteski algorithmsppinv_algorithm()
andgpinv_algorithm()
and, if try_comb flag == True, a combinatorial algorithmcomb_algorithm()
.- Returns
list of calculated coefficients and str of algorithm used None: if cannot calculate
- Return type
tuple
Examples
>>> reaction = ChemicalReaction("KMnO4+HCl=MnCl2+Cl2+H2O+KCl") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).calculate_coefficients_auto() ([2, 16, 2, 5, 8, 2], 'inverse') >>> reaction = ChemicalReaction("H2O2+KNO3+H2SO4=K2SO4+NO+H2O+O2") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).calculate_coefficients_auto() ([73, 118, 59, 59, 118, 132, 125], 'general pseudoinverse') >>> reaction = ChemicalReaction("NH4ClO4+HNO3+HCl=HClO4+NOCl+N2O+N2O3+H2O+Cl2") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).calculate_coefficients_auto() ([64, 167, 137, 80, 43, 64, 30, 240, 39], 'general pseudoinverse')
- static is_reaction_balanced(reactant_matrix: numpy.array, product_matrix: numpy.array, coefficients: list, tolerance: float = 1e-08) bool ¶
Is reaction balanced with specified coefficients.
Checks if reaction is balanced by multiplying reactant matrix and product matrix by the respective coefficient vector. Method is static to call it outside of balancer instance.
- Parameters
reactant_matrix (np.array) -- matrix of reactants property generated by
chemsynthcalc.chemical_reaction.ChemicalReaction
classproduct_matrix (np.array) -- matrix of products property generated by
chemsynthcalc.chemical_reaction.ChemicalReaction
classcoefficients (list) -- coefficients
tolerance (float) -- tolerance limit for the np.allclose function
- Returns
True if balanced within tolerance
- Return type
bool
Examples
>>> reaction = ChemicalReaction("NH4ClO4+HNO3+HCl=HClO4+NOCl+N2O+N2O3+H2O+Cl2") >>> Balancer.is_reaction_balanced(reaction.reactant_matrix, reaction.product_matrix, [64, 167, 137, 80, 43, 64, 30, 240, 39]) True >>> reaction = ChemicalReaction("H2+O2=H2O") >>> Balancer.is_reaction_balanced(reaction.reactant_matrix, reaction.product_matrix, [2,2,2]) False
- round_up_coefficients(coefficients: list, order: int) list ¶
Round up the float coefficient to int.
Round up the float coefficient if it contains a series of the same digit (i.e. 3.00000000009). This function is needed to fix inevitable floating point math errors.
Note
There is probably a better and faster way to do it.
- Parameters
coefficients (list) -- List of coefficients to round
order (int) -- rounding precision
- Returns
list of rounded coefficients
- Return type
list
Example
>>> reaction = ChemicalReaction("P2O3+HClO3+H2O=H3PO4+HCl") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).round_up_coefficients([1.500000000000001, 1.0, 4.500000000000002, 3.0000000000000013, 1.0000000000000002], 8)) [1.5, 1.0, 4.5, 3.0, 1.0]
- intify_coefficients(coefficients: list, limit: int) list ¶
Reduce the coefficients to integers by finding the greatest common divider.
- Parameters
coefficients (list) -- List of coefficients to intify
limit (int) -- upper limit (max int coef)
- Returns
list of intified coefficients
- Return type
list
Example
>>> reaction = ChemicalReaction("P2O3+HClO3+H2O=H3PO4+HCl") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).intify_coefficients([1.5, 1.0, 4.5, 3.0, 1.0], 100000) [3, 2, 9, 6, 2]
- inv_algorithm() list ¶
Matrix inverse algorithm for reaction balancing.
A reaction matrix inverse algorithm proposed by Thorne. The calculation is based on the nullity, or dimensionality, of the matrix.
The algorithm can be described in steps:
If the number of rows is greater than the number of columns, add zero columns until the matrix becomes square (Note: this is a modification of the original Thorne method described in the article).
If reaction matrix is square (which means that the number of atoms involved is equal to the number of compounds) than we turn matrix in its row-echelon form by singular value decomposition.
Calculation of the nullity of the matrix, which is basically number of compounds minus rank of the matrix.
Create a matrix augumented by nullity number of rows of flipped identity matrix. If any rows are zeros, replace them with identity matrix rows.
Inverse the augumented matrix.
Exctract and transpose rightmost column.
Normalize this value with the absolute min value of the vector.
Round up float operations errors.
The absolute values of this vector are coefficients of the reaction.
Note
While this method works great for reactions with 0 and 1 nullity, it generally cannot work with nullities 2 and higher. Thorne claims that for higher nullities, a nullity number of vectors should be extracted, and each of them contains a set of correct coefficients. However, if number of rows in augmentation flipped identity matrix is 2 or more, one can easily see that each vector will contain nullity-1 zeroes, therefore they cannot be a correct vector of coefficients.
- Returns
list of calculated coefficients
- Return type
list
Examples
>>> reaction = ChemicalReaction("Bi2O3+TiO2=Bi4Ti3O12") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).inv_algorithm() [2.0, 3.0, 1.0] >>> reaction = ChemicalReaction("NH3+Br2=N2+NH4Br") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).inv_algorithm() [8.0, 3.0, 1.0, 6.0] >>> reaction = ChemicalReaction("Zn+H2S2O7=ZnSO4+H2S+H2O") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).inv_algorithm() [4.0, 2.5, 4.0, 1.0, 1.5]
- gpinv_algorithm() list ¶
Matrix gerenal pseudoinverse algorithm for reaction balancing.
A reaction matrix pseudoinverse algorithm proposed by Risteski. There are other articles and methods of chemical equation balancing by this author, however, this particular algorithm seems to be most convenient for matrix calculations. The algorithm can be described in steps:
Stack reactant matrix and negative product matrix.
Calculate MP pseudoinverse of this matrix.
Calculate coefficients by formula: x = (I – A+A)a, where x is the coefficients vector, I - identity matrix, A+ - MP inverse, A - matrix, a - arbitrary vector (in this case, vector of ones).
Note
This method is more general than Thorne's method, although it has some its own peculiarities. First of all, the output of this method is float, so, to generate an int coefs list, it needs to be converted, which is not always leads to a good result. Secondly, MP pseudoinverse is sensetive to row order in the reaction matrix. The rows should be ordered by atoms apperances in the reaction string.
- Returns
list of calculated coefficients
- Return type
list
Examples
>>> reaction = ChemicalReaction("Bi2O3+TiO2=Bi4Ti3O12") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).gpinv_algorithm() [0.857142857142856, 1.285714285714286, 0.42857142857142894] >>> reaction = ChemicalReaction("NH3+Br2=N2+NH4Br") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).gpinv_algorithm() [1.3090909090909086, 0.49090909090909124, 0.16363636363636305, 0.9818181818181823] >>> reaction = ChemicalReaction("Zn+H2S2O7=ZnSO4+H2S+H2O") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).gpinv_algorithm() [1.2530120481927716, 0.7831325301204817, 1.253012048192771, 0.313253012048193, 0.4698795180722889]
- ppinv_algorithm() list ¶
Matrix partial pseudoinverse algorithm for reaction balancing.
A reaction matrix pseudoinverse algorithm also proposed by Risteski. The method is founded on virtue of the solution of a Diophantine matrix equation by using of a Moore-Penrose pseudoinverse matrix.
The algorithm can be described in steps:
Take the Moore-Penrose pseudoinverse of the reactant matrix.
Create a G matrix in the form of (I-AA^-)B, where I is the identity matrix, A is the reactant matrix, A^- is the MP pseudoinverse of A and B is the product matrix.
Then, the vector y (coefficients of products) is equal to (I-G^-G)u.
Vector x (coefficients of reactants) is equal to A^-By + (I-A^-A)v, where u and v are columns of ones.
Note
While this algorithm and
gpinv_algorithm()
are very similar, there are some differences in output results. This method exists mostly for legacy purposes, like balancing following reactions according to Risteski.- Returns
list of calculated coefficients
- Return type
list
Examples
>>> reaction = ChemicalReaction("PtNH3BrNO3+CuNH3KNO3+BeCO3=C44H50O14.98+Cu(NO3)2+PtO3+Br1.99NO2+K1.97O+BeO+HNO3") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).ppinv_algorithm() [0.13568057806893347, 0.5130378112503738, 1.533818182010022, 0.03485950413659115, 0.5130378112503766, 0.13568057806893571, 0.06818119500951737, 0.26042528489867056, 1.5338181820100212, 0.20317996112835507] >>> reaction = ChemicalReaction("PtNH3BrNO3+(Fe(CN)3)4(Fe(CN)2)3+C44H50O15+Cu(NO3)2+K2BeO2=CuNH3KNO3+BeCO3+K3.97Fe(CN)6+PtO2+Br1.96NO2+HNO3") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).ppinv_algorithm() [1.0653080872224086, 0.02084998005190298, 0.03200884162226492, 1.236558074626148, 0.9079895101341948, 1.2365580746261489, 0.9079895101341948, 0.145949860363285, 1.0653080872224083, 0.5435245342971473, 1.0866921189021224] >>> reaction = ChemicalReaction("KAu(CN)2+AgRuAuTe8+Fe2(SO4)3+N2Se4+WO3+Na2CO3+H2CO3+HCl=[Ru(C10H8N2)3]Cl2*6H2O+C4H3AuNa1.96OS7+[WCl4(NSeCl)]2+K3.98Fe(CN)6+Au2O3+TeO3+AgO+NO2") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).ppinv_algorithm() [3.077274686056925, 0.071072198453605, 0.3865922972433353, 0.03396659573785036, 0.13586638295139766, 0.1623687648421996, 1.117085035989227, 0.8214763116641697, 0.07107219845360468, 0.16568241310428458, 0.06793319147569614, 0.7731845944866663, 1.491332235703123, 0.5685775876288415, 0.07107219845360557, 1.021075422996532]
- comb_algorithm(max_number_of_iterations: int = 100000000.0) list ¶
Matrix combinatorial algorithm for reaction balancing.
Finds a solution solution of a Diophantine matrix equation by simply enumerating of all possible solutions of number_of_iterations coefficients. The solution space is created by Cartesian product (in this case, np.meshgrid function), and therefore it is very limited by memory. There must a better, clever and fast solution to this!
Important
Only for integer coefficients less than 128. Only for reactions with total compound count <=10. A CuPy GPU-accelerated version of this method is available in the source code.
Note
All possible variations of coefficients vectors are combinations = max_coefficients**number_of_compounds, therefore this method is most effective for reaction with small numbers of compounds.
- Returns
list of calculated coefficients
- Return type
list
Examples
>>> reaction = ChemicalReaction("KMnO4+H2S+H2SO4=S+MnSO4+K2SO4+H2O") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).comb_algorithm() [2, 2, 2, 1, 2, 1, 4] >>> reaction = ChemicalReaction("H2O2+KNO3+H2SO4=K2SO4+NO+H2O+O2") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).comb_algorithm() [1, 2, 1, 1, 2, 2, 2] >>> reaction = ChemicalReaction("Fe2O3+C=Fe3O4+FeO+Fe+Fe3C+CO+CO2") >>> Balancer(reaction.reactant_matrix, reaction.product_matrix, 8, True, True).comb_algorithm() [4, 5, 1, 1, 1, 1, 1, 3]
chemsynthcalc.reaction_matrix module¶
- class chemsynthcalc.reaction_matrix.ChemicalReactionMatrix(parsed_all: list)¶
Bases:
object
Class that creates a reaction matrix from parsed formulas of the parsed reaction string.
- Parameters
parsed_all (list) -- list of all parsed formulas
- merged_dict¶
merged total dict of all parsed formulas
- Type
dict
- electronegativity¶
list of (atom, electronegativity) tuples formed from
chemsynthcalc.periodic_table
file- Type
list
- electronegativity_pattern¶
list of atoms sorted by their Pauling electronegativities
- Type
list
- list_of_atoms¶
list of atoms from
chemsynthcalc.periodic_table
file.- Type
list
- create_reaction_matrix() numpy.array ¶
Create chemical reaction matrix.
Method that creates a chemical matrix of reaction from the list of parsed compound. Initially contains a species type (atom label) at the start of each row of matrix (might be used in case of future expansion of matrix representation in print). Retruns 2D NumPy array (since Matrix class is no longer recommended https://numpy.org/doc/stable/reference/generated/numpy.matrix.html).
- Returns
the 2D array of chemical reaction matrix (amounts of all atoms in all compounds of reaction)
- Return type
np.array
Example
>>> parsed = ChemicalReaction("H2+O2=H2O").parsed_formulas >>> ChemicalReactionMatrix(parsed).create_reaction_matrix() [[2. 0. 2.] [0. 2. 1.]]