Example #1
0
    def test_reaction_degeneracy_independent_of_generatereactions_direction(
            self):
        """
        test_reaction_degeneracy_independent_of_generatereactions_direction
        
        Ensure the returned kinetics have the same degeneracy irrespective of
        whether __generateReactions has forward = True or False
        """

        family = database.kinetics.families['Disproportionation']

        molA = Molecule().fromSMILES('C[CH2]')
        molB = Molecule().fromSMILES('C[CH2]')
        molC = Molecule().fromSMILES('C=C')
        molD = Molecule().fromSMILES('CC')

        molA.assignAtomIDs()
        molB.assignAtomIDs()
        molC.assignAtomIDs()
        molD.assignAtomIDs()

        # generate reactions in both directions
        forward_reactions = family._KineticsFamily__generateReactions(
            [molA, molB], products=[molC, molD], forward=True)
        reverse_reactions = family._KineticsFamily__generateReactions(
            [molC, molD], products=[molA, molB], forward=False)

        forward_reactions = find_degenerate_reactions(forward_reactions)
        reverse_reactions = find_degenerate_reactions(reverse_reactions)

        self.assertEqual(
            forward_reactions[0].degeneracy, reverse_reactions[0].degeneracy,
            'the kinetics from forward and reverse directions had different degeneracies, {} and {} respectively'
            .format(forward_reactions[0].degeneracy,
                    reverse_reactions[0].degeneracy))
    def test_reaction_degeneracy_independent_of_generatereactions_direction(self):
        """
        test_reaction_degeneracy_independent_of_generatereactions_direction
        
        Ensure the returned kinetics have the same degeneracy irrespective of
        whether __generateReactions has forward = True or False
        """

        family = database.kinetics.families['Disproportionation']

        molA = Molecule().fromSMILES('C[CH2]')
        molB = Molecule().fromSMILES('C[CH2]')
        molC = Molecule().fromSMILES('C=C')
        molD = Molecule().fromSMILES('CC')
        
        molA.assignAtomIDs()
        molB.assignAtomIDs()
        molC.assignAtomIDs()
        molD.assignAtomIDs()

        # generate reactions in both directions
        forward_reactions = family._KineticsFamily__generateReactions([molA, molB], products=[molC, molD], forward=True)
        reverse_reactions = family._KineticsFamily__generateReactions([molC, molD], products=[molA, molB], forward=False)

        forward_reactions = find_degenerate_reactions(forward_reactions)
        reverse_reactions = find_degenerate_reactions(reverse_reactions)

        self.assertEqual(forward_reactions[0].degeneracy, reverse_reactions[0].degeneracy,
                         'the kinetics from forward and reverse directions had different degeneracies, {} and {} respectively'.format(forward_reactions[0].degeneracy, reverse_reactions[0].degeneracy))
Example #3
0
File: rmgdb.py Project: alongd/ARC
def loop_families(rmgdb, reaction):
    """
    Loop through kinetic families and return a list of tuples of (family, degenerate_reactions)
    `reaction` is an RMG Reaction object
    Returns a list of (family, degenerate_reactions) tuples
    """
    fam_list = list()
    for family in rmgdb.kinetics.families.values():
        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.generateReactions(reactants=[reactant0],
                                                   products=reaction.products)
                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.generateReactions(
                        reactants=[reactant0, reactant1],
                        products=reaction.products)
                    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.generateReactions(
                            reactants=[reactant0, reactant1, reactant2],
                            products=reaction.products)
                        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 isomorphic_species_lists([product0], fam_rxn.products):
                        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)
        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 isomorphic_species_lists([product0, product1],
                                                    fam_rxn.products):
                            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)
        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 isomorphic_species_lists(
                                [product0, product1, product2],
                                    fam_rxn.products):
                                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)
        if degenerate_reactions:
            fam_list.append((family, degenerate_reactions))
    return fam_list
