diff --git a/arc/reaction_test.py b/arc/reaction_test.py index 93753ac62e..709166cc21 100644 --- a/arc/reaction_test.py +++ b/arc/reaction_test.py @@ -35,7 +35,8 @@ def setUpClass(cls): """ cls.maxDiff = None cls.rmgdb = rmgdb.make_rmg_database_object() - cls.rmgdb.kinetics.families = None + if cls.rmgdb.kinetics is not None: + cls.rmgdb.kinetics.families = None rmgdb.load_families_only(cls.rmgdb, "all") cls.h2_xyz = {'coords': ((0, 0, 0.3736550), (0, 0, -0.3736550)), 'isotopes': (1, 1), 'symbols': ('H', 'H')} diff --git a/arc/rmgdb.py b/arc/rmgdb.py index bb6e9dc6a3..4687d51ada 100644 --- a/arc/rmgdb.py +++ b/arc/rmgdb.py @@ -6,10 +6,9 @@ from typing import TYPE_CHECKING, List, Optional, Tuple, Union from rmgpy import settings as rmg_settings -from rmgpy.data.kinetics.common import find_degenerate_reactions from rmgpy.data.rmg import RMGDatabase from rmgpy.exceptions import KineticsError -from rmgpy.reaction import same_species_lists, Reaction +from rmgpy.reaction import Reaction from arc.common import get_logger, generate_resonance_structures from arc.exceptions import InputError @@ -213,6 +212,24 @@ def determine_reaction_family(rmgdb: RMGDatabase, return None, False +def match_family_by_label(rmgdb: RMGDatabase, + family_label: str, + ) -> Optional['KineticsFamily']: + """ + Find a family in the RMG database by its label. + + Args: + rmgdb (RMGDatabase): The RMG database instance. + family_label (str): The family label. + + Returns: Optional[KineticsFamily] + The corresponding family object instance. + """ + for family in rmgdb.kinetics.families.values(): + if family.label == family_label: + return family + + def loop_families(rmgdb: RMGDatabase, reaction: Reaction, ) -> List[Tuple['KineticsFamily', list]]: @@ -227,79 +244,20 @@ def loop_families(rmgdb: RMGDatabase, Returns: List[Tuple['KineticsFamily', list]] Entries are tuples of a corresponding RMG KineticsFamily instance and a list of degenerate reactions. """ - reaction = reaction.copy() # Use a copy to avoid changing atom order in the molecules by RMG. - for spc in reaction.reactants + reaction.products: - generate_resonance_structures(spc) - fam_list = list() - for family in rmgdb.kinetics.families.values(): - family.save_order = True - degenerate_reactions = list() - family_reactions_by_r = list() # Family reactions for the specified reactants. - family_reactions_by_rnp = list() # Family reactions for the specified reactants and products. - - if len(reaction.reactants) == 1: - for reactant0 in reaction.reactants[0].molecule: - fam_rxn = family.generate_reactions(reactants=[reactant0], - products=reaction.products, - delete_labels=False, + rxn_copy = reaction.copy() + reactions_f = rmgdb.kinetics.generate_reactions(reactants=rxn_copy.reactants, + products=rxn_copy.products, + only_families=True, + resonance=True, + ) + reactions_r = rmgdb.kinetics.generate_reactions(reactants=rxn_copy.products, + products=rxn_copy.reactants, + only_families=True, + resonance=True, ) - if fam_rxn: - family_reactions_by_r.extend(fam_rxn) - elif len(reaction.reactants) == 2: - for reactant0 in reaction.reactants[0].molecule: - for reactant1 in reaction.reactants[1].molecule: - fam_rxn = family.generate_reactions(reactants=[reactant0, reactant1], - products=reaction.products, - delete_labels=False, - ) - if fam_rxn: - family_reactions_by_r.extend(fam_rxn) - elif len(reaction.reactants) == 3: - for reactant0 in reaction.reactants[0].molecule: - for reactant1 in reaction.reactants[1].molecule: - for reactant2 in reaction.reactants[2].molecule: - fam_rxn = family.generate_reactions(reactants=[reactant0, reactant1, reactant2], - products=reaction.products, - delete_labels=False, - ) - if fam_rxn: - family_reactions_by_r.extend(fam_rxn) - - if len(reaction.products) == 1: - for fam_rxn in family_reactions_by_r: - for product0 in reaction.products[0].molecule: - if same_species_lists([product0], fam_rxn.products, save_order=True): - family_reactions_by_rnp.append(fam_rxn) - degenerate_reactions = find_degenerate_reactions(rxn_list=family_reactions_by_rnp, - same_reactants=False, - kinetics_database=rmgdb.kinetics, - save_order=True - ) - elif len(reaction.products) == 2: - for fam_rxn in family_reactions_by_r: - for product0 in reaction.products[0].molecule: - for product1 in reaction.products[1].molecule: - if same_species_lists([product0, product1], fam_rxn.products, save_order=True): - family_reactions_by_rnp.append(fam_rxn) - degenerate_reactions = find_degenerate_reactions(rxn_list=family_reactions_by_rnp, - same_reactants=False, - kinetics_database=rmgdb.kinetics, - save_order=True - ) - elif len(reaction.products) == 3: - for fam_rxn in family_reactions_by_r: - for product0 in reaction.products[0].molecule: - for product1 in reaction.products[1].molecule: - for product2 in reaction.products[2].molecule: - if same_species_lists([product0, product1, product2], fam_rxn.products, save_order=True): - family_reactions_by_rnp.append(fam_rxn) - degenerate_reactions = find_degenerate_reactions(rxn_list=family_reactions_by_rnp, - same_reactants=False, - kinetics_database=rmgdb.kinetics, - save_order=True - ) - if degenerate_reactions: - fam_list.append((family, degenerate_reactions)) + fam_list = list() + for rxn in reactions_f + reactions_r: + fam_list.append((match_family_by_label(rmgdb=rmgdb, family_label=rxn.family), rxn)) return fam_list @@ -331,17 +289,16 @@ def determine_rmg_kinetics(rmgdb: RMGDatabase, break # Families: fam_list = loop_families(rmgdb, reaction) - for family, degenerate_reactions in fam_list: - for deg_rxn in degenerate_reactions: - template = family.retrieve_template(deg_rxn.template) - kinetics = family.estimate_kinetics_using_rate_rules(template)[0] - kinetics.change_rate(deg_rxn.degeneracy) - kinetics = kinetics.to_arrhenius(dh_rxn298) # Convert ArrheniusEP to Arrhenius using the dHrxn at 298K - deg_rxn.kinetics = kinetics - deg_rxn.comment = f'Family: {deg_rxn.family}' - deg_rxn.reactants = reaction.reactants - deg_rxn.products = reaction.products - rmg_reactions.extend(degenerate_reactions) + for family, rxn in fam_list: + template = family.retrieve_template(rxn.template) + kinetics = family.estimate_kinetics_using_rate_rules(template)[0] + kinetics.change_rate(rxn.degeneracy) + kinetics = kinetics.to_arrhenius(dh_rxn298) # Convert ArrheniusEP to Arrhenius using the dHrxn at 298K + rxn.kinetics = kinetics + rxn.comment = f'Family: {rxn.family}' + rxn.reactants = reaction.reactants + rxn.products = reaction.products + rmg_reactions.append(rxn) worked_through_nist_fams = [] # NIST: for family, degenerate_reactions in fam_list: