Esempio n. 1
0
class TestSpecies(unittest.TestCase):
    """
    Contains unit tests for the Species class.
    """
    def setUp(self):
        """
        A method that is run before each unit test in this class.
        """
        self.species = Species(
            index=1,
            label='C2H4',
            thermo=ThermoData(
                Tdata=([300.0, 400.0, 500.0, 600.0, 800.0, 1000.0,
                        1500.0], 'K'),
                Cpdata=([3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 15.0], 'cal/(mol*K)'),
                H298=(-20.0, 'kcal/mol'),
                S298=(50.0, 'cal/(mol*K)'),
                Tmin=(300.0, 'K'),
                Tmax=(2000.0, 'K'),
            ),
            conformer=Conformer(
                E0=(0.0, 'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(28.03, 'amu')),
                    NonlinearRotor(
                        inertia=([5.6952e-47, 2.7758e-46,
                                  3.3454e-46], 'kg*m^2'),
                        symmetry=1),
                    HarmonicOscillator(frequencies=([
                        834.50, 973.31, 975.37, 1067.1, 1238.5, 1379.5, 1472.3,
                        1691.3, 3121.6, 3136.7, 3192.5, 3221.0
                    ], 'cm^-1')),
                ],
                spin_multiplicity=1,
                optical_isomers=1,
            ),
            molecule=[Molecule().from_smiles('C=C')],
            transport_data=TransportData(sigma=(1, 'angstrom'),
                                         epsilon=(100, 'K')),
            molecular_weight=(28.03, 'amu'),
            reactive=True,
        )

        self.species2 = Species().from_adjacency_list("""
            1  C u0 p0 c0 {2,D} {6,S} {7,S}
            2  C u0 p0 c0 {1,D} {3,S} {8,S}
            3  C u0 p0 c0 {2,S} {4,D} {9,S}
            4  C u0 p0 c0 {3,D} {5,S} {10,S}
            5  C u0 p0 c0 {4,S} {6,D} {11,S}
            6  C u0 p0 c0 {1,S} {5,D} {12,S}
            7  H u0 p0 c0 {1,S}
            8  H u0 p0 c0 {2,S}
            9  H u0 p0 c0 {3,S}
            10 H u0 p0 c0 {4,S}
            11 H u0 p0 c0 {5,S}
            12 H u0 p0 c0 {6,S}
            """)

    def test_pickle(self):
        """
        Test that a Species object can be pickled and unpickled.
        
        ...with no loss of information.
        """
        import pickle
        species = pickle.loads(pickle.dumps(self.species, -1))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity,
                         species.molecule[0].multiplicity)
        self.assertEqual(self.species.get_thermo_data().H298.value_si,
                         species.get_thermo_data().H298.value_si)
        self.assertEqual(self.species.get_thermo_data().H298.units,
                         species.get_thermo_data().H298.units)
        self.assertEqual(len(self.species.conformer.modes),
                         len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].is_isomorphic(
            species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si,
                         species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units,
                         species.conformer.E0.units)
        self.assertEqual(self.species.transport_data.sigma.value_si,
                         species.transport_data.sigma.value_si)
        self.assertEqual(self.species.transport_data.sigma.units,
                         species.transport_data.sigma.units)
        self.assertAlmostEqual(
            self.species.transport_data.epsilon.value_si / 1.381e-23,
            species.transport_data.epsilon.value_si / 1.381e-23, 4)
        self.assertEqual(self.species.transport_data.epsilon.units,
                         species.transport_data.epsilon.units)
        self.assertEqual(self.species.molecular_weight.value_si,
                         species.molecular_weight.value_si)
        self.assertEqual(self.species.molecular_weight.units,
                         species.molecular_weight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def test_output(self):
        """
        Test that a Species object can be reconstructed from its repr().
        
        ...with no loss of information.
        """
        namespace = {}
        exec('species = {0!r}'.format(self.species), globals(), namespace)
        self.assertIn('species', namespace)
        species = namespace['species']
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity,
                         species.molecule[0].multiplicity)
        self.assertEqual(self.species.get_thermo_data().H298.value_si,
                         species.get_thermo_data().H298.value_si)
        self.assertEqual(self.species.get_thermo_data().H298.units,
                         species.get_thermo_data().H298.units)
        self.assertEqual(len(self.species.conformer.modes),
                         len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].is_isomorphic(
            species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si,
                         species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units,
                         species.conformer.E0.units)
        self.assertEqual(self.species.transport_data.sigma.value_si,
                         species.transport_data.sigma.value_si)
        self.assertEqual(self.species.transport_data.sigma.units,
                         species.transport_data.sigma.units)
        self.assertAlmostEqual(self.species.transport_data.epsilon.value_si,
                               species.transport_data.epsilon.value_si, 3)
        self.assertEqual(self.species.transport_data.epsilon.units,
                         species.transport_data.epsilon.units)
        self.assertEqual(self.species.molecular_weight.value_si,
                         species.molecular_weight.value_si)
        self.assertEqual(self.species.molecular_weight.units,
                         species.molecular_weight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def test_equality(self):
        """Test that we can perform equality comparison with Species objects"""
        spc1 = Species(smiles='C')
        spc2 = Species(smiles='C')

        self.assertNotEqual(spc1, spc2)
        self.assertEqual(spc1, spc1)
        self.assertEqual(spc2, spc2)

    def test_less_than(self):
        """Test that we can perform less than comparison with Species objects"""
        spc1 = Species(index=1, label='a', smiles='C')
        spc2 = Species(index=2, label='a', smiles='C')
        spc3 = Species(index=2, label='b', smiles='C')
        spc4 = Species(index=1, label='a', smiles='CC')

        self.assertLess(spc1, spc2)
        self.assertLess(spc1, spc3)
        self.assertLess(spc2, spc3)
        self.assertLess(spc1, spc4)
        self.assertLess(spc2, spc4)
        self.assertLess(spc3, spc4)

    def test_greater_than(self):
        """Test that we can perform greater than comparison with Species objects"""
        spc1 = Species(index=1, label='a', smiles='C')
        spc2 = Species(index=2, label='a', smiles='C')
        spc3 = Species(index=2, label='b', smiles='C')
        spc4 = Species(index=1, label='a', smiles='CC')

        self.assertGreater(spc2, spc1)
        self.assertGreater(spc3, spc1)
        self.assertGreater(spc3, spc2)
        self.assertGreater(spc4, spc1)
        self.assertGreater(spc4, spc2)
        self.assertGreater(spc4, spc3)

    def test_hash(self):
        """Test behavior of Species hashing using dictionaries and sets"""
        spc1 = Species(index=1, label='a', smiles='C')
        spc2 = Species(index=2, label='a', smiles='C')
        spc3 = Species(index=2, label='b', smiles='C')
        spc4 = Species(index=1, label='a', smiles='CC')

        # Test dictionary behavior
        self.assertEqual(len(dict.fromkeys([spc1, spc2, spc3, spc4])), 4)

        # Test set behavior
        self.assertEqual(len({spc1, spc2, spc3, spc4}), 4)

    def test_to_adjacency_list(self):
        """
        Test that to_adjacency_list() works as expected.
        """
        string = self.species.to_adjacency_list()
        self.assertTrue(
            string.startswith(self.species.molecule[0].to_adjacency_list(
                label=self.species.label, remove_h=False)), string)

    def test_species_props(self):
        """
        Test a key-value pair is added to the props attribute of Species.
        """
        self.species.props['foo'] = 'bar'
        self.assertIsInstance(self.species.props, dict)
        self.assertEquals(self.species.props['foo'], 'bar')

    def test_species_props_object_attribute(self):
        """
        Test that Species's props dictionaries are independent of each other.
        
        Create a test in which is checked whether props is an object attribute rather
        than a class attribute
        """
        spc2 = Species()
        self.species.props['foo'] = 'bar'
        spc3 = Species()
        spc3.props['foo'] = 'bla'
        self.assertEquals(self.species.props['foo'], 'bar')
        self.assertDictEqual(spc2.props, {})
        self.assertDictEqual(spc3.props, {'foo': 'bla'})

    def test_resonance_isomers_generated(self):
        """Test that 1-penten-3-yl makes 2-penten-1-yl resonance isomer"""
        spec = Species().from_smiles('C=C[CH]CC')
        spec.generate_resonance_structures()
        self.assertEquals(len(spec.molecule), 2)
        self.assertEquals(spec.molecule[1].to_smiles(), "[CH2]C=CCC")

    def test_resonace_isomers_represented(self):
        """Test that both resonance forms of 1-penten-3-yl are printed by __repr__"""
        spec = Species().from_smiles('C=C[CH]CC')
        spec.generate_resonance_structures()
        namespace = {}
        exec('spec2 = {0!r}'.format(spec), globals(), namespace)
        self.assertIn('spec2', namespace)
        spec2 = namespace['spec2']
        self.assertEqual(len(spec.molecule), len(spec2.molecule))
        for i, j in zip(spec.molecule, spec2.molecule):
            self.assertTrue(
                j.is_isomorphic(i),
                msg='i is not isomorphic with j, where i is {} and j is {}'.
                format(i.to_smiles(), j.to_smiles()))

    def test_is_isomorphic_to_filtered_resonance_structure(self):
        """
        Test that a Species containing a non-representative resonance structure is isomorphic
        with the "correct" Species containing only representative structures (which were not filtered out)

        When generating resonance isomers for N/O/S atoms, a large number of resonance structures per species could
        potentially be generated, yet most are filtered out and only the "correct" / "representative" structures
        are kept. This test makes sure that if a non-representative structure (i.e., a structure that was filtered out)
        is generated, RMG finds the Species it belongs to, if the last exists.
        """

        spc1_correct = Species().from_smiles(
            '[O]N=O')  # check charge separation with higher octet deviation
        spc1_nonrepresentative = Species().from_adjacency_list(
            """multiplicity 2
                                                                1 N u1 p1 c0 {2,S} {3,S}
                                                                2 O u0 p3 c-1 {1,S}
                                                                3 O u0 p2 c+1 {1,S}"""
        )
        spc2_correct = Species().from_smiles(
            '[N]=NON=O')  # check atoms with val 6
        spc2_nonrepresentative = Species().from_adjacency_list(
            """multiplicity 2
                                                                1 O u0 p2 c0 {2,S} {3,S}
                                                                2 N u1 p1 c0 {1,S} {4,S}
                                                                3 N u0 p2 c-1 {1,S} {5,S}
                                                                4 N u0 p2 c0 {2,S}
                                                                5 O u0 p2 c+1 {3,S}"""
        )
        spc3_correct = Species().from_smiles('[O]S(O)=O')  # check O4tc penalty
        spc3_nonrepresentative = Species().from_adjacency_list(
            """multiplicity 2
                                                                1 S u0 p1 c-1 {2,S} {3,S} {4,T}
                                                                2 O u0 p2 c0 {1,S} {5,S}
                                                                3 O u1 p2 c0 {1,S}
                                                                4 O u0 p1 c+1 {1,T}
                                                                5 H u0 p0 c0 {2,S}"""
        )
        spc4_correct = Species().from_smiles(
            'OS(=[N+]=[N-])O')  # check O4dc penalty
        spc4_nonrepresentative = Species().from_adjacency_list(
            """1 S u0 p0 c+1 {2,D} {3,D} {4,S}
                                                                2 N u0 p1 c0 {1,D} {5,S}
                                                                3 O u0 p1 c+1 {1,D} {6,S}
                                                                4 O u0 p2 c0 {1,S} {7,S}
                                                                5 N u0 p3 c-2 {2,S}
                                                                6 H u0 p0 c0 {3,S}
                                                                7 H u0 p0 c0 {4,S}"""
        )
        spc5_correct = Species().from_smiles('[O][S]')  # checks birad penalty
        spc5_nonrepresentative = Species().from_adjacency_list(
            """multiplicity 3
                                                                1 O u0 p2 c0 {2,D}
                                                                2 S u2 p1 c0 {1,D}"""
        )
        spc6_correct = Species().from_smiles(
            '[N-]=[N+]=S=S=O')  # checks the S#S case
        spc6_nonrepresentative = Species().from_adjacency_list(
            """1 S u0 p1 c0 {2,S} {3,T}
                                                                2 N u0 p0 c+1 {1,S} {4,T}
                                                                3 S u0 p1 c0 {1,T} {5,S}
                                                                4 N u0 p1 c0 {2,T}
                                                                5 O u0 p3 c-1 {3,S}"""
        )

        # check that the structures are not isomorphic if resonance structures are not generated:
        self.assertFalse(
            spc1_correct.is_isomorphic(spc1_nonrepresentative, strict=True))

        # check that the nonrepresentative structure is isomorphic by generating resonance structures:
        self.assertTrue(
            spc1_correct.is_isomorphic(spc1_nonrepresentative, strict=False))
        self.assertTrue(
            spc2_correct.is_isomorphic(spc2_nonrepresentative, strict=False))
        self.assertTrue(
            spc3_correct.is_isomorphic(spc3_nonrepresentative, strict=False))
        self.assertTrue(
            spc4_correct.is_isomorphic(spc4_nonrepresentative, strict=False))
        self.assertTrue(
            spc5_correct.is_isomorphic(spc5_nonrepresentative, strict=False))
        self.assertTrue(
            spc6_correct.is_isomorphic(spc6_nonrepresentative, strict=False))

    def test_get_resonance_hybrid(self):
        """
        Tests that get_resonance_hybrid returns an isomorphic structure
        which has intermediate bond orders.
        
        This check is for C=C[CH]CC which has another resonance structure,
        [CH2]C=CC. When these structures are merged, the bond structure should be,
        C~C~CC, where '~' is a hybrid bond of order 1.5. 
        """
        spec = Species().from_smiles('C=C[CH]CC')
        hybrid_mol = spec.get_resonance_hybrid()

        self.assertTrue(hybrid_mol.to_single_bonds().is_isomorphic(
            spec.molecule[0].to_single_bonds()))

        # a rough check for intermediate bond orders
        expected_orders = [1, 1.5]
        bonds = []
        # ensure all bond orders are expected
        for atom in hybrid_mol.atoms:
            for atom2 in atom.bonds:
                bond = hybrid_mol.get_bond(atom, atom2)
                self.assertTrue(
                    any([
                        bond.is_order(otherOrder)
                        for otherOrder in expected_orders
                    ]),
                    'Unexpected bond order {}'.format(bond.get_order_num()))
                bonds.append(bond)

        # ensure all expected orders are present
        for expected_order in expected_orders:
            self.assertTrue(
                any([bond.is_order(expected_order) for bond in bonds]),
                'No bond of order {} found'.format(expected_order))

    def test_copy(self):
        """Test that we can make a copy of a Species object."""

        spc_cp = self.species.copy()

        self.assertTrue(id(self.species) != id(spc_cp))
        self.assertTrue(self.species.is_isomorphic(spc_cp))
        self.assertEquals(self.species.label, spc_cp.label)
        self.assertEquals(self.species.index, spc_cp.index)

        self.assertTrue(
            self.species.molecular_weight.equals(spc_cp.molecular_weight))
        self.assertEquals(self.species.reactive, spc_cp.reactive)

    def test_cantera(self):
        """
        Test that a Cantera Species object is created correctly.
        """
        from rmgpy.thermo import NASA, NASAPolynomial
        import cantera as ct
        rmg_species = Species(
            label="Ar",
            thermo=NASA(polynomials=[
                NASAPolynomial(coeffs=[2.5, 0, 0, 0, 0, -745.375, 4.37967],
                               Tmin=(200, 'K'),
                               Tmax=(1000, 'K')),
                NASAPolynomial(coeffs=[2.5, 0, 0, 0, 0, -745.375, 4.37967],
                               Tmin=(1000, 'K'),
                               Tmax=(6000, 'K'))
            ],
                        Tmin=(200, 'K'),
                        Tmax=(6000, 'K'),
                        comment="""
Thermo library: primaryThermoLibrary
"""),
            molecule=[Molecule(smiles="[Ar]")],
            transport_data=TransportData(shapeIndex=0,
                                         epsilon=(1134.93, 'J/mol'),
                                         sigma=(3.33, 'angstrom'),
                                         dipoleMoment=(2, 'De'),
                                         polarizability=(1, 'angstrom^3'),
                                         rotrelaxcollnum=15.0,
                                         comment="""GRI-Mech"""))

        rmg_ct_species = rmg_species.to_cantera(use_chemkin_identifier=True)

        ct_species = ct.Species.fromCti("""species(name=u'Ar',
        atoms='Ar:1',
        thermo=(NASA([200.00, 1000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00]),
                NASA([1000.00, 6000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00])),
        transport=gas_transport(geom='atom',
                                diam=3.33,
                                well_depth=136.501,
                                dipole=2.0,
                                polar=1.0,
                                rot_relax=15.0))""")
        self.assertEqual(type(rmg_ct_species), type(ct_species))
        self.assertEqual(rmg_ct_species.name, ct_species.name)
        self.assertEqual(rmg_ct_species.composition, ct_species.composition)
        self.assertEqual(rmg_ct_species.size, ct_species.size)
        self.assertEqual(type(rmg_ct_species.thermo), type(ct_species.thermo))
        self.assertEqual(type(rmg_ct_species.transport),
                         type(ct_species.transport))

    def test_get_transport_data(self):
        """
        Test that transport data can be retrieved correctly via the get_transport_data method.
        """

        spc = Species(label="Ar",
                      molecule=[Molecule(smiles="[Ar]")],
                      transport_data=TransportData(
                          shapeIndex=0,
                          epsilon=(1134.93, 'J/mol'),
                          sigma=(3.33, 'angstrom'),
                          dipoleMoment=(2, 'De'),
                          polarizability=(1, 'angstrom^3'),
                          rotrelaxcollnum=15.0,
                          comment="""GRI-Mech"""))

        self.assertTrue(spc.get_transport_data() is spc.transport_data)

    def test_fingerprint_property(self):
        """Test that the fingerprint property works"""
        self.assertEqual(self.species2.fingerprint, 'C06H06N00O00S00')

    def test_inchi_property(self):
        """Test that the InChI property works"""
        self.assertEqual(self.species2.inchi,
                         'InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H')

    def test_multiplicity_property(self):
        """Test that the fingerprint property works"""
        self.assertEqual(self.species2.multiplicity, 1)

    def test_smiles_property(self):
        """Test that the InChI property works"""
        self.assertEqual(self.species2.smiles, 'C1=CC=CC=C1')

    def test_inchi_instantiation(self):
        """Test that we can create a species using the InChI argument"""
        test = Species(inchi='InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H')

        self.assertTrue(test.is_isomorphic(self.species2))

    def test_smiles_instantiation(self):
        """Test that we can create a species using the SMILES argument"""
        test = Species(smiles='C1=CC=CC=C1')

        self.assertTrue(test.is_isomorphic(self.species2))
Esempio n. 2
0
class TestSpecies(unittest.TestCase):
    """
    Contains unit tests for the Species class.
    """
    
    def setUp(self):
        """
        A method that is run before each unit test in this class.
        """
        self.species = Species(
            index=1,
            label='C2H4',
            thermo=ThermoData(
                Tdata=([300.0,400.0,500.0,600.0,800.0,1000.0,1500.0],'K'),
                Cpdata=([3.0,4.0,5.0,6.0,8.0,10.0,15.0],'cal/(mol*K)'),
                H298=(-20.0,'kcal/mol'),
                S298=(50.0,'cal/(mol*K)'),
                Tmin=(300.0,'K'),
                Tmax=(2000.0,'K'),
            ),
            conformer=Conformer(
                E0=(0.0,'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(28.03,'amu')),
                    NonlinearRotor(inertia=([5.6952e-47, 2.7758e-46, 3.3454e-46],'kg*m^2'), symmetry=1),
                    HarmonicOscillator(frequencies=([834.50, 973.31, 975.37, 1067.1, 1238.5, 1379.5, 1472.3, 1691.3, 3121.6, 3136.7, 3192.5, 3221.0],'cm^-1')),
                ],
                spinMultiplicity=1,
                opticalIsomers=1,
            ),
            molecule=[Molecule().fromSMILES('C=C')],
            transportData=TransportData(sigma=(1, 'angstrom'), epsilon=(100, 'K')),
            molecularWeight=(28.03,'amu'),
            reactive=True,
        )
        
    def testPickle(self):
        """
        Test that a Species object can be pickled and unpickled.
        
        ...with no loss of information.
        """
        import cPickle
        species = cPickle.loads(cPickle.dumps(self.species,-1))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity, species.molecule[0].multiplicity)
        self.assertEqual(self.species.getThermoData().H298.value_si, species.getThermoData().H298.value_si)
        self.assertEqual(self.species.getThermoData().H298.units, species.getThermoData().H298.units)
        self.assertEqual(len(self.species.conformer.modes), len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si, species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units, species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si, species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units, species.transportData.sigma.units)
        self.assertAlmostEqual(self.species.transportData.epsilon.value_si / 1.381e-23, species.transportData.epsilon.value_si / 1.381e-23, 4)
        self.assertEqual(self.species.transportData.epsilon.units, species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si, species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units, species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def testOutput(self):
        """
        Test that a Species object can be reconstructed from its repr().
        
        ...with no loss of information.
        """
        species = None
        exec('species = {0!r}'.format(self.species))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity, species.molecule[0].multiplicity)
        self.assertEqual(self.species.getThermoData().H298.value_si, species.getThermoData().H298.value_si)
        self.assertEqual(self.species.getThermoData().H298.units, species.getThermoData().H298.units)
        self.assertEqual(len(self.species.conformer.modes), len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si, species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units, species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si, species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units, species.transportData.sigma.units)
        self.assertAlmostEqual(self.species.transportData.epsilon.value_si, species.transportData.epsilon.value_si, 3)
        self.assertEqual(self.species.transportData.epsilon.units, species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si, species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units, species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)
        
    def testToAdjacencyList(self):
        """
        Test that toAdjacencyList() works as expected.
        """
        string = self.species.toAdjacencyList()
        self.assertTrue(string.startswith(self.species.molecule[0].toAdjacencyList(label=self.species.label,removeH=False)),string)
    
    def testSpeciesProps(self):
        """
        Test a key-value pair is added to the props attribute of Species.
        """
        self.species.props['foo'] = 'bar'
        self.assertIsInstance(self.species.props, dict)
        self.assertEquals(self.species.props['foo'], 'bar')
        
    def testSpeciesProps_object_attribute(self):
        """
        Test that Species's props dictionaries are independent of each other.
        
        Create a test in which is checked whether props is an object attribute rather
        than a class attribute
        """
        spc2 = Species()
        self.species.props['foo'] = 'bar'
        spc3 = Species()
        spc3.props['foo'] = 'bla'
        self.assertEquals(self.species.props['foo'], 'bar')
        self.assertDictEqual(spc2.props, {})
        self.assertDictEqual(spc3.props, {'foo': 'bla'})

    def testResonanceIsomersGenerated(self):
        "Test that 1-penten-3-yl makes 2-penten-1-yl resonance isomer"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generate_resonance_structures()
        self.assertEquals(len(spec.molecule), 2)
        self.assertEquals(spec.molecule[1].toSMILES(), "[CH2]C=CCC")

    def testResonaceIsomersRepresented(self):
        "Test that both resonance forms of 1-penten-3-yl are printed by __repr__"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generate_resonance_structures()
        exec('spec2 = {0!r}'.format(spec))
        self.assertEqual(len(spec.molecule), len(spec2.molecule))
        for i, j in zip(spec.molecule, spec2.molecule):
            self.assertTrue(j.isIsomorphic(i), msg='i is not isomorphic with j, where i is {} and j is {}'.format(i.toSMILES(), j.toSMILES()))

    def testGetResonanceHybrid(self):
        """
        Tests that getResonanceHybrid returns an isomorphic structure
        which has intermediate bond orders.
        
        This check is for C=C[CH]CC which has another resonance structure,
        [CH2]C=CC. When these structures are merged, the bond structure should be,
        C~C~CC, where '~' is a hybrid bond of order 1.5. 
        """
        spec = Species().fromSMILES('C=C[CH]CC')
        hybridMol = spec.getResonanceHybrid()
        
        self.assertTrue(hybridMol.toSingleBonds().isIsomorphic(spec.molecule[0].toSingleBonds()))
        
        # a rough check for intermediate bond orders
        expected_orders = [1,1.5]
        bonds = []
        # ensure all bond orders are expected
        for atom in hybridMol.atoms:
            for atom2 in atom.bonds:
                bond = hybridMol.getBond(atom,atom2)
                self.assertTrue(any([bond.isOrder(otherOrder) for otherOrder in expected_orders]), 'Unexpected bond order {}'.format(bond.getOrderNum()))
                bonds.append(bond)
                
        # ensure all expected orders are present
        for expected_order in expected_orders:
            self.assertTrue(any([bond.isOrder(expected_order) for bond in bonds]),'No bond of order {} found'.format(expected_order))
            
            
    def testCopy(self):
        """Test that we can make a copy of a Species object."""

        spc_cp = self.species.copy()

        self.assertTrue(id(self.species) != id(spc_cp))
        self.assertTrue(self.species.isIsomorphic(spc_cp))
        self.assertEquals(self.species.label, spc_cp.label)
        self.assertEquals(self.species.index, spc_cp.index)

        self.assertTrue(self.species.molecularWeight.equals(spc_cp.molecularWeight))
        self.assertEquals(self.species.reactive, spc_cp.reactive)
        
    def testCantera(self):
        """
        Test that a Cantera Species object is created correctly.
        """
        from rmgpy.thermo import NASA, NASAPolynomial
        import cantera as ct
        rmgSpecies = Species(label="Ar", thermo=NASA(polynomials=[NASAPolynomial(coeffs=[2.5,0,0,0,0,-745.375,4.37967], Tmin=(200,'K'), Tmax=(1000,'K')), NASAPolynomial(coeffs=[2.5,0,0,0,0,-745.375,4.37967], Tmin=(1000,'K'), Tmax=(6000,'K'))], Tmin=(200,'K'), Tmax=(6000,'K'), comment="""
Thermo library: primaryThermoLibrary
"""), molecule=[Molecule(SMILES="[Ar]")], transportData=TransportData(shapeIndex=0, epsilon=(1134.93,'J/mol'), sigma=(3.33,'angstrom'), dipoleMoment=(2,'De'), polarizability=(1,'angstrom^3'), rotrelaxcollnum=15.0, comment="""GRI-Mech"""))
        
        rmg_ctSpecies = rmgSpecies.toCantera(useChemkinIdentifier = True)
        
        ctSpecies = ct.Species.fromCti("""species(name=u'Ar',
        atoms='Ar:1',
        thermo=(NASA([200.00, 1000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00]),
                NASA([1000.00, 6000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00])),
        transport=gas_transport(geom='atom',
                                diam=3.33,
                                well_depth=136.501,
                                dipole=2.0,
                                polar=1.0,
                                rot_relax=15.0))""")
        self.assertEqual(type(rmg_ctSpecies),type(ctSpecies))
        self.assertEqual(rmg_ctSpecies.name, ctSpecies.name)
        self.assertEqual(rmg_ctSpecies.composition, ctSpecies.composition)
        self.assertEqual(rmg_ctSpecies.size, ctSpecies.size)
        self.assertEqual(type(rmg_ctSpecies.thermo), type(ctSpecies.thermo))
        self.assertEqual(type(rmg_ctSpecies.transport), type(ctSpecies.transport))

    def testGetTransportData(self):
        """
        Test that transport data can be retrieved correctly via the getTransportData method.
        """

        spc = Species(label="Ar", molecule=[Molecule(SMILES="[Ar]")], transportData=TransportData(shapeIndex=0, epsilon=(1134.93,'J/mol'), sigma=(3.33,'angstrom'), dipoleMoment=(2,'De'), polarizability=(1,'angstrom^3'), rotrelaxcollnum=15.0, comment="""GRI-Mech"""))

        self.assertTrue(spc.getTransportData() is spc.transportData)