Example #4
0
    def generate_reactions_from_families(self,
                                         reactants,
                                         products=None,
                                         only_families=None,
                                         resonance=True):
        """
        Generate all reactions between the provided list or tuple of one or two
        `reactants`, which can be either :class:`Molecule` objects or :class:`Species`
        objects. This method can apply all kinetics families or a selected subset.

        Args:
            reactants:      Molecules or Species to react
            products:       List of Molecules or Species of desired product structures (optional)
            only_families:  List of family labels to generate reactions from (optional)
                            Default is to generate reactions from all families
            resonance:      Flag to generate resonance structures for reactants and products (optional)
                            Default is True, resonance structures will be generated

        Returns:
            List of reactions containing Species objects with the specified reactants and products.
        """
        # Check if the reactants are the same
        # If they refer to the same memory address, then make a deep copy so
        # they can be manipulated independently
        if isinstance(reactants, tuple):
            reactants = list(reactants)
        same_reactants = 0
        if len(reactants) == 2:
            if reactants[0] is reactants[1]:
                reactants[1] = reactants[1].copy(deep=True)
                same_reactants = 2
            elif reactants[0].is_isomorphic(reactants[1]):
                same_reactants = 2
        elif len(reactants) == 3:
            same_01 = reactants[0] is reactants[1]
            same_02 = reactants[0] is reactants[2]
            if same_01 and same_02:
                same_reactants = 3
                reactants[1] = reactants[1].copy(deep=True)
                reactants[2] = reactants[2].copy(deep=True)
            elif same_01:
                same_reactants = 2
                reactants[1] = reactants[1].copy(deep=True)
            elif same_02:
                same_reactants = 2
                reactants[2] = reactants[2].copy(deep=True)
            elif reactants[1] is reactants[2]:
                same_reactants = 2
                reactants[2] = reactants[2].copy(deep=True)
            else:
                same_01 = reactants[0].is_isomorphic(reactants[1])
                same_02 = reactants[0].is_isomorphic(reactants[2])
                if same_01 and same_02:
                    same_reactants = 3
                elif same_01 or same_02:
                    same_reactants = 2
                elif reactants[1].is_isomorphic(reactants[2]):
                    same_reactants = 2

        # Label reactant atoms for proper degeneracy calculation (cannot be in tuple)
        ensure_independent_atom_ids(reactants, resonance=resonance)

        combos = generate_molecule_combos(reactants)

        reaction_list = []
        for combo in combos:
            reaction_list.extend(
                self.react_molecules(combo,
                                     products=products,
                                     only_families=only_families,
                                     prod_resonance=resonance))

        # Calculate reaction degeneracy
        reaction_list = find_degenerate_reactions(reaction_list,
                                                  same_reactants,
                                                  kinetics_database=self)
        # Add reverse attribute to families with ownReverse
        to_delete = []
        for i, rxn in enumerate(reaction_list):
            family = self.families[rxn.family]
            if family.own_reverse:
                successful = family.add_reverse_attribute(rxn)
                if not successful:
                    to_delete.append(i)
        # Delete reactions which we could not find a reverse reaction for
        for i in reversed(to_delete):
            del reaction_list[i]

        return reaction_list
Example #5
0
def loop_families(rmgdb, reaction):
    """
    Loop through kinetic families and return a list of tuples of (family, degenerate_reactions)
    `reaction` is an RMG Reaction object.
    Returns a list of (family, degenerate_reactions) tuples.

    Args:
        rmgdb (RMGDatabase): The RMG database instance.
        reaction (Reaction): The RMG Reaction object.

    Returns: list
        Entries are corresponding RMG reaction families.
    """
    reaction = reaction.copy(
    )  # use a copy to avoid changing atom order in the molecules by RMG
    fam_list = list()
    for family in rmgdb.kinetics.families.values():
        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)
                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)
                    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)
                        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):
                        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)
        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):
                            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)
        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):
                                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)
        if degenerate_reactions:
            fam_list.append((family, degenerate_reactions))
    return fam_list
Example #6
0
def loop_families(
    rmgdb: RMGDatabase,
    reaction: Reaction,
) -> List[Tuple['KineticsFamily', list]]:
    """
    Loop through kinetic families and return a list of tuples of (family, degenerate_reactions)
    corresponding to ``reaction``.

    Args:
        rmgdb (RMGDatabase): The RMG database instance.
        reaction (Reaction): The RMG Reaction object instance.

    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:
        spc.generate_resonance_structures(save_order=True)
    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,
                )
                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))
    return fam_list