Esempio n. 1
0
    def test_identical_reactants_have_similar_kinetics(self):
        """
        tests identical reactants have the same kinetics than different reactants.
        
        this test assures that r addition multiple bond reactions from the same 
        rate rule have the same reaction rate if the reactants are identicaal 
        since little changes in the reactant or transition state symmetry. 
        
        This method should be more robust than just checking
        the degeneracy of reactions.
        """
        rxn_family_str = 'R_Addition_MultipleBond'
        butenyl_adj_list = """
            multiplicity 2
            1 C u0 p0 c0 {2,S} {3,S} {5,S} {6,S}
            2 C u0 p0 c0 {1,S} {4,D} {7,S}
            3 C u1 p0 c0 {1,S} {8,S} {9,S}
            4 C u0 p0 c0 {2,D} {10,S} {11,S}
            5 H u0 p0 c0 {1,S}
            6 H u0 p0 c0 {1,S}
            7 H u0 p0 c0 {2,S}
            8 H u0 p0 c0 {3,S}
            9 H u0 p0 c0 {3,S}
            10 H u0 p0 c0 {4,S}
            11 H u0 p0 c0 {4,S}
            """
        pentenyl_adj_list = """
            multiplicity 2
            1 C u0 p0 c0 {2,S} {3,S} {8,S} {9,S}
            2 C u0 p0 c0 {1,S} {4,S} {6,S} {7,S}
            3 C u0 p0 c0 {1,S} {5,D} {10,S}
            4 C u1 p0 c0 {2,S} {11,S} {12,S}
            5 C u0 p0 c0 {3,D} {13,S} {14,S}
            6 H u0 p0 c0 {2,S}
            7 H u0 p0 c0 {2,S}
            8 H u0 p0 c0 {1,S}
            9 H u0 p0 c0 {1,S}
            10 H u0 p0 c0 {3,S}
            11 H u0 p0 c0 {4,S}
            12 H u0 p0 c0 {4,S}
            13 H u0 p0 c0 {5,S}
            14 H u0 p0 c0 {5,S}
            """

        family = self.database.kinetics.families[rxn_family_str]

        # get reaction objects and their degeneracy
        pp_degeneracy, pp_reactions = self.find_reaction_degeneracy(
            [butenyl_adj_list, butenyl_adj_list],
            rxn_family_str,
            num_independent_reactions=2)
        pb_degeneracy, pb_reactions = self.find_reaction_degeneracy(
            [butenyl_adj_list, pentenyl_adj_list],
            rxn_family_str,
            num_independent_reactions=4)

        # find the correct reaction from the list
        symmetric_product = Molecule().fromAdjacencyList('''
            multiplicity 3
            1 C u0 p0 c0 {2,S} {3,S} {6,S} {9,S}
            2 C u0 p0 c0 {1,S} {4,S} {10,S} {11,S}
            3 C u0 p0 c0 {1,S} {7,S} {12,S} {13,S}
            4 C u0 p0 c0 {2,S} {5,S} {14,S} {15,S}
            5 C u0 p0 c0 {4,S} {8,D} {16,S}
            6 C u1 p0 c0 {1,S} {19,S} {20,S}
            7 C u1 p0 c0 {3,S} {17,S} {18,S}
            8 C u0 p0 c0 {5,D} {21,S} {22,S}
            9 H u0 p0 c0 {1,S}
            10 H u0 p0 c0 {2,S}
            11 H u0 p0 c0 {2,S}
            12 H u0 p0 c0 {3,S}
            13 H u0 p0 c0 {3,S}
            14 H u0 p0 c0 {4,S}
            15 H u0 p0 c0 {4,S}
            16 H u0 p0 c0 {5,S}
            17 H u0 p0 c0 {7,S}
            18 H u0 p0 c0 {7,S}
            19 H u0 p0 c0 {6,S}
            20 H u0 p0 c0 {6,S}
            21 H u0 p0 c0 {8,S}
            22 H u0 p0 c0 {8,S}
            ''')
        asymmetric_product = Molecule().fromAdjacencyList('''
            multiplicity 3
            1 C u0 p0 c0 {2,S} {3,S} {7,S} {10,S}
            2 C u0 p0 c0 {1,S} {5,S} {11,S} {12,S}
            3 C u0 p0 c0 {1,S} {4,S} {13,S} {14,S}
            4 C u0 p0 c0 {3,S} {6,S} {17,S} {18,S}
            5 C u0 p0 c0 {2,S} {8,S} {15,S} {16,S}
            6 C u0 p0 c0 {4,S} {9,D} {19,S}
            7 C u1 p0 c0 {1,S} {22,S} {23,S}
            8 C u1 p0 c0 {5,S} {20,S} {21,S}
            9 C u0 p0 c0 {6,D} {24,S} {25,S}
            10 H u0 p0 c0 {1,S}
            11 H u0 p0 c0 {2,S}
            12 H u0 p0 c0 {2,S}
            13 H u0 p0 c0 {3,S}
            14 H u0 p0 c0 {3,S}
            15 H u0 p0 c0 {5,S}
            16 H u0 p0 c0 {5,S}
            17 H u0 p0 c0 {4,S}
            18 H u0 p0 c0 {4,S}
            19 H u0 p0 c0 {6,S}
            20 H u0 p0 c0 {8,S}
            21 H u0 p0 c0 {8,S}
            22 H u0 p0 c0 {7,S}
            23 H u0 p0 c0 {7,S}
            24 H u0 p0 c0 {9,S}
            25 H u0 p0 c0 {9,S}
            ''')

        pp_reaction = next(
            (reaction for reaction in pp_reactions
             if reaction.products[0].isIsomorphic(symmetric_product)), None)
        pb_reaction = next(
            (reaction for reaction in pb_reactions
             if reaction.products[0].isIsomorphic(asymmetric_product)), None)

        pp_kinetics_list = family.getKinetics(
            pp_reaction,
            pp_reaction.template,
            degeneracy=pp_reaction.degeneracy,
            estimator='rate rules')
        self.assertEqual(
            len(pp_kinetics_list), 1,
            'The propyl and propyl recombination should only return one reaction. It returned {0}. Here is the full kinetics: {1}'
            .format(len(pp_kinetics_list), pp_kinetics_list))

        pb_kinetics_list = family.getKinetics(
            pb_reaction,
            pb_reaction.template,
            degeneracy=pb_reaction.degeneracy,
            estimator='rate rules')
        self.assertEqual(
            len(pb_kinetics_list), 1,
            'The propyl and butyl recombination should only return one reaction. It returned {0}. Here is the full kinetics: {1}'
            .format(len(pb_kinetics_list), pb_kinetics_list))

        # the same reaction group must be found or this test will not work
        self.assertIn(
            pb_kinetics_list[0][0].comment, pp_kinetics_list[0][0].comment,
            'this test found different kinetics for the two groups, so it will not function as expected\n'
            + str(pp_kinetics_list) + str(pb_kinetics_list))

        # test that the kinetics are correct
        self.assertAlmostEqual(pp_kinetics_list[0][0].getRateCoefficient(300),
                               pb_kinetics_list[0][0].getRateCoefficient(300))