Esempio n. 3
0
class TestSpecies(unittest.TestCase):
    """
    Contains unit tests for the Species class.
    """
    def setUp(self):
        """
        A method that is run before each unit test in this class.
        """
        self.species = Species(
            index=1,
            label='C2H4',
            thermo=ThermoData(
                Tdata=([300.0, 400.0, 500.0, 600.0, 800.0, 1000.0,
                        1500.0], 'K'),
                Cpdata=([3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 15.0], 'cal/(mol*K)'),
                H298=(-20.0, 'kcal/mol'),
                S298=(50.0, 'cal/(mol*K)'),
                Tmin=(300.0, 'K'),
                Tmax=(2000.0, 'K'),
            ),
            conformer=Conformer(
                E0=(0.0, 'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(28.03, 'amu')),
                    NonlinearRotor(
                        inertia=([5.6952e-47, 2.7758e-46,
                                  3.3454e-46], 'kg*m^2'),
                        symmetry=1),
                    HarmonicOscillator(frequencies=([
                        834.50, 973.31, 975.37, 1067.1, 1238.5, 1379.5, 1472.3,
                        1691.3, 3121.6, 3136.7, 3192.5, 3221.0
                    ], 'cm^-1')),
                ],
                spinMultiplicity=1,
                opticalIsomers=1,
            ),
            molecule=[Molecule().fromSMILES('C=C')],
            transportData=TransportData(sigma=(1, 'angstrom'),
                                        epsilon=(100, 'K')),
            molecularWeight=(28.03, 'amu'),
            reactive=True,
        )

    def testPickle(self):
        """
        Test that a Species object can be pickled and unpickled.
        
        ...with no loss of information.
        """
        import cPickle
        species = cPickle.loads(cPickle.dumps(self.species, -1))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity,
                         species.molecule[0].multiplicity)
        self.assertEqual(self.species.getThermoData().H298.value_si,
                         species.getThermoData().H298.value_si)
        self.assertEqual(self.species.getThermoData().H298.units,
                         species.getThermoData().H298.units)
        self.assertEqual(len(self.species.conformer.modes),
                         len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(
            species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si,
                         species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units,
                         species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si,
                         species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units,
                         species.transportData.sigma.units)
        self.assertAlmostEqual(
            self.species.transportData.epsilon.value_si / 1.381e-23,
            species.transportData.epsilon.value_si / 1.381e-23, 4)
        self.assertEqual(self.species.transportData.epsilon.units,
                         species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si,
                         species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units,
                         species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def testOutput(self):
        """
        Test that a Species object can be reconstructed from its repr().
        
        ...with no loss of information.
        """
        species = None
        exec('species = {0!r}'.format(self.species))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity,
                         species.molecule[0].multiplicity)
        self.assertEqual(self.species.getThermoData().H298.value_si,
                         species.getThermoData().H298.value_si)
        self.assertEqual(self.species.getThermoData().H298.units,
                         species.getThermoData().H298.units)
        self.assertEqual(len(self.species.conformer.modes),
                         len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(
            species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si,
                         species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units,
                         species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si,
                         species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units,
                         species.transportData.sigma.units)
        self.assertAlmostEqual(self.species.transportData.epsilon.value_si,
                               species.transportData.epsilon.value_si, 3)
        self.assertEqual(self.species.transportData.epsilon.units,
                         species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si,
                         species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units,
                         species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def testToAdjacencyList(self):
        """
        Test that toAdjacencyList() works as expected.
        """
        string = self.species.toAdjacencyList()
        self.assertTrue(
            string.startswith(self.species.molecule[0].toAdjacencyList(
                label=self.species.label, removeH=False)), string)

    def testSpeciesProps(self):
        """
        Test a key-value pair is added to the props attribute of Species.
        """
        self.species.props['foo'] = 'bar'
        self.assertIsInstance(self.species.props, dict)
        self.assertEquals(self.species.props['foo'], 'bar')

    def testSpeciesProps_object_attribute(self):
        """
        Test that Species's props dictionaries are independent of each other.
        
        Create a test in which is checked whether props is an object attribute rather
        than a class attribute
        """
        spc2 = Species()
        self.species.props['foo'] = 'bar'
        spc3 = Species()
        spc3.props['foo'] = 'bla'
        self.assertEquals(self.species.props['foo'], 'bar')
        self.assertDictEqual(spc2.props, {})
        self.assertDictEqual(spc3.props, {'foo': 'bla'})

    def testResonanceIsomersGenerated(self):
        "Test that 1-penten-3-yl makes 2-penten-1-yl resonance isomer"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generateResonanceIsomers()
        self.assertEquals(len(spec.molecule), 2)
        self.assertEquals(spec.molecule[1].toSMILES(), "[CH2]C=CCC")

    def testResonaceIsomersRepresented(self):
        "Test that both resonance forms of 1-penten-3-yl are printed by __repr__"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generateResonanceIsomers()
        exec('spec2 = {0!r}'.format(spec))
        self.assertEqual(len(spec.molecule), len(spec2.molecule))
        for i, j in zip(spec.molecule, spec2.molecule):
            self.assertTrue(i.isIsomorphic(j))

    def testCopy(self):
        """Test that we can make a copy of a Species object."""

        spc_cp = self.species.copy()

        self.assertTrue(id(self.species) != id(spc_cp))
        self.assertTrue(self.species.isIsomorphic(spc_cp))
        self.assertEquals(self.species.label, spc_cp.label)
        self.assertEquals(self.species.index, spc_cp.index)

        self.assertTrue(
            self.species.molecularWeight.equals(spc_cp.molecularWeight))
        self.assertEquals(self.species.reactive, spc_cp.reactive)

    def testCantera(self):
        """
        Test that a Cantera Species object is created correctly.
        """
        from rmgpy.thermo import NASA, NASAPolynomial
        import cantera as ct
        rmgSpecies = Species(
            label="Ar",
            thermo=NASA(polynomials=[
                NASAPolynomial(coeffs=[2.5, 0, 0, 0, 0, -745.375, 4.37967],
                               Tmin=(200, 'K'),
                               Tmax=(1000, 'K')),
                NASAPolynomial(coeffs=[2.5, 0, 0, 0, 0, -745.375, 4.37967],
                               Tmin=(1000, 'K'),
                               Tmax=(6000, 'K'))
            ],
                        Tmin=(200, 'K'),
                        Tmax=(6000, 'K'),
                        comment="""
Thermo library: primaryThermoLibrary
"""),
            molecule=[Molecule(SMILES="[Ar]")],
            transportData=TransportData(shapeIndex=0,
                                        epsilon=(1134.93, 'J/mol'),
                                        sigma=(3.33, 'angstrom'),
                                        dipoleMoment=(2, 'De'),
                                        polarizability=(1, 'angstrom^3'),
                                        rotrelaxcollnum=15.0,
                                        comment="""GRI-Mech"""))

        rmg_ctSpecies = rmgSpecies.toCantera()

        ctSpecies = ct.Species.fromCti("""species(name=u'Ar',
        atoms='Ar:1',
        thermo=(NASA([200.00, 1000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00]),
                NASA([1000.00, 6000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00])),
        transport=gas_transport(geom='atom',
                                diam=3.33,
                                well_depth=136.501,
                                dipole=2.0,
                                polar=1.0,
                                rot_relax=15.0))""")
        self.assertEqual(type(rmg_ctSpecies), type(ctSpecies))
        self.assertEqual(rmg_ctSpecies.name, ctSpecies.name)
        self.assertEqual(rmg_ctSpecies.composition, ctSpecies.composition)
        self.assertEqual(rmg_ctSpecies.size, ctSpecies.size)
        self.assertEqual(type(rmg_ctSpecies.thermo), type(ctSpecies.thermo))
        self.assertEqual(type(rmg_ctSpecies.transport),
                         type(ctSpecies.transport))

    def testGetTransportData(self):
        """
        Test that transport data can be retrieved correctly via the getTransportData method.
        """

        spc = Species(label="Ar",
                      molecule=[Molecule(SMILES="[Ar]")],
                      transportData=TransportData(
                          shapeIndex=0,
                          epsilon=(1134.93, 'J/mol'),
                          sigma=(3.33, 'angstrom'),
                          dipoleMoment=(2, 'De'),
                          polarizability=(1, 'angstrom^3'),
                          rotrelaxcollnum=15.0,
                          comment="""GRI-Mech"""))

        self.assertTrue(spc.getTransportData() is spc.transportData)
Esempio n. 4
0
class TestSpecies(unittest.TestCase):
    """
    Contains unit tests for the Species class.
    """
    
    def setUp(self):
        """
        A method that is run before each unit test in this class.
        """
        self.species = Species(
            index=1,
            label='C2H4',
            thermo=ThermoData(
                Tdata=([300.0,400.0,500.0,600.0,800.0,1000.0,1500.0],'K'),
                Cpdata=([3.0,4.0,5.0,6.0,8.0,10.0,15.0],'cal/(mol*K)'),
                H298=(-20.0,'kcal/mol'),
                S298=(50.0,'cal/(mol*K)'),
                Tmin=(300.0,'K'),
                Tmax=(2000.0,'K'),
            ),
            conformer=Conformer(
                E0=(0.0,'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(28.03,'amu')),
                    NonlinearRotor(inertia=([5.6952e-47, 2.7758e-46, 3.3454e-46],'kg*m^2'), symmetry=1),
                    HarmonicOscillator(frequencies=([834.50, 973.31, 975.37, 1067.1, 1238.5, 1379.5, 1472.3, 1691.3, 3121.6, 3136.7, 3192.5, 3221.0],'cm^-1')),
                ],
                spinMultiplicity=1,
                opticalIsomers=1,
            ),
            molecule=[Molecule().fromSMILES('C=C')],
            transportData=TransportData(sigma=(1, 'angstrom'), epsilon=(100, 'K')),
            molecularWeight=(28.03,'amu'),
            reactive=True,
        )
        
    def testPickle(self):
        """
        Test that a Species object can be pickled and unpickled.
        
        ...with no loss of information.
        """
        import cPickle
        species = cPickle.loads(cPickle.dumps(self.species,-1))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity, species.molecule[0].multiplicity)
        self.assertEqual(self.species.thermo.H298.value_si, species.thermo.H298.value_si)
        self.assertEqual(self.species.thermo.H298.units, species.thermo.H298.units)
        self.assertEqual(len(self.species.conformer.modes), len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si, species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units, species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si, species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units, species.transportData.sigma.units)
        self.assertAlmostEqual(self.species.transportData.epsilon.value_si / 1.381e-23, species.transportData.epsilon.value_si / 1.381e-23, 4)
        self.assertEqual(self.species.transportData.epsilon.units, species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si, species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units, species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def testOutput(self):
        """
        Test that a Species object can be reconstructed from its repr().
        
        ...with no loss of information.
        """
        species = None
        exec('species = {0!r}'.format(self.species))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity, species.molecule[0].multiplicity)
        self.assertEqual(self.species.thermo.H298.value_si, species.thermo.H298.value_si)
        self.assertEqual(self.species.thermo.H298.units, species.thermo.H298.units)
        self.assertEqual(len(self.species.conformer.modes), len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si, species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units, species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si, species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units, species.transportData.sigma.units)
        self.assertAlmostEqual(self.species.transportData.epsilon.value_si, species.transportData.epsilon.value_si, 3)
        self.assertEqual(self.species.transportData.epsilon.units, species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si, species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units, species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)
        
    def testToAdjacencyList(self):
        """
        Test that toAdjacencyList() works as expected.
        """
        string = self.species.toAdjacencyList()
        self.assertTrue(string.startswith(self.species.molecule[0].toAdjacencyList(label=self.species.label,removeH=False)),string)
    
    def testSpeciesProps(self):
        """
        Test a key-value pair is added to the props attribute of Species.
        """
        self.species.props['foo'] = 'bar'
        self.assertIsInstance(self.species.props, dict)
        self.assertEquals(self.species.props['foo'], 'bar')
        
    def testSpeciesProps_object_attribute(self):
        """
        Test that Species's props dictionaries are independent of each other.
        
        Create a test in which is checked whether props is an object attribute rather
        than a class attribute
        """
        spc2 = Species()
        self.species.props['foo'] = 'bar'
        spc3 = Species()
        spc3.props['foo'] = 'bla'
        self.assertEquals(self.species.props['foo'], 'bar')
        self.assertDictEqual(spc2.props, {})
        self.assertDictEqual(spc3.props, {'foo': 'bla'})

    def testResonanceIsomersGenerated(self):
        "Test that 1-penten-3-yl makes 2-penten-1-yl resonance isomer"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generateResonanceIsomers()
        self.assertEquals(len(spec.molecule), 2)
        self.assertEquals(spec.molecule[1].toSMILES(), "[CH2]C=CCC")

    def testResonaceIsomersRepresented(self):
        "Test that both resonance forms of 1-penten-3-yl are printed by __repr__"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generateResonanceIsomers()
        exec('spec2 = {0!r}'.format(spec))
        self.assertEqual(len(spec.molecule), len(spec2.molecule))
        for i, j in zip(spec.molecule, spec2.molecule):
            self.assertTrue(i.isIsomorphic(j))

    def testCopy(self):
        """Test that we can make a copy of a Species object."""

        spc_cp = self.species.copy()

        self.assertTrue(id(self.species) != id(spc_cp))
        self.assertTrue(self.species.isIsomorphic(spc_cp))
        self.assertEquals(self.species.label, spc_cp.label)
        self.assertEquals(self.species.index, spc_cp.index)

        self.assertTrue(self.species.molecularWeight.equals(spc_cp.molecularWeight))
        self.assertEquals(self.species.reactive, spc_cp.reactive)