def test_reaction_families(self): # R_Addition_MultipleBond reaction = Reaction("C#C+[OH]_[CH]=CO") _, family = reaction.get_labeled_reaction() self.assertEqual(family.lower(), "R_Addition_MultipleBond".lower()) # intra_H_migration reaction = Reaction("C[CH]O_CC[O]") _, family = reaction.get_labeled_reaction() self.assertEqual(family.lower(), "intra_H_migration".lower())
def test_symmetry_number(self): self.assertEquals(self.ts.symmetry_number, 1) self.assertEquals(self.ts2.symmetry_number, 1) reactions_to_test = { "[CH3]+[OH]_C+[O]": 3, # TODO add other reactions here } for reaction_string, expected_symmetry in reactions_to_test.items(): rxn = Reaction(reaction_string) rxn.get_labeled_reaction() ts = rxn.ts["forward"][0] self.assertEquals(ts.symmetry_number, expected_symmetry)
def test_estimate_distances(self): reaction = Reaction("CC+[O]O_[CH2]C+OO") labeled_reaction, _ = reaction.get_labeled_reaction() distance_data = self.ts_database.estimate_distances(labeled_reaction) d12 = 1.38 d13 = 2.53 # d13 in reactionTest is smaller than the distance in baseTest.py because # d13 is edited to be smaller in reaction.py. The value returned from the database # is ~2.53 but is reduced to ~2.43 when called from the reaction object itself d23 = 1.16 self.assertAlmostEquals(d12, distance_data.distances["d12"], places=1) self.assertAlmostEquals(d13, distance_data.distances["d13"], places=1) self.assertAlmostEquals(d23, distance_data.distances["d23"], places=1)
class TestReaction(unittest.TestCase): def setUp(self): self.reaction = Reaction("CC+[O]O_[CH2]C+OO") self.reaction2 = Reaction(rmg_reaction=RMGReaction( reactants=[RMGMolecule(smiles="CC"), RMGMolecule(smiles="[O]O")], products=[RMGMolecule(smiles="[CH2]C"), RMGMolecule(smiles="OO")])) def test_label(self): self.assertEqual(self.reaction.label, "CC+[O]O_[CH2]C+OO") self.assertEqual(self.reaction2.get_label(), "CC+[O]O_C[CH2]+OO") def test_rmg_reaction(self): test_reaction = RMGReaction( reactants=[RMGMolecule(smiles="CC"), RMGMolecule(smiles="[O]O")], products=[RMGMolecule(smiles="[CH2]C"), RMGMolecule(smiles="OO")]) self.assertTrue( test_reaction.is_isomorphic(self.reaction.get_rmg_reaction())) self.assertTrue( test_reaction.is_isomorphic(self.reaction2.get_rmg_reaction())) def test_databases(self): rmg_database, ts_databases = self.reaction.load_databases() self.assertIsInstance(rmg_database, RMGDatabase) self.assertIsInstance(ts_databases, dict) self.assertIsInstance(ts_databases["H_Abstraction"], TransitionStates) rmg_database, ts_databases = self.reaction2.load_databases() self.assertIsInstance(rmg_database, RMGDatabase) self.assertIsInstance(ts_databases, dict) self.assertIsInstance(ts_databases["H_Abstraction"], TransitionStates) def test_disance_data(self): d12 = 1.38 d13 = 2.43 # d13 in reactionTest is smaller than the distance in baseTest.py because # d13 is edited to be smaller in reaction.py. The value returned from the database # is ~2.53 but is reduced to 2.43 when called from the reaction object itself d23 = 1.16 self.assertAlmostEquals(d12, self.reaction.distance_data.distances["d12"], places=1) self.assertAlmostEquals(d13, self.reaction.distance_data.distances["d13"], places=1) self.assertAlmostEquals(d23, self.reaction.distance_data.distances["d23"], places=1) self.assertAlmostEquals(d12, self.reaction2.distance_data.distances["d12"], places=1) self.assertAlmostEquals(d13, self.reaction2.distance_data.distances["d13"], places=1) self.assertAlmostEquals(d23, self.reaction2.distance_data.distances["d23"], places=1) def test_generate_reactants_and_products(self): reactants, products = self.reaction.generate_reactants_and_products() self.assertIsInstance(reactants, list) self.assertIsInstance(products, list) self.assertEquals(len(reactants), 2) self.assertAlmostEquals(len(products), 2) reactants, products = self.reaction2.generate_reactants_and_products() self.assertIsInstance(reactants, list) self.assertIsInstance(products, list) self.assertEquals(len(reactants), 2) self.assertAlmostEquals(len(products), 2) def test_labeled_reaction(self): test_reaction = RMGReaction( reactants=[RMGMolecule(smiles="CC"), RMGMolecule(smiles="[O]O")], products=[RMGMolecule(smiles="[CH2]C"), RMGMolecule(smiles="OO")]) labeled_reaction, reaction_family = self.reaction.get_labeled_reaction( ) self.assertEquals(reaction_family.lower(), "h_abstraction") self.assertTrue(test_reaction.is_isomorphic(labeled_reaction)) merged = labeled_reaction.reactants[0].merge( labeled_reaction.reactants[1]) self.assertTrue(merged.get_labeled_atoms("*1")[0].is_carbon()) self.assertTrue(merged.get_labeled_atoms("*2")[0].is_hydrogen()) self.assertTrue(merged.get_labeled_atoms("*3")[0].is_oxygen) merged = labeled_reaction.products[0].merge( labeled_reaction.products[1]) self.assertTrue(merged.get_labeled_atoms("*3")[0].is_carbon()) self.assertTrue(merged.get_labeled_atoms("*2")[0].is_hydrogen()) self.assertTrue(merged.get_labeled_atoms("*1")[0].is_oxygen) labeled_reaction, reaction_family = self.reaction2.get_labeled_reaction( ) self.assertEquals(reaction_family.lower(), "h_abstraction") self.assertTrue(test_reaction.is_isomorphic(labeled_reaction)) merged = labeled_reaction.reactants[0].merge( labeled_reaction.reactants[1]) self.assertTrue(merged.get_labeled_atoms("*1")[0].is_carbon()) self.assertTrue(merged.get_labeled_atoms("*2")[0].is_hydrogen()) self.assertTrue(merged.get_labeled_atoms("*3")[0].is_oxygen) merged = labeled_reaction.products[0].merge( labeled_reaction.products[1]) self.assertTrue(merged.get_labeled_atoms("*3")[0].is_carbon()) self.assertTrue(merged.get_labeled_atoms("*2")[0].is_hydrogen()) self.assertTrue(merged.get_labeled_atoms("*1")[0].is_oxygen) def test_rmg_complexes(self): self.reaction.get_labeled_reaction() self.reaction.get_rmg_complexes() self.assertEquals(len(self.reaction.complexes), 2) self.assertEquals( len(self.reaction.complexes["forward"].get_all_labeled_atoms()), 3) self.assertEquals( len(self.reaction.complexes["reverse"].get_all_labeled_atoms()), 3) self.reaction2.get_labeled_reaction() self.reaction2.get_rmg_complexes() self.assertEquals(len(self.reaction2.complexes), 2) self.assertEquals( len(self.reaction2.complexes["forward"].get_all_labeled_atoms()), 3) self.assertEquals( len(self.reaction2.complexes["reverse"].get_all_labeled_atoms()), 3) def test_ts(self): self.assertEquals(len(self.reaction.ts), 2) self.assertEquals(len(self.reaction.ts["forward"]), 1) self.assertEquals(len(self.reaction.ts["reverse"]), 1) self.assertIsInstance(self.reaction.ts["forward"][0], TS) self.assertIsInstance(self.reaction.ts["reverse"][0], TS) self.assertEquals(len(self.reaction2.ts), 2) self.assertEquals(len(self.reaction2.ts["forward"]), 1) self.assertEquals(len(self.reaction2.ts["reverse"]), 1) self.assertIsInstance(self.reaction2.ts["forward"][0], TS) self.assertIsInstance(self.reaction2.ts["reverse"][0], TS) def test_reaction_families(self): # R_Addition_MultipleBond reaction = Reaction("C#C+[OH]_[CH]=CO") _, family = reaction.get_labeled_reaction() self.assertEqual(family.lower(), "R_Addition_MultipleBond".lower()) # intra_H_migration reaction = Reaction("C[CH]O_CC[O]") _, family = reaction.get_labeled_reaction() self.assertEqual(family.lower(), "intra_H_migration".lower())
class TestStatMech(unittest.TestCase): def setUp(self): self.reaction = Reaction("CC+[O]O_[CH2]C+OO") self.reaction.get_labeled_reaction() self.reaction.generate_reactants_and_products() directory = os.path.expandvars("$AUTOTST/test") if not os.path.exists( os.path.join(directory, "ts", self.reaction.label)): os.makedirs(os.path.join(directory, "ts", self.reaction.label)) if not os.path.exists( os.path.join(directory, "ts", self.reaction.label, self.reaction.label + ".log")): shutil.copy( os.path.join(directory, "bin", "log-files", self.reaction.label + "_forward_0.log"), os.path.join(directory, "ts", self.reaction.label, self.reaction.label + ".log")) for sp in self.reaction.reactants + self.reaction.products: for smiles in sp.conformers.keys(): if not os.path.exists( os.path.join(directory, "species", smiles)): os.makedirs(os.path.join(directory, "species", smiles)) if not os.path.exists( os.path.join(directory, "species", smiles, smiles + ".log")): shutil.copy( os.path.join(directory, "bin", "log-files", smiles + "_0.log"), os.path.join(directory, "species", smiles, smiles + ".log")) self.statmech = StatMech(reaction=self.reaction, directory=directory) def tearDown(self): directory = os.path.expandvars("$AUTOTST/test") if os.path.exists(os.path.join(directory, "ts")): shutil.rmtree(os.path.join(directory, "ts")) if os.path.exists(os.path.join(directory, "species")): shutil.rmtree(os.path.join(directory, "species")) for head, _, files in os.walk(os.path.expandvars("$AUTOTST")): for fi in files: if fi.endswith(".symm"): os.remove(os.path.join(head, fi)) def test_get_atoms(self): ts = self.reaction.ts["forward"][0] atom_dict = self.statmech.get_atoms(ts) self.assertEqual(atom_dict["H"], 7) self.assertEqual(atom_dict["C"], 2) self.assertEqual(atom_dict["O"], 2) #def test_get_bonds(self): ### For somereason, this test doesn't work on travis... # ts = self.reaction.ts["forward"][0] # bond_dict = self.statmech.get_bonds(ts) # self.assertEqual(bond_dict["O-O"], 1) # self.assertEqual(bond_dict["O-H"], 1) # self.assertEqual(bond_dict["C-C"], 1) # self.assertEqual(bond_dict["C-H"], 6) def test_write_conformer_file(self): species = self.reaction.reactants[0] conformer = species.conformers.values()[0][0] self.assertTrue(self.statmech.write_conformer_file(conformer)) self.assertTrue( os.path.exists( os.path.join(self.statmech.directory, "species", conformer.smiles, conformer.smiles + ".py"))) # Running it again to see if it recognizes that a .py file was already written self.assertTrue(self.statmech.write_conformer_file(conformer)) def test_write_species_file(self): species = self.reaction.reactants[0] self.statmech.write_species_files(species) for smiles in species.conformers.keys(): self.assertTrue( os.path.exists( os.path.join(self.statmech.directory, "species", smiles, smiles + ".py"))) def test_write_ts_input(self): ts = self.reaction.ts["forward"][0] self.assertTrue(self.statmech.write_ts_input(ts)) self.assertTrue( os.path.exists( os.path.join(self.statmech.directory, "ts", self.reaction.label, self.reaction.label + ".py"))) self.assertTrue(self.statmech.write_ts_input(ts)) def test_write_kinetics_input(self): self.statmech.write_kinetics_input() self.assertTrue( os.path.exists( os.path.join(self.statmech.directory, "ts", self.reaction.label, self.reaction.label + ".kinetics.py"))) def test_write_files(self): self.statmech.write_files() for mol in self.reaction.reactants + self.reaction.products: for confs in mol.conformers.values(): conf = confs[0] self.assertTrue( os.path.exists( os.path.join(self.statmech.directory, "species", conf.smiles, conf.smiles + ".py"))) self.assertTrue( os.path.exists( os.path.join(self.statmech.directory, "ts", self.reaction.label, self.reaction.label + ".py"))) self.assertTrue( os.path.exists( os.path.join(self.statmech.directory, "ts", self.reaction.label, self.reaction.label + ".kinetics.py"))) def test_run(self): self.statmech.write_files() self.statmech.run() self.assertIsInstance(self.statmech.kinetics_job.reaction, RMGReaction) self.assertIsInstance(self.statmech.kinetics_job.reaction.kinetics, Arrhenius) def test_set_results(self): self.test_run() self.statmech.set_results() self.assertTrue( self.reaction.rmg_reaction.isIsomorphic( self.statmech.kinetics_job.reaction)) self.assertTrue( self.statmech.reaction.rmg_reaction.isIsomorphic( self.statmech.kinetics_job.reaction))
class VibrationalAnalysisTest(unittest.TestCase): def setUp(self): self.reaction = Reaction("CC+[O]O_[CH2]C+OO") self.reaction.get_labeled_reaction() self.ts = self.reaction.ts["forward"][0] self.ts.get_molecules() directory = os.path.expandvars("$AUTOTST/test") if not os.path.exists( os.path.join(directory, "ts", self.reaction.label, "conformers")): os.makedirs( os.path.join(directory, "ts", self.reaction.label, "conformers")) if not os.path.exists( os.path.join(directory, "ts", self.reaction.label, self.reaction.label + ".log")): shutil.copy( os.path.join(directory, "bin", "log-files", self.reaction.label + "_forward_0.log"), os.path.join(directory, "ts", self.reaction.label, "conformers", self.reaction.label + "_forward_0.log")) self.directory = directory self.vibrational_analysis = VibrationalAnalysis( transitionstate=self.ts, directory=self.directory) def tearDown(self): directory = os.path.expandvars("$AUTOTST/test") if os.path.exists(os.path.join(directory, "ts")): shutil.rmtree(os.path.join(directory, "ts")) for head, _, files in os.walk(os.path.expandvars("$AUTOTST")): for fi in files: if fi.endswith(".symm"): os.remove(os.path.join(head, fi)) def test_get_log_file(self): log_file = self.vibrational_analysis.get_log_file() actual_path = os.path.join( self.directory, "ts", self.ts.reaction_label, "conformers", "{}_{}_{}.log".format(self.ts.reaction_label, self.ts.direction, self.ts.index)) self.assertEqual(log_file, actual_path) def test_parse_vibrations(self): vibrations = self.vibrational_analysis.parse_vibrations() self.assertIsInstance(vibrations, list) self.assertEqual(len(vibrations), 27) def test_obtain_geometries(self): vibrations = self.vibrational_analysis.parse_vibrations() symbol_dict = { 17: "Cl", 9: "F", 8: "O", 7: "N", 6: "C", 1: "H", } atoms = [] parser = ccread(self.vibrational_analysis.log_file) for atom_num, coords in zip(parser.atomnos, parser.atomcoords[-1]): atoms.append(Atom(symbol=symbol_dict[atom_num], position=coords)) test_pre_geometry = Atoms(atoms) test_post_geometry = test_pre_geometry.copy() for vib, displacement in vibrations: if vib < 0: test_post_geometry.arrays["positions"] -= displacement pre_geometry, post_geometry = self.vibrational_analysis.obtain_geometries( ) for i, positions in enumerate(test_pre_geometry.arrays["positions"]): for j, x in enumerate(positions): self.assertEqual(x, pre_geometry.arrays["positions"][i][j]) for i, positions in enumerate(test_post_geometry.arrays["positions"]): for j, x in enumerate(positions): self.assertEqual(x, post_geometry.arrays["positions"][i][j]) def test_validate_ts(self): self.assertTrue(self.vibrational_analysis.validate_ts())