Esempio n. 2
0
 def test_from_smarts(self):
     smarts = '[CH4]'
     mol = from_smarts(Molecule(), smarts)
     self.assertTrue(mol.is_isomorphic(self.methane))
Esempio n. 3
0
    def test_read_inchikey_error(self):
        """Test that the correct error is raised when reading an InChIKey"""
        with self.assertRaises(ValueError) as cm:
            Molecule().from_inchi('InChIKey=UHOVQNZJYSORNB-UHFFFAOYSA-N')

        self.assertTrue('InChIKey is a write-only format' in str(cm.exception))
Esempio n. 4
0
 def test_axis_symmetry_number7(self):
     """
     Test the Molecule.calculate_axis_symmetry_number() on C=C=C=[N]
     """
     molecule = Molecule().from_smiles('C=C=C=[N]')
     self.assertEqual(calculate_axis_symmetry_number(molecule), 2)
Esempio n. 5
0
    def testParseThermoComments(self):
        """
        Test that the ThermoDatabase.extractSourceFromComments function works properly
        on various thermo comments.
        """
        from rmgpy.thermo import NASA, NASAPolynomial
        # Pure group additivity thermo
        propane = Species(
            index=3,
            label="Propane",
            thermo=NASA(
                polynomials=[
                    NASAPolynomial(coeffs=[
                        3.05257, 0.0125099, 3.79386e-05, -5.12022e-08,
                        1.87065e-11, -14454.2, 10.0672
                    ],
                                   Tmin=(100, 'K'),
                                   Tmax=(986.57, 'K')),
                    NASAPolynomial(coeffs=[
                        5.91316, 0.0218763, -8.17661e-06, 1.49855e-09,
                        -1.05991e-13, -16038.9, -8.86555
                    ],
                                   Tmin=(986.57, 'K'),
                                   Tmax=(5000, 'K'))
                ],
                Tmin=(100, 'K'),
                Tmax=(5000, 'K'),
                comment=
                """Thermo group additivity estimation: group(Cs-CsCsHH) + gauche(Cs(CsCsRR)) + other(R) + group(Cs-CsHHH) + gauche(Cs(Cs(CsRR)RRR)) + other(R) + group(Cs-CsHHH) + gauche(Cs(Cs(CsRR)RRR)) + other(R)"""
            ),
            molecule=[Molecule(SMILES="CCC")])

        source = self.database.extractSourceFromComments(propane)
        self.assertTrue(
            'GAV' in source,
            'Should have found that propane thermo source is GAV.')
        self.assertEqual(len(source['GAV']['group']), 2)
        self.assertEqual(len(source['GAV']['other']), 1)
        self.assertEqual(len(source['GAV']['gauche']), 2)

        # Pure library thermo
        dipk = Species(index=1,
                       label="DIPK",
                       thermo=NASA(polynomials=[
                           NASAPolynomial(coeffs=[
                               3.35002, 0.017618, -2.46235e-05, 1.7684e-08,
                               -4.87962e-12, 35555.7, 5.75335
                           ],
                                          Tmin=(100, 'K'),
                                          Tmax=(888.28, 'K')),
                           NASAPolynomial(coeffs=[
                               6.36001, 0.00406378, -1.73509e-06, 5.05949e-10,
                               -4.49975e-14, 35021, -8.41155
                           ],
                                          Tmin=(888.28, 'K'),
                                          Tmax=(5000, 'K'))
                       ],
                                   Tmin=(100, 'K'),
                                   Tmax=(5000, 'K'),
                                   comment="""Thermo library: DIPK"""),
                       molecule=[Molecule(SMILES="CC(C)C(=O)C(C)C")])

        source = self.database.extractSourceFromComments(dipk)
        self.assertTrue('Library' in source)

        # Mixed library and HBI thermo
        dipk_rad = Species(
            index=4,
            label="R_tert",
            thermo=NASA(polynomials=[
                NASAPolynomial(coeffs=[
                    2.90061, 0.0298018, -7.06268e-05, 6.9636e-08, -2.42414e-11,
                    54431, 5.44492
                ],
                               Tmin=(100, 'K'),
                               Tmax=(882.19, 'K')),
                NASAPolynomial(coeffs=[
                    6.70999, 0.000201027, 6.65617e-07, -7.99543e-11,
                    4.08721e-15, 54238.6, -9.73662
                ],
                               Tmin=(882.19, 'K'),
                               Tmax=(5000, 'K'))
            ],
                        Tmin=(100, 'K'),
                        Tmax=(5000, 'K'),
                        comment="""Thermo library: DIPK + radical(C2CJCHO)"""),
            molecule=[
                Molecule(SMILES="C[C](C)C(=O)C(C)C"),
                Molecule(SMILES="CC(C)=C([O])C(C)C")
            ])

        source = self.database.extractSourceFromComments(dipk_rad)
        self.assertTrue('Library' in source)
        self.assertTrue('GAV' in source)
        self.assertEqual(len(source['GAV']['radical']), 1)

        # Pure QM thermo
        cineole = Species(
            index=6,
            label="Cineole",
            thermo=NASA(polynomials=[
                NASAPolynomial(coeffs=[
                    -0.324129, 0.0619667, 9.71008e-05, -1.60598e-07,
                    6.28285e-11, -38699.9, 29.3686
                ],
                               Tmin=(100, 'K'),
                               Tmax=(985.52, 'K')),
                NASAPolynomial(coeffs=[
                    20.6043, 0.0586913, -2.22152e-05, 4.19949e-09,
                    -3.06046e-13, -46791, -91.4152
                ],
                               Tmin=(985.52, 'K'),
                               Tmax=(5000, 'K'))
            ],
                        Tmin=(100, 'K'),
                        Tmax=(5000, 'K'),
                        comment="""QM MopacMolPM3 calculation attempt 1"""),
            molecule=[Molecule(SMILES="CC12CCC(CC1)C(C)(C)O2")])

        source = self.database.extractSourceFromComments(cineole)
        self.assertTrue('QM' in source)

        # Mixed QM and HBI thermo
        cineole_rad = Species(
            index=7,
            label="CineoleRad",
            thermo=NASA(
                polynomials=[
                    NASAPolynomial(coeffs=[
                        -0.2897, 0.0627717, 8.63299e-05, -1.47868e-07,
                        5.81665e-11, -14017.6, 31.0266
                    ],
                                   Tmin=(100, 'K'),
                                   Tmax=(988.76, 'K')),
                    NASAPolynomial(coeffs=[
                        20.4836, 0.0562555, -2.13903e-05, 4.05725e-09,
                        -2.96023e-13, -21915, -88.1205
                    ],
                                   Tmin=(988.76, 'K'),
                                   Tmax=(5000, 'K'))
                ],
                Tmin=(100, 'K'),
                Tmax=(5000, 'K'),
                comment=
                """QM MopacMolPM3 calculation attempt 1 + radical(Cs_P)"""),
            molecule=[Molecule(SMILES="[CH2]C12CCC(CC1)C(C)(C)O2")])

        source = self.database.extractSourceFromComments(cineole_rad)
        self.assertTrue('QM' in source)
        self.assertTrue('GAV' in source)
        self.assertEqual(len(source['GAV']['radical']), 1)

        # No thermo comments
        other = Species(
            index=7,
            label="CineoleRad",
            thermo=NASA(
                polynomials=[
                    NASAPolynomial(coeffs=[
                        -0.2897, 0.0627717, 8.63299e-05, -1.47868e-07,
                        5.81665e-11, -14017.6, 31.0266
                    ],
                                   Tmin=(100, 'K'),
                                   Tmax=(988.76, 'K')),
                    NASAPolynomial(coeffs=[
                        20.4836, 0.0562555, -2.13903e-05, 4.05725e-09,
                        -2.96023e-13, -21915, -88.1205
                    ],
                                   Tmin=(988.76, 'K'),
                                   Tmax=(5000, 'K'))
                ],
                Tmin=(100, 'K'),
                Tmax=(5000, 'K'),
            ),
            molecule=[Molecule(SMILES="[CH2]C12CCC(CC1)C(C)(C)O2")])

        # Function should complain if there's no thermo comments
        self.assertRaises(self.database.extractSourceFromComments(cineole_rad))

        # Check a dummy species that has plus and minus thermo group contributions
        polycyclic = Species(
            index=7,
            label="dummy",
            thermo=NASA(
                polynomials=[
                    NASAPolynomial(coeffs=[
                        -0.2897, 0.0627717, 8.63299e-05, -1.47868e-07,
                        5.81665e-11, -14017.6, 31.0266
                    ],
                                   Tmin=(100, 'K'),
                                   Tmax=(988.76, 'K')),
                    NASAPolynomial(coeffs=[
                        20.4836, 0.0562555, -2.13903e-05, 4.05725e-09,
                        -2.96023e-13, -21915, -88.1205
                    ],
                                   Tmin=(988.76, 'K'),
                                   Tmax=(5000, 'K'))
                ],
                Tmin=(100, 'K'),
                Tmax=(5000, 'K'),
                comment=
                """Thermo group additivity estimation: group(Cs-CsCsHH) + group(Cs-CsCsHH) - ring(Benzene)"""
            ),
            molecule=[Molecule(SMILES="[CH2]C12CCC(CC1)C(C)(C)O2")])

        source = self.database.extractSourceFromComments(polycyclic)
        self.assertTrue('GAV' in source)
        self.assertEqual(source['GAV']['ring'][0][1],
                         -1)  # the weight of benzene contribution should be -1
        self.assertEqual(
            source['GAV']['group'][0][1],
            2)  # weight of the group(Cs-CsCsHH) conbtribution should be 2
