Beispiel #1
0
    def test_ensure_independent_atom_ids(self):
        """
        Ensure ensure_independent_atom_ids modifies atomlabels
        """
        s1 = Species().fromSMILES('CCC')
        s2 = Species().fromSMILES('C=C[CH]C')
        self.assertEqual(s2.molecule[0].atoms[0].id, -1)

        ensure_independent_atom_ids([s1, s2])
        # checks atom id
        self.assertNotEqual(s2.molecule[0].atoms[0].id, -1)
        # checks second resonance structure id
        self.assertNotEqual(s2.molecule[1].atoms[0].id, -1)
    def test_ensure_independent_atom_ids(self):
        """
        Ensure ensure_independent_atom_ids modifies atomlabels
        """
        s1 = Species().fromSMILES('CCC')
        s2 = Species().fromSMILES('C=C[CH]C')
        self.assertEqual(s2.molecule[0].atoms[0].id, -1)

        ensure_independent_atom_ids([s1, s2])
        # checks atom id
        self.assertNotEqual(s2.molecule[0].atoms[0].id, -1)
        # checks second resonance structure id
        self.assertNotEqual(s2.molecule[1].atoms[0].id, -1)
Beispiel #3
0
    def test_ensure_independent_atom_ids_no_resonance(self):
        """
        Ensure ensure_independent_atom_ids does not generate resonance
        """
        s1 = Species().fromSMILES('CCC')
        s2 = Species().fromSMILES('C=C[CH]C')
        self.assertEqual(s2.molecule[0].atoms[0].id, -1)

        ensure_independent_atom_ids([s1, s2], resonance=False)
        # checks resonance structures
        self.assertEqual(len(s2.molecule), 1)
        # checks that atom ids are changed
        for atom in s2.molecule[0].atoms:
            self.assertNotEqual(atom.id, -1)
    def test_ensure_independent_atom_ids_no_resonance(self):
        """
        Ensure ensure_independent_atom_ids does not generate resonance
        """
        s1 = Species().fromSMILES('CCC')
        s2 = Species().fromSMILES('C=C[CH]C')
        self.assertEqual(s2.molecule[0].atoms[0].id, -1)

        ensure_independent_atom_ids([s1, s2],resonance=False)
        # checks resonance structures
        self.assertEqual(len(s2.molecule),1)
        # checks that atom ids are changed
        for atom in s2.molecule[0].atoms:
            self.assertNotEqual(atom.id, -1)
Beispiel #5
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