|
| 1 | +#!/usr/bin/env python3 |
| 2 | +# encoding: utf-8 |
| 3 | + |
| 4 | +""" |
| 5 | +This module contains unit tests of the arc.job.adapters.ts.heuristics module |
| 6 | +""" |
| 7 | + |
| 8 | +import unittest |
| 9 | +import shutil |
| 10 | + |
| 11 | +from arc.common import ARC_PATH, _check_r_n_p_symbols_between_rmg_and_arc_rxns, almost_equal_coords |
| 12 | +from arc.job.adapters.ts.linear import (LinearAdapter, |
| 13 | + average_zmat_params, |
| 14 | + get_rxn_weight, |
| 15 | + get_weight, |
| 16 | + interpolate_isomerization, |
| 17 | + ) |
| 18 | +from arc.reaction import ARCReaction |
| 19 | +from arc.rmgdb import load_families_only, make_rmg_database_object |
| 20 | +from arc.species.converter import str_to_xyz, zmat_to_xyz, xyz_to_str |
| 21 | +from arc.species.species import ARCSpecies |
| 22 | +from arc.species.zmat import _compare_zmats |
| 23 | + |
| 24 | + |
| 25 | +class TestHeuristicsAdapter(unittest.TestCase): |
| 26 | + """ |
| 27 | + Contains unit tests for the HeuristicsAdapter class. |
| 28 | + """ |
| 29 | + |
| 30 | + @classmethod |
| 31 | + def setUpClass(cls): |
| 32 | + """ |
| 33 | + A method that is run before all unit tests in this class. |
| 34 | + """ |
| 35 | + cls.maxDiff = None |
| 36 | + # cls.rmgdb = make_rmg_database_object() |
| 37 | + # load_families_only(cls.rmgdb) |
| 38 | + |
| 39 | + def test_average_zmat_params(self): |
| 40 | + """Test the average_zmat_params() function.""" |
| 41 | + zmat_1 = {'symbols': ('H', 'H'), |
| 42 | + 'coords': ((None, None, None), |
| 43 | + ('R_1_0', None, None)), |
| 44 | + 'vars': {'R_1_0': 0.7}, |
| 45 | + 'map': {0: 0, 1: 1}} |
| 46 | + zmat_2 = {'symbols': ('H', 'H'), |
| 47 | + 'coords': ((None, None, None), |
| 48 | + ('R_1_0', None, None)), |
| 49 | + 'vars': {'R_1_0': 1.3}, |
| 50 | + 'map': {0: 0, 1: 1}} |
| 51 | + expected_zmat = {'symbols': ('H', 'H'), |
| 52 | + 'coords': ((None, None, None), |
| 53 | + ('R_1_0', None, None)), |
| 54 | + 'vars': {'R_1_0': 1.0}, |
| 55 | + 'map': {0: 0, 1: 1}} |
| 56 | + zmat = average_zmat_params(zmat_1, zmat_2) |
| 57 | + self.assertTrue(_compare_zmats(zmat, expected_zmat)) |
| 58 | + |
| 59 | + expected_zmat = {'symbols': ('H', 'H'), |
| 60 | + 'coords': ((None, None, None), |
| 61 | + ('R_1_0', None, None)), |
| 62 | + 'vars': {'R_1_0': 0.85}, |
| 63 | + 'map': {0: 0, 1: 1}} |
| 64 | + zmat = average_zmat_params(zmat_1, zmat_2, weight=0.25) |
| 65 | + self.assertTrue(_compare_zmats(zmat, expected_zmat)) |
| 66 | + zmat = average_zmat_params(zmat_2, zmat_1, weight=0.75) |
| 67 | + self.assertTrue(_compare_zmats(zmat, expected_zmat)) |
| 68 | + |
| 69 | + zmat_1 = {'symbols': ('C', 'N', 'H', 'H', 'H', 'H', 'H'), |
| 70 | + 'coords': ((None, None, None), ('R_1_0', None, None), ('R_2|4_0|0', 'A_2|4_0|0_1|1', None), |
| 71 | + ('R_3|6_1|1', 'A_3|6_1|1_0|0', 'D_3_1_0_2'), |
| 72 | + ('R_2|4_0|0', 'A_2|4_0|0_1|1', 'D_4_0_1_3'), ('R_5_0', 'A_5_0_1', 'D_5_0_1_4'), |
| 73 | + ('R_3|6_1|1', 'A_3|6_1|1_0|0', 'D_6_1_0_5')), |
| 74 | + 'vars': {'R_1_0': 1.451965854148702, 'D_3_1_0_2': 60.83821034525936, |
| 75 | + 'D_4_0_1_3': 301.30263742432356, 'R_5_0': 1.0936965384360282, |
| 76 | + 'A_5_0_1': 110.59878027260544, 'D_5_0_1_4': 239.76779188408136, |
| 77 | + 'D_6_1_0_5': 65.17113681053117, 'R_2|4_0|0': 1.0935188594180785, |
| 78 | + 'R_3|6_1|1': 1.019169330302324, 'A_2|4_0|0_1|1': 110.20495980110817, |
| 79 | + 'A_3|6_1|1_0|0': 109.41187648524644}, |
| 80 | + 'map': {0: 0, 1: 1, 2: 2, 3: 5, 4: 3, 5: 4, 6: 6}} |
| 81 | + zmat_2 = {'symbols': ('C', 'N', 'H', 'H', 'H', 'H', 'H'), |
| 82 | + 'coords': ((None, None, None), ('R_1_0', None, None), ('R_2|4_0|0', 'A_2|4_0|0_1|1', None), |
| 83 | + ('R_3|6_1|1', 'A_3|6_1|1_0|0', 'D_3_1_0_2'), |
| 84 | + ('R_2|4_0|0', 'A_2|4_0|0_1|1', 'D_4_0_1_3'), ('R_5_0', 'A_5_0_1', 'D_5_0_1_4'), |
| 85 | + ('R_3|6_1|1', 'A_3|6_1|1_0|0', 'D_6_1_0_5')), |
| 86 | + 'vars': {'R_1_0': 1.2, 'D_3_1_0_2': 50, |
| 87 | + 'D_4_0_1_3': 250, 'R_5_0': 1.0936965384360282, |
| 88 | + 'A_5_0_1': 110.59878027260544, 'D_5_0_1_4': 239.76779188408136, |
| 89 | + 'D_6_1_0_5': 120, 'R_2|4_0|0': 1.0935188594180785, |
| 90 | + 'R_3|6_1|1': 1.6, 'A_2|4_0|0_1|1': 110.20495980110817, |
| 91 | + 'A_3|6_1|1_0|0': 109.41187648524644}, |
| 92 | + 'map': {0: 0, 1: 1, 2: 2, 3: 5, 4: 3, 5: 4, 6: 6}} |
| 93 | + expected_zmat = {'symbols': ('C', 'N', 'H', 'H', 'H', 'H', 'H'), |
| 94 | + 'coords': ((None, None, None), ('R_1_0', None, None), ('R_2|4_0|0', 'A_2|4_0|0_1|1', None), |
| 95 | + ('R_3|6_1|1', 'A_3|6_1|1_0|0', 'D_3_1_0_2'), ('R_2|4_0|0', 'A_2|4_0|0_1|1', 'D_4_0_1_3'), |
| 96 | + ('R_5_0', 'A_5_0_1', 'D_5_0_1_4'), ('R_3|6_1|1', 'A_3|6_1|1_0|0', 'D_6_1_0_5')), |
| 97 | + 'vars': {'R_1_0': 1.3259829270743508, 'D_3_1_0_2': 55.419105172629685, |
| 98 | + 'D_4_0_1_3': 275.6513187121618, 'R_5_0': 1.0936965384360282, |
| 99 | + 'A_5_0_1': 110.59878027260544, 'D_5_0_1_4': 239.76779188408136, |
| 100 | + 'D_6_1_0_5': 92.58556840526558, 'R_2|4_0|0': 1.0935188594180785, |
| 101 | + 'R_3|6_1|1': 1.309584665151162, 'A_2|4_0|0_1|1': 110.20495980110817, |
| 102 | + 'A_3|6_1|1_0|0': 109.41187648524644}, |
| 103 | + 'map': {0: 0, 1: 1, 2: 2, 3: 5, 4: 3, 5: 4, 6: 6}} |
| 104 | + zmat = average_zmat_params(zmat_1, zmat_2) |
| 105 | + self.assertTrue(_compare_zmats(zmat, expected_zmat)) |
| 106 | + |
| 107 | + def test_get_weight(self): |
| 108 | + """Test the get_weight() function.""" |
| 109 | + self.assertEqual(get_weight([0], [0], 4), 0.5) # 4 / 8 |
| 110 | + self.assertEqual(get_weight([0], [8], 12), 0.75) # 12 / 20 |
| 111 | + self.assertEqual(get_weight([0], [2], 6), 0.6) # 6 / 10 |
| 112 | + self.assertEqual(get_weight([10], [0], 30), 0.4) # 20 / 50 |
| 113 | + self.assertEqual(get_weight([20], [10], 40), 0.4) # 20 / 50 |
| 114 | + self.assertIsNone(get_weight([20], [None], 40), 0.4) # 20 / 50 |
| 115 | + self.assertEqual(get_weight([8, 2], [0], 30), 0.4) # 20 / 50 |
| 116 | + self.assertEqual(get_weight([4, 1], [5.5, 1.5], 11), 0.6) # 6 / 10 |
| 117 | + |
| 118 | + def test_get_rxn_weight(self): |
| 119 | + """Test the get_rxn_weight() function.""" |
| 120 | + rxn_1 = ARCReaction(r_species=[ARCSpecies(label='HO2', smiles='[O]O'), |
| 121 | + ARCSpecies(label='NH', smiles='[NH]')], |
| 122 | + p_species=[ARCSpecies(label='N', smiles='[N]'), |
| 123 | + ARCSpecies(label='H2O2', smiles='OO')]) |
| 124 | + rxn_1.r_species[0].e0 = 252.0 |
| 125 | + rxn_1.r_species[1].e0 = 100.5 |
| 126 | + rxn_1.p_species[0].e0 = 116.0 |
| 127 | + rxn_1.p_species[1].e0 = 200.3 |
| 128 | + rxn_1.ts_species = ARCSpecies(label='TS', is_ts=True) |
| 129 | + rxn_1.ts_species.e0 = 391.6 |
| 130 | + self.assertAlmostEquals(get_rxn_weight(rxn_1), 0.3417832) |
| 131 | + |
| 132 | + def test_interpolate_isomerization(self): |
| 133 | + """Test the interpolate_isomerization() function.""" |
| 134 | + nc3h7_xyz = """C 0.00375165 -0.48895802 -1.20586379 |
| 135 | + C 0.00375165 -0.48895802 0.28487510 |
| 136 | + C 0.00375165 0.91997987 0.85403684 |
| 137 | + H 0.41748586 -1.33492098 -1.74315104 |
| 138 | + H -0.57506729 0.24145491 -1.76006154 |
| 139 | + H -0.87717095 -1.03203740 0.64280162 |
| 140 | + H 0.88948616 -1.02465371 0.64296621 |
| 141 | + H 0.88512433 1.48038223 0.52412379 |
| 142 | + H 0.01450405 0.88584135 1.94817394 |
| 143 | + H -0.88837301 1.47376959 0.54233121""" |
| 144 | + ic3h7_xyz = """C -0.40735690 -0.74240205 -0.34312948 |
| 145 | + C 0.38155377 -0.25604705 0.82450968 |
| 146 | + C 0.54634593 1.25448345 0.81064511 |
| 147 | + H 0.00637731 -1.58836501 -0.88041673 |
| 148 | + H -0.98617584 -0.01198912 -0.89732723 |
| 149 | + H -1.29710684 -1.29092340 0.08598983 |
| 150 | + H 1.36955428 -0.72869684 0.81102246 |
| 151 | + H 1.06044877 1.58846788 -0.09702437 |
| 152 | + H 1.13774084 1.57830484 1.67308862 |
| 153 | + H -0.42424546 1.75989927 0.85794283""" |
| 154 | + rxn = ARCReaction(r_species=[ARCSpecies(label='nC3H7', smiles='[CH2]CC', xyz=nc3h7_xyz)], |
| 155 | + p_species=[ARCSpecies(label='iC3H7', smiles='C[CH]C', xyz=ic3h7_xyz)]) |
| 156 | + expected_ts_xyz = str_to_xyz("""C 0.01099731 -0.46789926 -1.15958911 |
| 157 | + C 0.01099731 -0.46789926 0.33114978 |
| 158 | + C 0.01099731 0.94103865 0.90031155 |
| 159 | + H 0.57795661 -1.24174248 -1.65467180 |
| 160 | + H -0.39690222 0.34527841 -1.69240298 |
| 161 | + H -1.19440431 -1.28933062 -0.47327539 |
| 162 | + H 0.89689057 -1.16420498 0.45967951 |
| 163 | + H 0.76979130 1.33747945 0.33815513 |
| 164 | + H -0.04544494 0.70455273 1.77835334 |
| 165 | + H -1.00071642 1.24557408 0.38839197""") |
| 166 | + ts_xyz = interpolate_isomerization(rxn, use_weights=False) |
| 167 | + self.assertTrue(almost_equal_coords(ts_xyz, expected_ts_xyz)) |
| 168 | + |
| 169 | + @classmethod |
| 170 | + def tearDownClass(cls): |
| 171 | + """ |
| 172 | + A function that is run ONCE after all unit tests in this class. |
| 173 | + Delete all project directories created during these unit tests. |
| 174 | + """ |
| 175 | + pass |
| 176 | + |
| 177 | + |
| 178 | +if __name__ == '__main__': |
| 179 | + unittest.main(testRunner=unittest.TextTestRunner(verbosity=2)) |
0 commit comments