Esempio n. 6
0
 def test_axis_symmetry_number_butatrienyl(self):
     """
     Test the Molecule.calculate_axis_symmetry_number() on C=C=C=[CH]
     """
     molecule = Molecule().from_smiles('C=C=C=[CH]')
     self.assertEqual(calculate_axis_symmetry_number(molecule), 1)
Esempio n. 7
0
 def test_axis_symmetry_number1(self):
     """
     Test the Molecule.calculate_axis_symmetry_number() on CC(C)=C=C(CC)CC
     """
     molecule = Molecule().from_smiles('CC(C)=C=C(CC)CC')
     self.assertEqual(calculate_axis_symmetry_number(molecule), 2)
Esempio n. 8
0
    def test_from_smiles(self):
        smiles = 'C'
        mol = from_smiles(Molecule(), smiles)
        self.assertTrue(mol.is_isomorphic(self.methane))

        # Test that atomtypes that rely on lone pairs for identity are typed correctly
        smiles = 'CN'
        mol = from_smiles(Molecule(), smiles)
        self.assertEquals(mol.atoms[1].atomtype, ATOMTYPES['N3s'])

        # Test N2
        adjlist = '''
        1 N u0 p1 c0 {2,T}
        2 N u0 p1 c0 {1,T}
        '''
        smiles = 'N#N'
        self.compare(adjlist, smiles)

        # Test CH4
        adjlist = '''
        1 C u0 p0 c0 {2,S} {3,S} {4,S} {5,S}
        2 H u0 p0 c0 {1,S}
        3 H u0 p0 c0 {1,S}
        4 H u0 p0 c0 {1,S}
        5 H u0 p0 c0 {1,S}
        '''
        smiles = 'C'
        self.compare(adjlist, smiles)

        # Test H2O
        adjlist = '''
        1 O u0 p2 c0 {2,S} {3,S}
        2 H u0 p0 c0 {1,S}
        3 H u0 p0 c0 {1,S}
        '''
        smiles = 'O'
        self.compare(adjlist, smiles)

        # Test C2H6
        adjlist = '''
        1 C u0 p0 c0 {2,S} {3,S} {4,S} {5,S}
        2 C u0 p0 c0 {1,S} {6,S} {7,S} {8,S}
        3 H u0 p0 c0 {1,S}
        4 H u0 p0 c0 {1,S}
        5 H u0 p0 c0 {1,S}
        6 H u0 p0 c0 {2,S}
        7 H u0 p0 c0 {2,S}
        8 H u0 p0 c0 {2,S}
        '''
        smiles = 'CC'
        self.compare(adjlist, smiles)

        # Test H2
        adjlist = '''
        1 H u0 p0 c0 {2,S}
        2 H u0 p0 c0 {1,S}
        '''
        smiles = '[H][H]'
        self.compare(adjlist, smiles)

        # Test H2O2
        adjlist = '''
        1 O u0 p2 c0 {2,S} {3,S}
        2 O u0 p2 c0 {1,S} {4,S}
        3 H u0 p0 c0 {1,S}
        4 H u0 p0 c0 {2,S}
        '''
        smiles = 'OO'
        self.compare(adjlist, smiles)

        # Test C3H8
        adjlist = '''
        1  C u0 p0 c0 {2,S} {4,S} {5,S} {6,S}
        2  C u0 p0 c0 {1,S} {3,S} {7,S} {8,S}
        3  C u0 p0 c0 {2,S} {9,S} {10,S} {11,S}
        4  H u0 p0 c0 {1,S}
        5  H u0 p0 c0 {1,S}
        6  H u0 p0 c0 {1,S}
        7  H u0 p0 c0 {2,S}
        8  H u0 p0 c0 {2,S}
        9  H u0 p0 c0 {3,S}
        10 H u0 p0 c0 {3,S}
        11 H u0 p0 c0 {3,S}
        '''
        smiles = 'CCC'
        self.compare(adjlist, smiles)

        # Test Ar
        adjlist = '''
        1 Ar u0 p4 c0
        '''
        smiles = '[Ar]'
        self.compare(adjlist, smiles)

        # Test He
        adjlist = '''
        1 He u0 p1 c0
        '''
        smiles = '[He]'
        self.compare(adjlist, smiles)

        # Test CH4O
        adjlist = '''
        1 C u0 p0 c0 {2,S} {3,S} {4,S} {5,S}
        2 O u0 p2 c0 {1,S} {6,S}
        3 H u0 p0 c0 {1,S}
        4 H u0 p0 c0 {1,S}
        5 H u0 p0 c0 {1,S}
        6 H u0 p0 c0 {2,S}
        '''
        smiles = 'CO'
        self.compare(adjlist, smiles)

        # Test CO2
        adjlist = '''
        1 O u0 p2 c0 {2,D}
        2 C u0 p0 c0 {1,D} {3,D}
        3 O u0 p2 c0 {2,D}
        '''
        smiles = 'O=C=O'
        self.compare(adjlist, smiles)

        # Test CO
        adjlist = '''
        1 C u0 p1 c-1 {2,T}
        2 O u0 p1 c+1 {1,T}
        '''
        smiles = '[C-]#[O+]'
        self.compare(adjlist, smiles)

        # Test C2H4
        adjlist = '''
        1 C u0 p0 c0 {2,D} {3,S} {4,S}
        2 C u0 p0 c0 {1,D} {5,S} {6,S}
        3 H u0 p0 c0 {1,S}
        4 H u0 p0 c0 {1,S}
        5 H u0 p0 c0 {2,S}
        6 H u0 p0 c0 {2,S}
        '''
        smiles = 'C=C'
        self.compare(adjlist, smiles)

        # Test O2
        adjlist = '''
        1 O u0 p2 c0 {2,D}
        2 O u0 p2 c0 {1,D}
        '''
        smiles = 'O=O'
        self.compare(adjlist, smiles)

        # Test CH3
        adjlist = '''
        multiplicity 2
        1 C u1 p0 c0 {2,S} {3,S} {4,S}
        2 H u0 p0 c0 {1,S}
        3 H u0 p0 c0 {1,S}
        4 H u0 p0 c0 {1,S}
        '''
        smiles = '[CH3]'
        self.compare(adjlist, smiles)

        # Test HO
        adjlist = '''
        multiplicity 2
        1 O u1 p2 c0 {2,S}
        2 H u0 p0 c0 {1,S}
        '''
        smiles = '[OH]'
        self.compare(adjlist, smiles)

        # Test C2H5
        adjlist = '''
        multiplicity 2
        1 C u0 p0 c0 {2,S} {5,S} {6,S} {7,S}
        2 C u1 p0 c0 {1,S} {3,S} {4,S}
        3 H u0 p0 c0 {2,S}
        4 H u0 p0 c0 {2,S}
        5 H u0 p0 c0 {1,S}
        6 H u0 p0 c0 {1,S}
        7 H u0 p0 c0 {1,S}
        '''
        smiles = 'C[CH2]'
        self.compare(adjlist, smiles)

        # Test O
        adjlist = '''
        multiplicity 3
        1 O u2 p2 c0
        '''
        smiles = '[O]'
        self.compare(adjlist, smiles)

        # Test HO2
        adjlist = '''
        multiplicity 2
        1 O u1 p2 c0 {2,S}
        2 O u0 p2 c0 {1,S} {3,S}
        3 H u0 p0 c0 {2,S}
        '''
        smiles = '[O]O'
        self.compare(adjlist, smiles)

        # Test CH, methylidyne.
        # Wikipedia reports:
        # The ground state is a doublet radical with one unpaired electron,
        # and the first two excited states are a quartet radical with three
        # unpaired electrons and a doublet radical with one unpaired electron.
        # With the quartet radical only 71 kJ above the ground state, a sample
        # of methylidyne exists as a mixture of electronic states even at
        # room temperature, giving rise to complex reactions.
        #
        adjlist = '''
        multiplicity 2
        1 C u1 p1 c0 {2,S}
        2 H u0 p0 c0 {1,S}
        '''
        smiles = '[CH]'
        self.compare(adjlist, smiles)

        # Test H
        adjlist = '''
        multiplicity 2
        1 H u1 p0 c0
        '''
        smiles = '[H]'
        self.compare(adjlist, smiles)

        # Test atomic C, which is triplet in ground state
        adjlist = '''
        multiplicity 3
        1 C u2 p1 c0
        '''
        smiles = '[C]'
        self.compare(adjlist, smiles)

        # Test O2
        adjlist = '''
        multiplicity 3
        1 O u1 p2 c0 {2,S}
        2 O u1 p2 c0 {1,S}
        '''
        smiles = '[O][O]'
        self.compare(adjlist, smiles)
Esempio n. 9
0
 def testAxisSymmetryNumberButatrienyl(self):
     """
     Test the Molecule.calculateAxisSymmetryNumber() on C=C=C=[CH]
     """
     molecule = Molecule().fromSMILES('C=C=C=[CH]')
     self.assertEqual(calculateAxisSymmetryNumber(molecule), 1)
Esempio n. 10
0
    def test_empty_molecule(self):
        """Test that we can safely return a blank identifier for an empty molecule."""
        mol = Molecule()

        self.assertEqual(mol.to_smiles(), '')
        self.assertEqual(mol.to_inchi(), '')
Esempio n. 11
0
    def test_aromatics(self):
        """Test that different aromatics representations returns different SMILES."""
        mol1 = Molecule().from_adjacency_list("""
1  O u0 p2 c0 {6,S} {9,S}
2  C u0 p0 c0 {3,D} {5,S} {11,S}
3  C u0 p0 c0 {2,D} {4,S} {12,S}
4  C u0 p0 c0 {3,S} {6,D} {13,S}
5  C u0 p0 c0 {2,S} {7,D} {10,S}
6  C u0 p0 c0 {1,S} {4,D} {7,S}
7  C u0 p0 c0 {5,D} {6,S} {8,S}
8  C u0 p0 c0 {7,S} {14,S} {15,S} {16,S}
9  H u0 p0 c0 {1,S}
10 H u0 p0 c0 {5,S}
11 H u0 p0 c0 {2,S}
12 H u0 p0 c0 {3,S}
13 H u0 p0 c0 {4,S}
14 H u0 p0 c0 {8,S}
15 H u0 p0 c0 {8,S}
16 H u0 p0 c0 {8,S}
""")
        mol2 = Molecule().from_adjacency_list("""
1  O u0 p2 c0 {6,S} {9,S}
2  C u0 p0 c0 {3,S} {5,D} {11,S}
3  C u0 p0 c0 {2,S} {4,D} {12,S}
4  C u0 p0 c0 {3,D} {6,S} {13,S}
5  C u0 p0 c0 {2,D} {7,S} {10,S}
6  C u0 p0 c0 {1,S} {4,S} {7,D}
7  C u0 p0 c0 {5,S} {6,D} {8,S}
8  C u0 p0 c0 {7,S} {14,S} {15,S} {16,S}
9  H u0 p0 c0 {1,S}
10 H u0 p0 c0 {5,S}
11 H u0 p0 c0 {2,S}
12 H u0 p0 c0 {3,S}
13 H u0 p0 c0 {4,S}
14 H u0 p0 c0 {8,S}
15 H u0 p0 c0 {8,S}
16 H u0 p0 c0 {8,S}
""")
        mol3 = Molecule().from_adjacency_list("""
1  O u0 p2 c0 {6,S} {9,S}
2  C u0 p0 c0 {3,B} {5,B} {11,S}
3  C u0 p0 c0 {2,B} {4,B} {12,S}
4  C u0 p0 c0 {3,B} {6,B} {13,S}
5  C u0 p0 c0 {2,B} {7,B} {10,S}
6  C u0 p0 c0 {1,S} {4,B} {7,B}
7  C u0 p0 c0 {5,B} {6,B} {8,S}
8  C u0 p0 c0 {7,S} {14,S} {15,S} {16,S}
9  H u0 p0 c0 {1,S}
10 H u0 p0 c0 {5,S}
11 H u0 p0 c0 {2,S}
12 H u0 p0 c0 {3,S}
13 H u0 p0 c0 {4,S}
14 H u0 p0 c0 {8,S}
15 H u0 p0 c0 {8,S}
16 H u0 p0 c0 {8,S}
""")

        smiles1 = mol1.to_smiles()
        smiles2 = mol2.to_smiles()
        smiles3 = mol3.to_smiles()

        self.assertNotEqual(smiles1, smiles2)
        self.assertNotEqual(smiles2, smiles3)
        self.assertNotEqual(smiles1, smiles3)
Esempio n. 12
0
 def compare(self, adjlist, smiles):
     mol = Molecule().from_adjacency_list(adjlist)
     self.assertEquals(smiles, mol.to_smiles())
Esempio n. 13
0
    def verify_output_file(self):
        """
        Check's that an output file exists and was successful.
        
        Returns a boolean flag that states whether a successful GAUSSIAN simulation already exists for the molecule with the 
        given (augmented) InChI Key.
        
        The definition of finding a successful simulation is based on these criteria:
        1) finding an output file with the file name equal to the InChI Key
        2) NOT finding any of the keywords that are denote a calculation failure
        3) finding all the keywords that denote a calculation success.
        4) finding a match between the InChI of the given molecule and the InchI found in the calculation files
        5) checking that the optimized geometry, when connected by single bonds, is isomorphic with self.molecule (converted to single bonds)

        If any of the above criteria is not matched, False will be returned.
        If all are satisfied, it will return True.
        """
        if not os.path.exists(self.output_file_path):
            logging.info("Output file {0} does not exist.".format(self.output_file_path))
            return False

        inchi_match = False  # flag (1 or 0) indicating whether the InChI in the file matches InChIaug this can only be 1 if inchi_found is also 1
        inchi_found = False  # flag (1 or 0) indicating whether an InChI was found in the log file

        # Initialize dictionary with "False"s 
        success_keys_found = dict([(key, False) for key in self.successKeys])

        with open(self.output_file_path) as outputFile:
            for line in outputFile:
                line = line.strip()

                for element in self.failureKeys:  # search for failure keywords
                    if element in line:
                        logging.error("Gaussian output file contains the following error: {0}".format(element))
                        return False

                for element in self.successKeys:  # search for success keywords
                    if element in line:
                        success_keys_found[element] = True

                if line.startswith("InChI="):
                    log_file_inchi = line  # output files should take up to 240 characters of the name in the input file
                    inchi_found = True
                    if self.unique_id_long in log_file_inchi:
                        inchi_match = True
                    elif self.unique_id_long.startswith(log_file_inchi):
                        logging.info("InChI too long to check, but beginning matches so assuming OK.")
                        inchi_match = True
                    else:
                        logging.warning("InChI in log file ({0}) didn't match that in geometry "
                                        "({1}).".format(log_file_inchi, self.geometry.unique_id_long))
                        if self.geometry.unique_id_long.startswith(log_file_inchi):
                            logging.warning("but the beginning matches so it's probably just a truncation problem.")
                            inchi_match = True
        # Check that ALL 'success' keywords were found in the file.
        if not all(success_keys_found.values()):
            logging.error('Not all of the required keywords for success were found in the output file!')
            return False

        if not inchi_found:
            logging.error("No InChI was found in the Gaussian output file {0}".format(self.output_file_path))
            return False

        if not inchi_match:
            # InChIs do not match (most likely due to limited name length mirrored in log file (240 characters), but possibly due to a collision)
            return self.checkForInChiKeyCollision(log_file_inchi)  # Not yet implemented!

        # Compare the optimized geometry to the original molecule
        qm_data = self.parse()
        cclib_mol = Molecule()
        cclib_mol.from_xyz(qm_data.atomicNumbers, qm_data.atomCoords.value)
        test_mol = self.molecule.to_single_bonds()
        if not cclib_mol.is_isomorphic(test_mol):
            logging.info("Incorrect connectivity for optimized geometry in file {0}".format(self.output_file_path))
            return False

        logging.info("Successful {1} quantum result in {0}".format(self.output_file_path, self.__class__.__name__))
        return True
#image = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data', 'hough_test', 'Test_Set_1', 'PNGs',
#                     'C(C)C(CCCC)(C)C.png')

#image = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data', 'hough_test', 'Test_Set_1', 'PNGs',
#                    'C(C)(CC)(CC)CCCCC.png')
#image = os.path.join(os.path.dirname(os.path.dirname(__file__)),'data','hough_test','short test set','C(C)(CC)(CC)CCCCC.png')
#image = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data', 'hough_test','square.jpg' )
#image = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data', 'hough_test', 'Test_Set_1','double_bonds', 'C((CCC)CC)C.png')
image = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data',
                     'hand_drawn', 'CC=CC(CC)C.png')

bname = os.path.basename(os.path.normpath(image))

smiles = bname.split('.')[0]
print smiles
m = Molecule().fromSMILES(str(smiles))

image = imread(image, as_grey=True)
thresh = threshold_otsu(image)
image = image > thresh
image = np.invert(image)
plt.imshow(image, cmap=plt.gray())
lines = get_hough_lines(image)
plotLines(lines)

#    min_dist_merge = params[0]
#    min_angle_merge = params[1]
#    min_width_merge = params[2]
#    split_tol = params[3]
#    min_dist_bond = params[4]
#    max_dist_bond = params[5]
Esempio n. 15
0
 def setUp(self):
     self.vf2 = VF2()
     self.mol = Molecule().from_smiles("CC(=O)C[CH2]")
     self.mol2 = self.mol.copy(deep=True)
Esempio n. 16
0
 def testAxisSymmetryNumber12Hexadienyl(self):
     """
     Test the Molecule.calculateAxisSymmetryNumber() on C=C=CCCC
     """
     molecule = Molecule().fromSMILES('C=C=CCCC')
     self.assertEqual(calculateAxisSymmetryNumber(molecule), 1)
Esempio n. 17
0
    def test_molecules_from_xyz(self):
        """Tests that atom orders are preserved when converting xyz's into RMG Molecules"""
        s_mol, b_mol = converter.molecules_from_xyz(self.xyz4)

        # check that the atom order is the same
        self.assertTrue(s_mol.atoms[0].isSulfur())
        self.assertTrue(b_mol.atoms[0].isSulfur())
        self.assertTrue(s_mol.atoms[1].isOxygen())
        self.assertTrue(b_mol.atoms[1].isOxygen())
        self.assertTrue(s_mol.atoms[2].isOxygen())
        self.assertTrue(b_mol.atoms[2].isOxygen())
        self.assertTrue(s_mol.atoms[3].isNitrogen())
        self.assertTrue(b_mol.atoms[3].isNitrogen())
        self.assertTrue(s_mol.atoms[4].isCarbon())
        self.assertTrue(b_mol.atoms[4].isCarbon())
        self.assertTrue(s_mol.atoms[5].isHydrogen())
        self.assertTrue(b_mol.atoms[5].isHydrogen())
        self.assertTrue(s_mol.atoms[6].isHydrogen())
        self.assertTrue(b_mol.atoms[6].isHydrogen())
        self.assertTrue(s_mol.atoms[7].isHydrogen())
        self.assertTrue(b_mol.atoms[7].isHydrogen())
        self.assertTrue(s_mol.atoms[8].isHydrogen())
        self.assertTrue(b_mol.atoms[8].isHydrogen())
        self.assertTrue(s_mol.atoms[9].isHydrogen())
        self.assertTrue(b_mol.atoms[9].isHydrogen())

        s_mol, b_mol = converter.molecules_from_xyz(self.xyz5)
        self.assertTrue(s_mol.atoms[0].isOxygen())
        self.assertTrue(b_mol.atoms[0].isOxygen())
        self.assertTrue(s_mol.atoms[2].isCarbon())
        self.assertTrue(b_mol.atoms[2].isCarbon())

        expected_bonded_adjlist = """multiplicity 2
1  O u0 p2 c0 {6,S} {10,S}
2  O u0 p2 c0 {3,S} {28,S}
3  C u0 p0 c0 {2,S} {8,S} {14,S} {15,S}
4  C u0 p0 c0 {7,S} {16,S} {17,S} {18,S}
5  C u0 p0 c0 {7,S} {19,S} {20,S} {21,S}
6  C u0 p0 c0 {1,S} {22,S} {23,S} {24,S}
7  C u1 p0 c0 {4,S} {5,S} {9,S}
8  C u0 p0 c0 {3,S} {10,D} {11,S}
9  C u0 p0 c0 {7,S} {11,D} {12,S}
10 C u0 p0 c0 {1,S} {8,D} {13,S}
11 C u0 p0 c0 {8,S} {9,D} {25,S}
12 C u0 p0 c0 {9,S} {13,D} {26,S}
13 C u0 p0 c0 {10,S} {12,D} {27,S}
14 H u0 p0 c0 {3,S}
15 H u0 p0 c0 {3,S}
16 H u0 p0 c0 {4,S}
17 H u0 p0 c0 {4,S}
18 H u0 p0 c0 {4,S}
19 H u0 p0 c0 {5,S}
20 H u0 p0 c0 {5,S}
21 H u0 p0 c0 {5,S}
22 H u0 p0 c0 {6,S}
23 H u0 p0 c0 {6,S}
24 H u0 p0 c0 {6,S}
25 H u0 p0 c0 {11,S}
26 H u0 p0 c0 {12,S}
27 H u0 p0 c0 {13,S}
28 H u0 p0 c0 {2,S}
"""
        expected_mol = Molecule().fromAdjacencyList(
            str(expected_bonded_adjlist))
        self.assertEqual(b_mol.toAdjacencyList(), expected_bonded_adjlist)
        # the isIsomorphic test must come after the adjlist test since it changes the atom order
        self.assertTrue(b_mol.isIsomorphic(expected_mol))
Esempio n. 18
0
 def testAxisSymmetryNumber1(self):
     """
     Test the Molecule.calculateAxisSymmetryNumber() on CC(C)=C=C(CC)CC
     """
     molecule = Molecule().fromSMILES('CC(C)=C=C(CC)CC')
     self.assertEqual(calculateAxisSymmetryNumber(molecule), 2)
Esempio n. 19
0
 def test_axis_symmetry_number_12_hexadienyl(self):
     """
     Test the Molecule.calculate_axis_symmetry_number() on C=C=CCCC
     """
     molecule = Molecule().from_smiles('C=C=CCCC')
     self.assertEqual(calculate_axis_symmetry_number(molecule), 1)
Esempio n. 20
0
 def testAxisSymmetryNumber3(self):
     """
     Test the Molecule.calculateAxisSymmetryNumber() on C=C=[C]C(C)(C)[C]=C=C
     """
     molecule = Molecule().fromSMILES('C=C=[C]C(C)(C)[C]=C=C')
     self.assertEqual(calculateAxisSymmetryNumber(molecule), 4)
Esempio n. 21
0
 def test_axis_symmetry_number3(self):
     """
     Test the Molecule.calculate_axis_symmetry_number() on C=C=[C]C(C)(C)[C]=C=C
     """
     molecule = Molecule().from_smiles('C=C=[C]C(C)(C)[C]=C=C')
     self.assertEqual(calculate_axis_symmetry_number(molecule), 4)
Esempio n. 22
0
 def testAxisSymmetryNumber5(self):
     """
     Test the Molecule.calculateAxisSymmetryNumber() on CC=C=C=O
     """
     molecule = Molecule().fromSMILES('CC=C=C=O')
     self.assertEqual(calculateAxisSymmetryNumber(molecule), 1)
Esempio n. 23
0
 def test_axis_symmetry_oxygen_singlet(self):
     """
     Test the Molecule.calculate_axis_symmetry_number() on O=O
     """
     molecule = Molecule().from_smiles('O=O')
     self.assertEqual(calculate_axis_symmetry_number(molecule), 1)
Esempio n. 24
0
 def testAxisSymmetryNumber7(self):
     """
     Test the Molecule.calculateAxisSymmetryNumber() on C=C=C=[N]
     """
     molecule = Molecule().fromSMILES('C=C=C=[N]')
     self.assertEqual(calculateAxisSymmetryNumber(molecule), 2)
Esempio n. 25
0
    def saveForm(self, posted, form):
        """
        Save form data into input.py file specified by the path.
        """
        # Clean past history
        self.rmg = RMG()

        # Databases
        #self.rmg.databaseDirectory = settings['database.directory']
        self.rmg.thermoLibraries = []
        if posted.thermo_libraries.all():
            self.rmg.thermoLibraries = [
                item.thermolib.encode()
                for item in posted.thermo_libraries.all()
            ]
        self.rmg.reactionLibraries = []
        self.rmg.seedMechanisms = []
        if posted.reaction_libraries.all():
            for item in posted.reaction_libraries.all():
                if not item.seedmech and not item.edge:
                    self.rmg.reactionLibraries.append(
                        (item.reactionlib.encode(), False))
                elif not item.seedmech:
                    self.rmg.reactionLibraries.append(
                        (item.reactionlib.encode(), True))
                else:
                    self.rmg.seedMechanisms.append(item.reactionlib.encode())
        self.rmg.statmechLibraries = []
        self.rmg.kineticsDepositories = 'default'
        self.rmg.kineticsFamilies = 'default'
        self.rmg.kineticsEstimator = 'rate rules'

        # Species
        self.rmg.initialSpecies = []
        speciesDict = {}
        initialMoleFractions = {}
        self.rmg.reactionModel = CoreEdgeReactionModel()
        for item in posted.reactor_species.all():
            structure = Molecule().fromAdjacencyList(item.adjlist.encode())
            spec, isNew = self.rmg.reactionModel.makeNewSpecies(
                structure,
                label=item.name.encode(),
                reactive=False if item.inert else True)
            self.rmg.initialSpecies.append(spec)
            speciesDict[item.name.encode()] = spec
            initialMoleFractions[spec] = item.molefrac

        # Reactor systems
        self.rmg.reactionSystems = []
        for item in posted.reactor_systems.all():
            T = Quantity(item.temperature, item.temperature_units.encode())
            P = Quantity(item.pressure, item.pressure_units.encode())
            termination = []
            if item.conversion:
                termination.append(
                    TerminationConversion(speciesDict[item.species.encode()],
                                          item.conversion))
            termination.append(
                TerminationTime(
                    Quantity(item.terminationtime, item.time_units.encode())))
            # Sensitivity Analysis
            sensitiveSpecies = []
            if item.sensitivity:
                if isinstance(item.sensitivity.encode(), str):
                    sensitivity = item.sensitivity.encode().split(',').strip()
                for spec in sensitivity:
                    sensitiveSpecies.append(speciesDict[spec])
            system = SimpleReactor(T, P, initialMoleFractions, termination,
                                   sensitiveSpecies, item.sensitivityThreshold)
            self.rmg.reactionSystems.append(system)

        # Simulator tolerances
        self.rmg.absoluteTolerance = form.cleaned_data['simulator_atol']
        self.rmg.relativeTolerance = form.cleaned_data['simulator_rtol']
        self.rmg.sensitivityAbsoluteTolerance = form.cleaned_data[
            'simulator_sens_atol']
        self.rmg.sensitivityRelativeTolerance = form.cleaned_data[
            'simulator_sens_rtol']
        self.rmg.fluxToleranceKeepInEdge = form.cleaned_data[
            'toleranceKeepInEdge']
        self.rmg.fluxToleranceMoveToCore = form.cleaned_data[
            'toleranceMoveToCore']
        self.rmg.fluxToleranceInterrupt = form.cleaned_data[
            'toleranceInterruptSimulation']
        self.rmg.maximumEdgeSpecies = form.cleaned_data['maximumEdgeSpecies']
        self.rmg.minCoreSizeForPrune = form.cleaned_data['minCoreSizeForPrune']
        self.rmg.minSpeciesExistIterationsForPrune = form.cleaned_data[
            'minSpeciesExistIterationsForPrune']
        self.rmg.filterReactions = form.cleaned_data['filterReactions']

        # Pressure Dependence
        pdep = form.cleaned_data['pdep'].encode()
        if pdep != 'off':
            self.rmg.pressureDependence = PressureDependenceJob(network=None)
            self.rmg.pressureDependence.method = pdep

            # Process interpolation model
            if form.cleaned_data['interpolation'].encode() == 'chebyshev':
                self.rmg.pressureDependence.interpolationModel = (
                    form.cleaned_data['interpolation'].encode(),
                    form.cleaned_data['temp_basis'],
                    form.cleaned_data['p_basis'])
            else:
                self.rmg.pressureDependence.interpolationModel = (
                    form.cleaned_data['interpolation'].encode(), )

            # Temperature and pressure range
            self.rmg.pressureDependence.Tmin = Quantity(
                form.cleaned_data['temp_low'],
                form.cleaned_data['temprange_units'].encode())
            self.rmg.pressureDependence.Tmax = Quantity(
                form.cleaned_data['temp_high'],
                form.cleaned_data['temprange_units'].encode())
            self.rmg.pressureDependence.Tcount = form.cleaned_data[
                'temp_interp']
            self.rmg.pressureDependence.generateTemperatureList()
            self.rmg.pressureDependence.Pmin = Quantity(
                form.cleaned_data['p_low'],
                form.cleaned_data['prange_units'].encode())
            self.rmg.pressureDependence.Pmax = Quantity(
                form.cleaned_data['p_high'],
                form.cleaned_data['prange_units'].encode())
            self.rmg.pressureDependence.Pcount = form.cleaned_data['p_interp']
            self.rmg.pressureDependence.generatePressureList()

            # Process grain size and count
            self.rmg.pressureDependence.grainSize = Quantity(
                form.cleaned_data['maximumGrainSize'],
                form.cleaned_data['grainsize_units'].encode())
            self.rmg.pressureDependence.grainCount = form.cleaned_data[
                'minimumNumberOfGrains']

            self.rmg.pressureDependence.maximumAtoms = form.cleaned_data[
                'maximumAtoms']
        # Additional Options
        self.rmg.units = 'si'
        self.rmg.saveRestartPeriod = Quantity(
            form.cleaned_data['saveRestartPeriod'],
            form.cleaned_data['saveRestartPeriodUnits'].encode(
            )) if form.cleaned_data['saveRestartPeriod'] else None
        self.rmg.generateOutputHTML = form.cleaned_data['generateOutputHTML']
        self.rmg.generatePlots = form.cleaned_data['generatePlots']
        self.rmg.saveSimulationProfiles = form.cleaned_data[
            'saveSimulationProfiles']
        self.rmg.saveEdgeSpecies = form.cleaned_data['saveEdgeSpecies']
        self.rmg.verboseComments = form.cleaned_data['verboseComments']

        # Species Constraints
        speciesConstraints = form.cleaned_data['speciesConstraints']
        if speciesConstraints == 'on':
            allowed = []
            if form.cleaned_data['allowed_inputSpecies']:
                allowed.append('input species')
            if form.cleaned_data['allowed_seedMechanisms']:
                allowed.append('seed mechanisms')
            if form.cleaned_data['allowed_reactionLibraries']:
                allowed.append('reaction libraries')
            self.rmg.speciesConstraints['allowed'] = allowed
            self.rmg.speciesConstraints[
                'maximumCarbonAtoms'] = form.cleaned_data['maximumCarbonAtoms']
            self.rmg.speciesConstraints[
                'maximumOxygenAtoms'] = form.cleaned_data['maximumOxygenAtoms']
            self.rmg.speciesConstraints[
                'maximumNitrogenAtoms'] = form.cleaned_data[
                    'maximumNitrogenAtoms']
            self.rmg.speciesConstraints[
                'maximumSiliconAtoms'] = form.cleaned_data[
                    'maximumSiliconAtoms']
            self.rmg.speciesConstraints[
                'maximumSulfurAtoms'] = form.cleaned_data['maximumSulfurAtoms']
            self.rmg.speciesConstraints[
                'maximumHeavyAtoms'] = form.cleaned_data['maximumHeavyAtoms']
            self.rmg.speciesConstraints[
                'maximumRadicalElectrons'] = form.cleaned_data[
                    'maximumRadicalElectrons']
            self.rmg.speciesConstraints['allowSingletO2'] = form.cleaned_data[
                'allowSingletO2']

        # Quantum Calculations
        quantumCalc = form.cleaned_data['quantumCalc']
        if quantumCalc == 'on':
            from rmgpy.qm.main import QMCalculator
            self.rmg.quantumMechanics = QMCalculator(
                software=form.cleaned_data['software'].encode(),
                method=form.cleaned_data['method'].encode(),
                fileStore=form.cleaned_data['fileStore'].encode(),
                scratchDirectory=form.cleaned_data['scratchDirectory'].encode(
                ),
                onlyCyclics=form.cleaned_data['onlyCyclics'],
                maxRadicalNumber=form.cleaned_data['maxRadicalNumber'],
            )

        # Save the input.py file
        self.rmg.saveInput(self.savepath)
Esempio n. 26
0
 def testAxisSymmetryOxygenSinglet(self):
     """
     Test the Molecule.calculateAxisSymmetryNumber() on O=O
     """
     molecule = Molecule().fromSMILES('O=O')
     self.assertEqual(calculateAxisSymmetryNumber(molecule), 1)
Esempio n. 27
0
    def test_incorrect_identifier_type(self):
        """Test that the appropriate error is raised for identifier/type mismatch."""
        with self.assertRaises(ValueError) as cm:
            Molecule().from_smiles('InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H')

        self.assertTrue('Improper identifier type' in str(cm.exception))
Esempio n. 28
0
    def get_resonance_hybrid(self):
        """
        Returns a molecule object with bond orders that are the average 
        of all the resonance structures.
        """
        # get labeled resonance isomers
        self.generate_resonance_structures(keep_isomorphic=True)

        # only consider reactive molecules as representative structures
        molecules = [mol for mol in self.molecule if mol.reactive]

        # return if no resonance
        if len(molecules) == 1:
            return molecules[0]

        # create a sorted list of atom objects for each resonance structure
        cython.declare(
            atomsFromStructures=list,
            oldAtoms=list,
            newAtoms=list,
            numResonanceStructures=cython.short,
            structureNum=cython.short,
            oldBondOrder=cython.float,
            index1=cython.short,
            index2=cython.short,
            newMol=Molecule,
            oldMol=Molecule,
            atom1=Atom,
            atom2=Atom,
            bond=Bond,
            atoms=list,
        )

        atoms_from_structures = []
        for new_mol in molecules:
            new_mol.atoms.sort(key=lambda atom: atom.id)
            atoms_from_structures.append(new_mol.atoms)

        num_resonance_structures = len(molecules)

        # make original structure with no bonds
        new_mol = Molecule()
        original_atoms = atoms_from_structures[0]
        for atom1 in original_atoms:
            atom = new_mol.add_atom(Atom(atom1.element))
            atom.id = atom1.id

        new_atoms = new_mol.atoms

        # initialize bonds to zero order
        for index1, atom1 in enumerate(original_atoms):
            for atom2 in atom1.bonds:
                index2 = original_atoms.index(atom2)
                bond = Bond(new_atoms[index1], new_atoms[index2], 0)
                new_mol.add_bond(bond)

        # set bonds to the proper value
        for structureNum, oldMol in enumerate(molecules):
            old_atoms = atoms_from_structures[structureNum]

            for index1, atom1 in enumerate(old_atoms):
                # make bond orders average of resonance structures
                for atom2 in atom1.bonds:
                    index2 = old_atoms.index(atom2)

                    new_bond = new_mol.get_bond(new_atoms[index1],
                                                new_atoms[index2])
                    old_bond_order = oldMol.get_bond(
                        old_atoms[index1], old_atoms[index2]).get_order_num()
                    new_bond.apply_action(
                        ('CHANGE_BOND', None,
                         old_bond_order / num_resonance_structures / 2))
                # set radicals in resonance hybrid to maximum of all structures
                if atom1.radical_electrons > 0:
                    new_atoms[index1].radical_electrons = max(
                        atom1.radical_electrons,
                        new_atoms[index1].radical_electrons)
        new_mol.update_atomtypes(log_species=False, raise_exception=False)
        return new_mol
Esempio n. 29
0
    def test_isotopic_molecule_1(self):
        """Test that we can parse an InChI for an isotopic molecule."""
        mol = Molecule().from_inchi('InChI=1S/CH4/h1H4/i1+1')

        self.assertTrue(len(mol.atoms), 4)
        self.assertEqual([atom.element.isotope for atom in mol.atoms].count(13), 1)
Esempio n. 30
0
    def testaddReverseAttribute(self):
        """
        tests that the addReverseAttribute method gets the reverse degeneracy correct
        """
        from rmgpy.data.rmg import getDB
        from rmgpy.data.kinetics.family import TemplateReaction
        adjlist = [
            '''
        multiplicity 2
        1 H u0 p0 c0 {7,S}
        2 H u0 p0 c0 {4,S}
        3 C u1 p0 c0 {5,S} {7,S} {8,S}
        4 C u0 p0 c0 {2,S} {6,S} {7,D}
        5 H u0 p0 c0 {3,S}
        6 H u0 p0 c0 {4,S}
        7 C u0 p0 c0 {1,S} {3,S} {4,D}
        8 H u0 p0 c0 {3,S}
        ''', '''
        1 C u0 p0 c0 {2,S} {4,S} {5,S} {6,S}
        2 C u0 p0 c0 i13 {1,S} {3,D} {7,S}
        3 C u0 p0 c0 {2,D} {8,S} {9,S}
        4 H u0 p0 c0 {1,S}
        5 H u0 p0 c0 {1,S}
        6 H u0 p0 c0 {1,S}
        7 H u0 p0 c0 {2,S}
        8 H u0 p0 c0 {3,S}
        9 H u0 p0 c0 {3,S}
        ''', '''
        multiplicity 2
        1 H u0 p0 c0 {7,S}
        2 H u0 p0 c0 {4,S}
        3 C u1 p0 c0 {5,S} {7,S} {8,S}
        4 C u0 p0 c0 {2,S} {6,S} {7,D}
        5 H u0 p0 c0 {3,S}
        6 H u0 p0 c0 {4,S}
        7 C u0 p0 c0 i13 {1,S} {3,S} {4,D}
        8 H u0 p0 c0 {3,S}
        ''', '''
        1 C u0 p0 c0 {2,S} {4,S} {5,S} {6,S}
        2 C u0 p0 c0 {1,S} {3,D} {7,S}
        3 C u0 p0 c0 {2,D} {8,S} {9,S}
        4 H u0 p0 c0 {1,S}
        5 H u0 p0 c0 {1,S}
        6 H u0 p0 c0 {1,S}
        7 H u0 p0 c0 {2,S}
        8 H u0 p0 c0 {3,S}
        9 H u0 p0 c0 {3,S}
        '''
        ]
        family = getDB('kinetics').families['H_Abstraction']
        r1 = Species(molecule=[Molecule().fromAdjacencyList(adjlist[0])])
        r2 = Species(molecule=[Molecule().fromAdjacencyList(adjlist[1])])
        p1 = Species(molecule=[Molecule().fromAdjacencyList(adjlist[2])])
        p2 = Species(molecule=[Molecule().fromAdjacencyList(adjlist[3])])
        r1.generateResonanceIsomers(keepIsomorphic=True)
        p1.generateResonanceIsomers(keepIsomorphic=True)

        rxn = TemplateReaction(reactants=[r1, r2], products=[p1, p2])

        rxn.degeneracy = family.calculateDegeneracy(rxn)
        self.assertEqual(rxn.degeneracy, 6)

        family.addReverseAttribute(rxn)

        self.assertEqual(rxn.reverse.degeneracy, 6)